OSDN Git Service

* config/i386/i386.h (enum reg_class) [SSE_FIRST_REG]: New.
[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_ROUNDP               141)
175    (UNSPEC_ROUNDS               142)
176
177    ; For SSE4.2 support
178    (UNSPEC_CRC32                143)
179    (UNSPEC_PCMPESTR             144)
180    (UNSPEC_PCMPISTR             145)
181   ])
182
183 (define_constants
184   [(UNSPECV_BLOCKAGE            0)
185    (UNSPECV_STACK_PROBE         1)
186    (UNSPECV_EMMS                2)
187    (UNSPECV_LDMXCSR             3)
188    (UNSPECV_STMXCSR             4)
189    (UNSPECV_FEMMS               5)
190    (UNSPECV_CLFLUSH             6)
191    (UNSPECV_ALIGN               7)
192    (UNSPECV_MONITOR             8)
193    (UNSPECV_MWAIT               9)
194    (UNSPECV_CMPXCHG_1           10)
195    (UNSPECV_CMPXCHG_2           11)
196    (UNSPECV_XCHG                12)
197    (UNSPECV_LOCK                13)
198   ])
199
200 ;; Registers by name.
201 (define_constants
202   [(BP_REG                       6)
203    (SP_REG                       7)
204    (FLAGS_REG                   17)
205    (FPSR_REG                    18)
206    (FPCR_REG                    19)
207    (R10_REG                     39)
208    (R11_REG                     40)
209   ])
210
211 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
212 ;; from i386.c.
213
214 ;; In C guard expressions, put expressions which may be compile-time
215 ;; constants first.  This allows for better optimization.  For
216 ;; example, write "TARGET_64BIT && reload_completed", not
217 ;; "reload_completed && TARGET_64BIT".
218
219 \f
220 ;; Processor type.  This attribute must exactly match the processor_type
221 ;; enumeration in i386.h.
222 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
223                     nocona,core2,generic32,generic64,amdfam10"
224   (const (symbol_ref "ix86_tune")))
225
226 ;; A basic instruction type.  Refinements due to arguments to be
227 ;; provided in other attributes.
228 (define_attr "type"
229   "other,multi,
230    alu,alu1,negnot,imov,imovx,lea,
231    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
232    icmp,test,ibr,setcc,icmov,
233    push,pop,call,callv,leave,
234    str,bitmanip,
235    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
236    sselog,sselog1,sseiadd,sseishft,sseimul,
237    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins,
238    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
239   (const_string "other"))
240
241 ;; Main data type used by the insn
242 (define_attr "mode"
243   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
244   (const_string "unknown"))
245
246 ;; The CPU unit operations uses.
247 (define_attr "unit" "integer,i387,sse,mmx,unknown"
248   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
249            (const_string "i387")
250          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
251                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins")
252            (const_string "sse")
253          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
254            (const_string "mmx")
255          (eq_attr "type" "other")
256            (const_string "unknown")]
257          (const_string "integer")))
258
259 ;; The (bounding maximum) length of an instruction immediate.
260 (define_attr "length_immediate" ""
261   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
262                           bitmanip")
263            (const_int 0)
264          (eq_attr "unit" "i387,sse,mmx")
265            (const_int 0)
266          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
267                           imul,icmp,push,pop")
268            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
269          (eq_attr "type" "imov,test")
270            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
271          (eq_attr "type" "call")
272            (if_then_else (match_operand 0 "constant_call_address_operand" "")
273              (const_int 4)
274              (const_int 0))
275          (eq_attr "type" "callv")
276            (if_then_else (match_operand 1 "constant_call_address_operand" "")
277              (const_int 4)
278              (const_int 0))
279          ;; We don't know the size before shorten_branches.  Expect
280          ;; the instruction to fit for better scheduling.
281          (eq_attr "type" "ibr")
282            (const_int 1)
283          ]
284          (symbol_ref "/* Update immediate_length and other attributes! */
285                       gcc_unreachable (),1")))
286
287 ;; The (bounding maximum) length of an instruction address.
288 (define_attr "length_address" ""
289   (cond [(eq_attr "type" "str,other,multi,fxch")
290            (const_int 0)
291          (and (eq_attr "type" "call")
292               (match_operand 0 "constant_call_address_operand" ""))
293              (const_int 0)
294          (and (eq_attr "type" "callv")
295               (match_operand 1 "constant_call_address_operand" ""))
296              (const_int 0)
297          ]
298          (symbol_ref "ix86_attr_length_address_default (insn)")))
299
300 ;; Set when length prefix is used.
301 (define_attr "prefix_data16" ""
302   (if_then_else (ior (eq_attr "mode" "HI")
303                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
304     (const_int 1)
305     (const_int 0)))
306
307 ;; Set when string REP prefix is used.
308 (define_attr "prefix_rep" ""
309   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
310     (const_int 1)
311     (const_int 0)))
312
313 ;; Set when 0f opcode prefix is used.
314 (define_attr "prefix_0f" ""
315   (if_then_else
316     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
317          (eq_attr "unit" "sse,mmx"))
318     (const_int 1)
319     (const_int 0)))
320
321 ;; Set when REX opcode prefix is used.
322 (define_attr "prefix_rex" ""
323   (cond [(and (eq_attr "mode" "DI")
324               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
325            (const_int 1)
326          (and (eq_attr "mode" "QI")
327               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
328                   (const_int 0)))
329            (const_int 1)
330          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
331              (const_int 0))
332            (const_int 1)
333         ]
334         (const_int 0)))
335
336 ;; There are also additional prefixes in SSSE3.
337 (define_attr "prefix_extra" "" (const_int 0))
338
339 ;; Set when modrm byte is used.
340 (define_attr "modrm" ""
341   (cond [(eq_attr "type" "str,leave")
342            (const_int 0)
343          (eq_attr "unit" "i387")
344            (const_int 0)
345          (and (eq_attr "type" "incdec")
346               (ior (match_operand:SI 1 "register_operand" "")
347                    (match_operand:HI 1 "register_operand" "")))
348            (const_int 0)
349          (and (eq_attr "type" "push")
350               (not (match_operand 1 "memory_operand" "")))
351            (const_int 0)
352          (and (eq_attr "type" "pop")
353               (not (match_operand 0 "memory_operand" "")))
354            (const_int 0)
355          (and (eq_attr "type" "imov")
356               (ior (and (match_operand 0 "register_operand" "")
357                         (match_operand 1 "immediate_operand" ""))
358                    (ior (and (match_operand 0 "ax_reg_operand" "")
359                              (match_operand 1 "memory_displacement_only_operand" ""))
360                         (and (match_operand 0 "memory_displacement_only_operand" "")
361                              (match_operand 1 "ax_reg_operand" "")))))
362            (const_int 0)
363          (and (eq_attr "type" "call")
364               (match_operand 0 "constant_call_address_operand" ""))
365              (const_int 0)
366          (and (eq_attr "type" "callv")
367               (match_operand 1 "constant_call_address_operand" ""))
368              (const_int 0)
369          ]
370          (const_int 1)))
371
372 ;; The (bounding maximum) length of an instruction in bytes.
373 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
374 ;; Later we may want to split them and compute proper length as for
375 ;; other insns.
376 (define_attr "length" ""
377   (cond [(eq_attr "type" "other,multi,fistp,frndint")
378            (const_int 16)
379          (eq_attr "type" "fcmp")
380            (const_int 4)
381          (eq_attr "unit" "i387")
382            (plus (const_int 2)
383                  (plus (attr "prefix_data16")
384                        (attr "length_address")))]
385          (plus (plus (attr "modrm")
386                      (plus (attr "prefix_0f")
387                            (plus (attr "prefix_rex")
388                                  (plus (attr "prefix_extra")
389                                        (const_int 1)))))
390                (plus (attr "prefix_rep")
391                      (plus (attr "prefix_data16")
392                            (plus (attr "length_immediate")
393                                  (attr "length_address")))))))
394
395 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
396 ;; `store' if there is a simple memory reference therein, or `unknown'
397 ;; if the instruction is complex.
398
399 (define_attr "memory" "none,load,store,both,unknown"
400   (cond [(eq_attr "type" "other,multi,str")
401            (const_string "unknown")
402          (eq_attr "type" "lea,fcmov,fpspc")
403            (const_string "none")
404          (eq_attr "type" "fistp,leave")
405            (const_string "both")
406          (eq_attr "type" "frndint")
407            (const_string "load")
408          (eq_attr "type" "push")
409            (if_then_else (match_operand 1 "memory_operand" "")
410              (const_string "both")
411              (const_string "store"))
412          (eq_attr "type" "pop")
413            (if_then_else (match_operand 0 "memory_operand" "")
414              (const_string "both")
415              (const_string "load"))
416          (eq_attr "type" "setcc")
417            (if_then_else (match_operand 0 "memory_operand" "")
418              (const_string "store")
419              (const_string "none"))
420          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
421            (if_then_else (ior (match_operand 0 "memory_operand" "")
422                               (match_operand 1 "memory_operand" ""))
423              (const_string "load")
424              (const_string "none"))
425          (eq_attr "type" "ibr")
426            (if_then_else (match_operand 0 "memory_operand" "")
427              (const_string "load")
428              (const_string "none"))
429          (eq_attr "type" "call")
430            (if_then_else (match_operand 0 "constant_call_address_operand" "")
431              (const_string "none")
432              (const_string "load"))
433          (eq_attr "type" "callv")
434            (if_then_else (match_operand 1 "constant_call_address_operand" "")
435              (const_string "none")
436              (const_string "load"))
437          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
438               (match_operand 1 "memory_operand" ""))
439            (const_string "both")
440          (and (match_operand 0 "memory_operand" "")
441               (match_operand 1 "memory_operand" ""))
442            (const_string "both")
443          (match_operand 0 "memory_operand" "")
444            (const_string "store")
445          (match_operand 1 "memory_operand" "")
446            (const_string "load")
447          (and (eq_attr "type"
448                  "!alu1,negnot,ishift1,
449                    imov,imovx,icmp,test,bitmanip,
450                    fmov,fcmp,fsgn,
451                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
452                    mmx,mmxmov,mmxcmp,mmxcvt")
453               (match_operand 2 "memory_operand" ""))
454            (const_string "load")
455          (and (eq_attr "type" "icmov")
456               (match_operand 3 "memory_operand" ""))
457            (const_string "load")
458         ]
459         (const_string "none")))
460
461 ;; Indicates if an instruction has both an immediate and a displacement.
462
463 (define_attr "imm_disp" "false,true,unknown"
464   (cond [(eq_attr "type" "other,multi")
465            (const_string "unknown")
466          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
467               (and (match_operand 0 "memory_displacement_operand" "")
468                    (match_operand 1 "immediate_operand" "")))
469            (const_string "true")
470          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
471               (and (match_operand 0 "memory_displacement_operand" "")
472                    (match_operand 2 "immediate_operand" "")))
473            (const_string "true")
474         ]
475         (const_string "false")))
476
477 ;; Indicates if an FP operation has an integer source.
478
479 (define_attr "fp_int_src" "false,true"
480   (const_string "false"))
481
482 ;; Defines rounding mode of an FP operation.
483
484 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
485   (const_string "any"))
486
487 ;; Describe a user's asm statement.
488 (define_asm_attributes
489   [(set_attr "length" "128")
490    (set_attr "type" "multi")])
491
492 ;; All x87 floating point modes
493 (define_mode_macro X87MODEF [SF DF XF])
494
495 ;; x87 SFmode and DFMode floating point modes
496 (define_mode_macro X87MODEF12 [SF DF])
497
498 ;; All integer modes handled by x87 fisttp operator.
499 (define_mode_macro X87MODEI [HI SI DI])
500
501 ;; All integer modes handled by integer x87 operators.
502 (define_mode_macro X87MODEI12 [HI SI])
503
504 ;; All SSE floating point modes
505 (define_mode_macro SSEMODEF [SF DF])
506
507 ;; All integer modes handled by SSE cvtts?2si* operators.
508 (define_mode_macro SSEMODEI24 [SI DI])
509
510 ;; SSE asm suffix for floating point modes
511 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
512
513 ;; SSE vector mode corresponding to a scalar mode
514 (define_mode_attr ssevecmode
515   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
516 \f
517 ;; Scheduling descriptions
518
519 (include "pentium.md")
520 (include "ppro.md")
521 (include "k6.md")
522 (include "athlon.md")
523 (include "geode.md")
524
525 \f
526 ;; Operand and operator predicates and constraints
527
528 (include "predicates.md")
529 (include "constraints.md")
530
531 \f
532 ;; Compare instructions.
533
534 ;; All compare insns have expanders that save the operands away without
535 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
536 ;; after the cmp) will actually emit the cmpM.
537
538 (define_expand "cmpti"
539   [(set (reg:CC FLAGS_REG)
540         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
541                     (match_operand:TI 1 "x86_64_general_operand" "")))]
542   "TARGET_64BIT"
543 {
544   if (MEM_P (operands[0]) && MEM_P (operands[1]))
545     operands[0] = force_reg (TImode, operands[0]);
546   ix86_compare_op0 = operands[0];
547   ix86_compare_op1 = operands[1];
548   DONE;
549 })
550
551 (define_expand "cmpdi"
552   [(set (reg:CC FLAGS_REG)
553         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
554                     (match_operand:DI 1 "x86_64_general_operand" "")))]
555   ""
556 {
557   if (MEM_P (operands[0]) && MEM_P (operands[1]))
558     operands[0] = force_reg (DImode, operands[0]);
559   ix86_compare_op0 = operands[0];
560   ix86_compare_op1 = operands[1];
561   DONE;
562 })
563
564 (define_expand "cmpsi"
565   [(set (reg:CC FLAGS_REG)
566         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
567                     (match_operand:SI 1 "general_operand" "")))]
568   ""
569 {
570   if (MEM_P (operands[0]) && MEM_P (operands[1]))
571     operands[0] = force_reg (SImode, operands[0]);
572   ix86_compare_op0 = operands[0];
573   ix86_compare_op1 = operands[1];
574   DONE;
575 })
576
577 (define_expand "cmphi"
578   [(set (reg:CC FLAGS_REG)
579         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
580                     (match_operand:HI 1 "general_operand" "")))]
581   ""
582 {
583   if (MEM_P (operands[0]) && MEM_P (operands[1]))
584     operands[0] = force_reg (HImode, operands[0]);
585   ix86_compare_op0 = operands[0];
586   ix86_compare_op1 = operands[1];
587   DONE;
588 })
589
590 (define_expand "cmpqi"
591   [(set (reg:CC FLAGS_REG)
592         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
593                     (match_operand:QI 1 "general_operand" "")))]
594   "TARGET_QIMODE_MATH"
595 {
596   if (MEM_P (operands[0]) && MEM_P (operands[1]))
597     operands[0] = force_reg (QImode, operands[0]);
598   ix86_compare_op0 = operands[0];
599   ix86_compare_op1 = operands[1];
600   DONE;
601 })
602
603 (define_insn "cmpdi_ccno_1_rex64"
604   [(set (reg FLAGS_REG)
605         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
606                  (match_operand:DI 1 "const0_operand" "n,n")))]
607   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
608   "@
609    test{q}\t%0, %0
610    cmp{q}\t{%1, %0|%0, %1}"
611   [(set_attr "type" "test,icmp")
612    (set_attr "length_immediate" "0,1")
613    (set_attr "mode" "DI")])
614
615 (define_insn "*cmpdi_minus_1_rex64"
616   [(set (reg FLAGS_REG)
617         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
618                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
619                  (const_int 0)))]
620   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
621   "cmp{q}\t{%1, %0|%0, %1}"
622   [(set_attr "type" "icmp")
623    (set_attr "mode" "DI")])
624
625 (define_expand "cmpdi_1_rex64"
626   [(set (reg:CC FLAGS_REG)
627         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
628                     (match_operand:DI 1 "general_operand" "")))]
629   "TARGET_64BIT"
630   "")
631
632 (define_insn "cmpdi_1_insn_rex64"
633   [(set (reg FLAGS_REG)
634         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
635                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
636   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
637   "cmp{q}\t{%1, %0|%0, %1}"
638   [(set_attr "type" "icmp")
639    (set_attr "mode" "DI")])
640
641
642 (define_insn "*cmpsi_ccno_1"
643   [(set (reg FLAGS_REG)
644         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
645                  (match_operand:SI 1 "const0_operand" "n,n")))]
646   "ix86_match_ccmode (insn, CCNOmode)"
647   "@
648    test{l}\t%0, %0
649    cmp{l}\t{%1, %0|%0, %1}"
650   [(set_attr "type" "test,icmp")
651    (set_attr "length_immediate" "0,1")
652    (set_attr "mode" "SI")])
653
654 (define_insn "*cmpsi_minus_1"
655   [(set (reg FLAGS_REG)
656         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
657                            (match_operand:SI 1 "general_operand" "ri,mr"))
658                  (const_int 0)))]
659   "ix86_match_ccmode (insn, CCGOCmode)"
660   "cmp{l}\t{%1, %0|%0, %1}"
661   [(set_attr "type" "icmp")
662    (set_attr "mode" "SI")])
663
664 (define_expand "cmpsi_1"
665   [(set (reg:CC FLAGS_REG)
666         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
667                     (match_operand:SI 1 "general_operand" "ri,mr")))]
668   ""
669   "")
670
671 (define_insn "*cmpsi_1_insn"
672   [(set (reg FLAGS_REG)
673         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
674                  (match_operand:SI 1 "general_operand" "ri,mr")))]
675   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
676     && ix86_match_ccmode (insn, CCmode)"
677   "cmp{l}\t{%1, %0|%0, %1}"
678   [(set_attr "type" "icmp")
679    (set_attr "mode" "SI")])
680
681 (define_insn "*cmphi_ccno_1"
682   [(set (reg FLAGS_REG)
683         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
684                  (match_operand:HI 1 "const0_operand" "n,n")))]
685   "ix86_match_ccmode (insn, CCNOmode)"
686   "@
687    test{w}\t%0, %0
688    cmp{w}\t{%1, %0|%0, %1}"
689   [(set_attr "type" "test,icmp")
690    (set_attr "length_immediate" "0,1")
691    (set_attr "mode" "HI")])
692
693 (define_insn "*cmphi_minus_1"
694   [(set (reg FLAGS_REG)
695         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
696                            (match_operand:HI 1 "general_operand" "ri,mr"))
697                  (const_int 0)))]
698   "ix86_match_ccmode (insn, CCGOCmode)"
699   "cmp{w}\t{%1, %0|%0, %1}"
700   [(set_attr "type" "icmp")
701    (set_attr "mode" "HI")])
702
703 (define_insn "*cmphi_1"
704   [(set (reg FLAGS_REG)
705         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
706                  (match_operand:HI 1 "general_operand" "ri,mr")))]
707   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
708    && ix86_match_ccmode (insn, CCmode)"
709   "cmp{w}\t{%1, %0|%0, %1}"
710   [(set_attr "type" "icmp")
711    (set_attr "mode" "HI")])
712
713 (define_insn "*cmpqi_ccno_1"
714   [(set (reg FLAGS_REG)
715         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
716                  (match_operand:QI 1 "const0_operand" "n,n")))]
717   "ix86_match_ccmode (insn, CCNOmode)"
718   "@
719    test{b}\t%0, %0
720    cmp{b}\t{$0, %0|%0, 0}"
721   [(set_attr "type" "test,icmp")
722    (set_attr "length_immediate" "0,1")
723    (set_attr "mode" "QI")])
724
725 (define_insn "*cmpqi_1"
726   [(set (reg FLAGS_REG)
727         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
728                  (match_operand:QI 1 "general_operand" "qi,mq")))]
729   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
730     && ix86_match_ccmode (insn, CCmode)"
731   "cmp{b}\t{%1, %0|%0, %1}"
732   [(set_attr "type" "icmp")
733    (set_attr "mode" "QI")])
734
735 (define_insn "*cmpqi_minus_1"
736   [(set (reg FLAGS_REG)
737         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
738                            (match_operand:QI 1 "general_operand" "qi,mq"))
739                  (const_int 0)))]
740   "ix86_match_ccmode (insn, CCGOCmode)"
741   "cmp{b}\t{%1, %0|%0, %1}"
742   [(set_attr "type" "icmp")
743    (set_attr "mode" "QI")])
744
745 (define_insn "*cmpqi_ext_1"
746   [(set (reg FLAGS_REG)
747         (compare
748           (match_operand:QI 0 "general_operand" "Qm")
749           (subreg:QI
750             (zero_extract:SI
751               (match_operand 1 "ext_register_operand" "Q")
752               (const_int 8)
753               (const_int 8)) 0)))]
754   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
755   "cmp{b}\t{%h1, %0|%0, %h1}"
756   [(set_attr "type" "icmp")
757    (set_attr "mode" "QI")])
758
759 (define_insn "*cmpqi_ext_1_rex64"
760   [(set (reg FLAGS_REG)
761         (compare
762           (match_operand:QI 0 "register_operand" "Q")
763           (subreg:QI
764             (zero_extract:SI
765               (match_operand 1 "ext_register_operand" "Q")
766               (const_int 8)
767               (const_int 8)) 0)))]
768   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
769   "cmp{b}\t{%h1, %0|%0, %h1}"
770   [(set_attr "type" "icmp")
771    (set_attr "mode" "QI")])
772
773 (define_insn "*cmpqi_ext_2"
774   [(set (reg FLAGS_REG)
775         (compare
776           (subreg:QI
777             (zero_extract:SI
778               (match_operand 0 "ext_register_operand" "Q")
779               (const_int 8)
780               (const_int 8)) 0)
781           (match_operand:QI 1 "const0_operand" "n")))]
782   "ix86_match_ccmode (insn, CCNOmode)"
783   "test{b}\t%h0, %h0"
784   [(set_attr "type" "test")
785    (set_attr "length_immediate" "0")
786    (set_attr "mode" "QI")])
787
788 (define_expand "cmpqi_ext_3"
789   [(set (reg:CC FLAGS_REG)
790         (compare:CC
791           (subreg:QI
792             (zero_extract:SI
793               (match_operand 0 "ext_register_operand" "")
794               (const_int 8)
795               (const_int 8)) 0)
796           (match_operand:QI 1 "general_operand" "")))]
797   ""
798   "")
799
800 (define_insn "cmpqi_ext_3_insn"
801   [(set (reg FLAGS_REG)
802         (compare
803           (subreg:QI
804             (zero_extract:SI
805               (match_operand 0 "ext_register_operand" "Q")
806               (const_int 8)
807               (const_int 8)) 0)
808           (match_operand:QI 1 "general_operand" "Qmn")))]
809   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
810   "cmp{b}\t{%1, %h0|%h0, %1}"
811   [(set_attr "type" "icmp")
812    (set_attr "mode" "QI")])
813
814 (define_insn "cmpqi_ext_3_insn_rex64"
815   [(set (reg FLAGS_REG)
816         (compare
817           (subreg:QI
818             (zero_extract:SI
819               (match_operand 0 "ext_register_operand" "Q")
820               (const_int 8)
821               (const_int 8)) 0)
822           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
823   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
824   "cmp{b}\t{%1, %h0|%h0, %1}"
825   [(set_attr "type" "icmp")
826    (set_attr "mode" "QI")])
827
828 (define_insn "*cmpqi_ext_4"
829   [(set (reg FLAGS_REG)
830         (compare
831           (subreg:QI
832             (zero_extract:SI
833               (match_operand 0 "ext_register_operand" "Q")
834               (const_int 8)
835               (const_int 8)) 0)
836           (subreg:QI
837             (zero_extract:SI
838               (match_operand 1 "ext_register_operand" "Q")
839               (const_int 8)
840               (const_int 8)) 0)))]
841   "ix86_match_ccmode (insn, CCmode)"
842   "cmp{b}\t{%h1, %h0|%h0, %h1}"
843   [(set_attr "type" "icmp")
844    (set_attr "mode" "QI")])
845
846 ;; These implement float point compares.
847 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
848 ;; which would allow mix and match FP modes on the compares.  Which is what
849 ;; the old patterns did, but with many more of them.
850
851 (define_expand "cmpxf"
852   [(set (reg:CC FLAGS_REG)
853         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
854                     (match_operand:XF 1 "nonmemory_operand" "")))]
855   "TARGET_80387"
856 {
857   ix86_compare_op0 = operands[0];
858   ix86_compare_op1 = operands[1];
859   DONE;
860 })
861
862 (define_expand "cmp<mode>"
863   [(set (reg:CC FLAGS_REG)
864         (compare:CC (match_operand:SSEMODEF 0 "cmp_fp_expander_operand" "")
865                     (match_operand:SSEMODEF 1 "cmp_fp_expander_operand" "")))]
866   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
867 {
868   ix86_compare_op0 = operands[0];
869   ix86_compare_op1 = operands[1];
870   DONE;
871 })
872
873 ;; FP compares, step 1:
874 ;; Set the FP condition codes.
875 ;;
876 ;; CCFPmode     compare with exceptions
877 ;; CCFPUmode    compare with no exceptions
878
879 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
880 ;; used to manage the reg stack popping would not be preserved.
881
882 (define_insn "*cmpfp_0"
883   [(set (match_operand:HI 0 "register_operand" "=a")
884         (unspec:HI
885           [(compare:CCFP
886              (match_operand 1 "register_operand" "f")
887              (match_operand 2 "const0_operand" "X"))]
888         UNSPEC_FNSTSW))]
889   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
890    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
891   "* return output_fp_compare (insn, operands, 0, 0);"
892   [(set_attr "type" "multi")
893    (set_attr "unit" "i387")
894    (set (attr "mode")
895      (cond [(match_operand:SF 1 "" "")
896               (const_string "SF")
897             (match_operand:DF 1 "" "")
898               (const_string "DF")
899            ]
900            (const_string "XF")))])
901
902 (define_insn "*cmpfp_xf"
903   [(set (match_operand:HI 0 "register_operand" "=a")
904         (unspec:HI
905           [(compare:CCFP
906              (match_operand:XF 1 "register_operand" "f")
907              (match_operand:XF 2 "register_operand" "f"))]
908           UNSPEC_FNSTSW))]
909   "TARGET_80387"
910   "* return output_fp_compare (insn, operands, 0, 0);"
911   [(set_attr "type" "multi")
912    (set_attr "unit" "i387")
913    (set_attr "mode" "XF")])
914
915 (define_insn "*cmpfp_<mode>"
916   [(set (match_operand:HI 0 "register_operand" "=a")
917         (unspec:HI
918           [(compare:CCFP
919              (match_operand:X87MODEF12 1 "register_operand" "f")
920              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm"))]
921           UNSPEC_FNSTSW))]
922   "TARGET_80387"
923   "* return output_fp_compare (insn, operands, 0, 0);"
924   [(set_attr "type" "multi")
925    (set_attr "unit" "i387")
926    (set_attr "mode" "<MODE>")])
927
928 (define_insn "*cmpfp_u"
929   [(set (match_operand:HI 0 "register_operand" "=a")
930         (unspec:HI
931           [(compare:CCFPU
932              (match_operand 1 "register_operand" "f")
933              (match_operand 2 "register_operand" "f"))]
934           UNSPEC_FNSTSW))]
935   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
936    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
937   "* return output_fp_compare (insn, operands, 0, 1);"
938   [(set_attr "type" "multi")
939    (set_attr "unit" "i387")
940    (set (attr "mode")
941      (cond [(match_operand:SF 1 "" "")
942               (const_string "SF")
943             (match_operand:DF 1 "" "")
944               (const_string "DF")
945            ]
946            (const_string "XF")))])
947
948 (define_insn "*cmpfp_<mode>"
949   [(set (match_operand:HI 0 "register_operand" "=a")
950         (unspec:HI
951           [(compare:CCFP
952              (match_operand 1 "register_operand" "f")
953              (match_operator 3 "float_operator"
954                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
955           UNSPEC_FNSTSW))]
956   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
957    && TARGET_USE_<MODE>MODE_FIOP
958    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
959   "* return output_fp_compare (insn, operands, 0, 0);"
960   [(set_attr "type" "multi")
961    (set_attr "unit" "i387")
962    (set_attr "fp_int_src" "true")
963    (set_attr "mode" "<MODE>")])
964
965 ;; FP compares, step 2
966 ;; Move the fpsw to ax.
967
968 (define_insn "x86_fnstsw_1"
969   [(set (match_operand:HI 0 "register_operand" "=a")
970         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
971   "TARGET_80387"
972   "fnstsw\t%0"
973   [(set_attr "length" "2")
974    (set_attr "mode" "SI")
975    (set_attr "unit" "i387")])
976
977 ;; FP compares, step 3
978 ;; Get ax into flags, general case.
979
980 (define_insn "x86_sahf_1"
981   [(set (reg:CC FLAGS_REG)
982         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
983                    UNSPEC_SAHF))]
984   "TARGET_SAHF"
985 {
986 #ifdef HAVE_AS_IX86_SAHF
987   return "sahf";
988 #else
989   return ".byte\t0x9e";
990 #endif
991 }
992   [(set_attr "length" "1")
993    (set_attr "athlon_decode" "vector")
994    (set_attr "amdfam10_decode" "direct")
995    (set_attr "mode" "SI")])
996
997 ;; Pentium Pro can do steps 1 through 3 in one go.
998 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes) 
999 (define_insn "*cmpfp_i_mixed"
1000   [(set (reg:CCFP FLAGS_REG)
1001         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1002                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1003   "TARGET_MIX_SSE_I387
1004    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1005    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1006   "* return output_fp_compare (insn, operands, 1, 0);"
1007   [(set_attr "type" "fcmp,ssecomi")
1008    (set (attr "mode")
1009      (if_then_else (match_operand:SF 1 "" "")
1010         (const_string "SF")
1011         (const_string "DF")))
1012    (set_attr "athlon_decode" "vector")
1013    (set_attr "amdfam10_decode" "direct")])
1014
1015 (define_insn "*cmpfp_i_sse"
1016   [(set (reg:CCFP FLAGS_REG)
1017         (compare:CCFP (match_operand 0 "register_operand" "x")
1018                       (match_operand 1 "nonimmediate_operand" "xm")))]
1019   "TARGET_SSE_MATH
1020    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1021    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1022   "* return output_fp_compare (insn, operands, 1, 0);"
1023   [(set_attr "type" "ssecomi")
1024    (set (attr "mode")
1025      (if_then_else (match_operand:SF 1 "" "")
1026         (const_string "SF")
1027         (const_string "DF")))
1028    (set_attr "athlon_decode" "vector")
1029    (set_attr "amdfam10_decode" "direct")])
1030
1031 (define_insn "*cmpfp_i_i387"
1032   [(set (reg:CCFP FLAGS_REG)
1033         (compare:CCFP (match_operand 0 "register_operand" "f")
1034                       (match_operand 1 "register_operand" "f")))]
1035   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1036    && TARGET_CMOVE
1037    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1038    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1039   "* return output_fp_compare (insn, operands, 1, 0);"
1040   [(set_attr "type" "fcmp")
1041    (set (attr "mode")
1042      (cond [(match_operand:SF 1 "" "")
1043               (const_string "SF")
1044             (match_operand:DF 1 "" "")
1045               (const_string "DF")
1046            ]
1047            (const_string "XF")))
1048    (set_attr "athlon_decode" "vector")
1049    (set_attr "amdfam10_decode" "direct")])
1050
1051 (define_insn "*cmpfp_iu_mixed"
1052   [(set (reg:CCFPU FLAGS_REG)
1053         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1054                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1055   "TARGET_MIX_SSE_I387
1056    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1057    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1058   "* return output_fp_compare (insn, operands, 1, 1);"
1059   [(set_attr "type" "fcmp,ssecomi")
1060    (set (attr "mode")
1061      (if_then_else (match_operand:SF 1 "" "")
1062         (const_string "SF")
1063         (const_string "DF")))
1064    (set_attr "athlon_decode" "vector")
1065    (set_attr "amdfam10_decode" "direct")])
1066
1067 (define_insn "*cmpfp_iu_sse"
1068   [(set (reg:CCFPU FLAGS_REG)
1069         (compare:CCFPU (match_operand 0 "register_operand" "x")
1070                        (match_operand 1 "nonimmediate_operand" "xm")))]
1071   "TARGET_SSE_MATH
1072    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1073    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1074   "* return output_fp_compare (insn, operands, 1, 1);"
1075   [(set_attr "type" "ssecomi")
1076    (set (attr "mode")
1077      (if_then_else (match_operand:SF 1 "" "")
1078         (const_string "SF")
1079         (const_string "DF")))
1080    (set_attr "athlon_decode" "vector")
1081    (set_attr "amdfam10_decode" "direct")])
1082
1083 (define_insn "*cmpfp_iu_387"
1084   [(set (reg:CCFPU FLAGS_REG)
1085         (compare:CCFPU (match_operand 0 "register_operand" "f")
1086                        (match_operand 1 "register_operand" "f")))]
1087   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1088    && TARGET_CMOVE
1089    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1090    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1091   "* return output_fp_compare (insn, operands, 1, 1);"
1092   [(set_attr "type" "fcmp")
1093    (set (attr "mode")
1094      (cond [(match_operand:SF 1 "" "")
1095               (const_string "SF")
1096             (match_operand:DF 1 "" "")
1097               (const_string "DF")
1098            ]
1099            (const_string "XF")))
1100    (set_attr "athlon_decode" "vector")
1101    (set_attr "amdfam10_decode" "direct")])
1102 \f
1103 ;; Move instructions.
1104
1105 ;; General case of fullword move.
1106
1107 (define_expand "movsi"
1108   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1109         (match_operand:SI 1 "general_operand" ""))]
1110   ""
1111   "ix86_expand_move (SImode, operands); DONE;")
1112
1113 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1114 ;; general_operand.
1115 ;;
1116 ;; %%% We don't use a post-inc memory reference because x86 is not a
1117 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1118 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1119 ;; targets without our curiosities, and it is just as easy to represent
1120 ;; this differently.
1121
1122 (define_insn "*pushsi2"
1123   [(set (match_operand:SI 0 "push_operand" "=<")
1124         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1125   "!TARGET_64BIT"
1126   "push{l}\t%1"
1127   [(set_attr "type" "push")
1128    (set_attr "mode" "SI")])
1129
1130 ;; For 64BIT abi we always round up to 8 bytes.
1131 (define_insn "*pushsi2_rex64"
1132   [(set (match_operand:SI 0 "push_operand" "=X")
1133         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1134   "TARGET_64BIT"
1135   "push{q}\t%q1"
1136   [(set_attr "type" "push")
1137    (set_attr "mode" "SI")])
1138
1139 (define_insn "*pushsi2_prologue"
1140   [(set (match_operand:SI 0 "push_operand" "=<")
1141         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1142    (clobber (mem:BLK (scratch)))]
1143   "!TARGET_64BIT"
1144   "push{l}\t%1"
1145   [(set_attr "type" "push")
1146    (set_attr "mode" "SI")])
1147
1148 (define_insn "*popsi1_epilogue"
1149   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1150         (mem:SI (reg:SI SP_REG)))
1151    (set (reg:SI SP_REG)
1152         (plus:SI (reg:SI SP_REG) (const_int 4)))
1153    (clobber (mem:BLK (scratch)))]
1154   "!TARGET_64BIT"
1155   "pop{l}\t%0"
1156   [(set_attr "type" "pop")
1157    (set_attr "mode" "SI")])
1158
1159 (define_insn "popsi1"
1160   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1161         (mem:SI (reg:SI SP_REG)))
1162    (set (reg:SI SP_REG)
1163         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1164   "!TARGET_64BIT"
1165   "pop{l}\t%0"
1166   [(set_attr "type" "pop")
1167    (set_attr "mode" "SI")])
1168
1169 (define_insn "*movsi_xor"
1170   [(set (match_operand:SI 0 "register_operand" "=r")
1171         (match_operand:SI 1 "const0_operand" "i"))
1172    (clobber (reg:CC FLAGS_REG))]
1173   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1174   "xor{l}\t%0, %0"
1175   [(set_attr "type" "alu1")
1176    (set_attr "mode" "SI")
1177    (set_attr "length_immediate" "0")])
1178
1179 (define_insn "*movsi_or"
1180   [(set (match_operand:SI 0 "register_operand" "=r")
1181         (match_operand:SI 1 "immediate_operand" "i"))
1182    (clobber (reg:CC FLAGS_REG))]
1183   "reload_completed
1184    && operands[1] == constm1_rtx
1185    && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1186 {
1187   operands[1] = constm1_rtx;
1188   return "or{l}\t{%1, %0|%0, %1}";
1189 }
1190   [(set_attr "type" "alu1")
1191    (set_attr "mode" "SI")
1192    (set_attr "length_immediate" "1")])
1193
1194 (define_insn "*movsi_1"
1195   [(set (match_operand:SI 0 "nonimmediate_operand"
1196                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1197         (match_operand:SI 1 "general_operand"
1198                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1199   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1200 {
1201   switch (get_attr_type (insn))
1202     {
1203     case TYPE_SSELOG1:
1204       if (get_attr_mode (insn) == MODE_TI)
1205         return "pxor\t%0, %0";
1206       return "xorps\t%0, %0";
1207
1208     case TYPE_SSEMOV:
1209       switch (get_attr_mode (insn))
1210         {
1211         case MODE_TI:
1212           return "movdqa\t{%1, %0|%0, %1}";
1213         case MODE_V4SF:
1214           return "movaps\t{%1, %0|%0, %1}";
1215         case MODE_SI:
1216           return "movd\t{%1, %0|%0, %1}";
1217         case MODE_SF:
1218           return "movss\t{%1, %0|%0, %1}";
1219         default:
1220           gcc_unreachable ();
1221         }
1222
1223     case TYPE_MMXADD:
1224       return "pxor\t%0, %0";
1225
1226     case TYPE_MMXMOV:
1227       if (get_attr_mode (insn) == MODE_DI)
1228         return "movq\t{%1, %0|%0, %1}";
1229       return "movd\t{%1, %0|%0, %1}";
1230
1231     case TYPE_LEA:
1232       return "lea{l}\t{%1, %0|%0, %1}";
1233
1234     default:
1235       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1236       return "mov{l}\t{%1, %0|%0, %1}";
1237     }
1238 }
1239   [(set (attr "type")
1240      (cond [(eq_attr "alternative" "2")
1241               (const_string "mmxadd")
1242             (eq_attr "alternative" "3,4,5")
1243               (const_string "mmxmov")
1244             (eq_attr "alternative" "6")
1245               (const_string "sselog1")
1246             (eq_attr "alternative" "7,8,9,10,11")
1247               (const_string "ssemov")
1248             (match_operand:DI 1 "pic_32bit_operand" "")
1249               (const_string "lea")
1250            ]
1251            (const_string "imov")))
1252    (set (attr "mode")
1253      (cond [(eq_attr "alternative" "2,3")
1254               (const_string "DI")
1255             (eq_attr "alternative" "6,7")
1256               (if_then_else
1257                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1258                 (const_string "V4SF")
1259                 (const_string "TI"))
1260             (and (eq_attr "alternative" "8,9,10,11")
1261                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1262               (const_string "SF")
1263            ]
1264            (const_string "SI")))])
1265
1266 ;; Stores and loads of ax to arbitrary constant address.
1267 ;; We fake an second form of instruction to force reload to load address
1268 ;; into register when rax is not available
1269 (define_insn "*movabssi_1_rex64"
1270   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1271         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1272   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1273   "@
1274    movabs{l}\t{%1, %P0|%P0, %1}
1275    mov{l}\t{%1, %a0|%a0, %1}"
1276   [(set_attr "type" "imov")
1277    (set_attr "modrm" "0,*")
1278    (set_attr "length_address" "8,0")
1279    (set_attr "length_immediate" "0,*")
1280    (set_attr "memory" "store")
1281    (set_attr "mode" "SI")])
1282
1283 (define_insn "*movabssi_2_rex64"
1284   [(set (match_operand:SI 0 "register_operand" "=a,r")
1285         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1286   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1287   "@
1288    movabs{l}\t{%P1, %0|%0, %P1}
1289    mov{l}\t{%a1, %0|%0, %a1}"
1290   [(set_attr "type" "imov")
1291    (set_attr "modrm" "0,*")
1292    (set_attr "length_address" "8,0")
1293    (set_attr "length_immediate" "0")
1294    (set_attr "memory" "load")
1295    (set_attr "mode" "SI")])
1296
1297 (define_insn "*swapsi"
1298   [(set (match_operand:SI 0 "register_operand" "+r")
1299         (match_operand:SI 1 "register_operand" "+r"))
1300    (set (match_dup 1)
1301         (match_dup 0))]
1302   ""
1303   "xchg{l}\t%1, %0"
1304   [(set_attr "type" "imov")
1305    (set_attr "mode" "SI")
1306    (set_attr "pent_pair" "np")
1307    (set_attr "athlon_decode" "vector")
1308    (set_attr "amdfam10_decode" "double")])   
1309
1310 (define_expand "movhi"
1311   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1312         (match_operand:HI 1 "general_operand" ""))]
1313   ""
1314   "ix86_expand_move (HImode, operands); DONE;")
1315
1316 (define_insn "*pushhi2"
1317   [(set (match_operand:HI 0 "push_operand" "=X")
1318         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1319   "!TARGET_64BIT"
1320   "push{l}\t%k1"
1321   [(set_attr "type" "push")
1322    (set_attr "mode" "SI")])
1323
1324 ;; For 64BIT abi we always round up to 8 bytes.
1325 (define_insn "*pushhi2_rex64"
1326   [(set (match_operand:HI 0 "push_operand" "=X")
1327         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1328   "TARGET_64BIT"
1329   "push{q}\t%q1"
1330   [(set_attr "type" "push")
1331    (set_attr "mode" "DI")])
1332
1333 (define_insn "*movhi_1"
1334   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1335         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1336   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1337 {
1338   switch (get_attr_type (insn))
1339     {
1340     case TYPE_IMOVX:
1341       /* movzwl is faster than movw on p2 due to partial word stalls,
1342          though not as fast as an aligned movl.  */
1343       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1344     default:
1345       if (get_attr_mode (insn) == MODE_SI)
1346         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1347       else
1348         return "mov{w}\t{%1, %0|%0, %1}";
1349     }
1350 }
1351   [(set (attr "type")
1352      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1353               (const_string "imov")
1354             (and (eq_attr "alternative" "0")
1355                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1356                           (const_int 0))
1357                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1358                           (const_int 0))))
1359               (const_string "imov")
1360             (and (eq_attr "alternative" "1,2")
1361                  (match_operand:HI 1 "aligned_operand" ""))
1362               (const_string "imov")
1363             (and (ne (symbol_ref "TARGET_MOVX")
1364                      (const_int 0))
1365                  (eq_attr "alternative" "0,2"))
1366               (const_string "imovx")
1367            ]
1368            (const_string "imov")))
1369     (set (attr "mode")
1370       (cond [(eq_attr "type" "imovx")
1371                (const_string "SI")
1372              (and (eq_attr "alternative" "1,2")
1373                   (match_operand:HI 1 "aligned_operand" ""))
1374                (const_string "SI")
1375              (and (eq_attr "alternative" "0")
1376                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1377                            (const_int 0))
1378                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1379                            (const_int 0))))
1380                (const_string "SI")
1381             ]
1382             (const_string "HI")))])
1383
1384 ;; Stores and loads of ax to arbitrary constant address.
1385 ;; We fake an second form of instruction to force reload to load address
1386 ;; into register when rax is not available
1387 (define_insn "*movabshi_1_rex64"
1388   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1389         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1390   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1391   "@
1392    movabs{w}\t{%1, %P0|%P0, %1}
1393    mov{w}\t{%1, %a0|%a0, %1}"
1394   [(set_attr "type" "imov")
1395    (set_attr "modrm" "0,*")
1396    (set_attr "length_address" "8,0")
1397    (set_attr "length_immediate" "0,*")
1398    (set_attr "memory" "store")
1399    (set_attr "mode" "HI")])
1400
1401 (define_insn "*movabshi_2_rex64"
1402   [(set (match_operand:HI 0 "register_operand" "=a,r")
1403         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1404   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1405   "@
1406    movabs{w}\t{%P1, %0|%0, %P1}
1407    mov{w}\t{%a1, %0|%0, %a1}"
1408   [(set_attr "type" "imov")
1409    (set_attr "modrm" "0,*")
1410    (set_attr "length_address" "8,0")
1411    (set_attr "length_immediate" "0")
1412    (set_attr "memory" "load")
1413    (set_attr "mode" "HI")])
1414
1415 (define_insn "*swaphi_1"
1416   [(set (match_operand:HI 0 "register_operand" "+r")
1417         (match_operand:HI 1 "register_operand" "+r"))
1418    (set (match_dup 1)
1419         (match_dup 0))]
1420   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1421   "xchg{l}\t%k1, %k0"
1422   [(set_attr "type" "imov")
1423    (set_attr "mode" "SI")
1424    (set_attr "pent_pair" "np")
1425    (set_attr "athlon_decode" "vector")
1426    (set_attr "amdfam10_decode" "double")])   
1427
1428 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1429 (define_insn "*swaphi_2"
1430   [(set (match_operand:HI 0 "register_operand" "+r")
1431         (match_operand:HI 1 "register_operand" "+r"))
1432    (set (match_dup 1)
1433         (match_dup 0))]
1434   "TARGET_PARTIAL_REG_STALL"
1435   "xchg{w}\t%1, %0"
1436   [(set_attr "type" "imov")
1437    (set_attr "mode" "HI")
1438    (set_attr "pent_pair" "np")
1439    (set_attr "athlon_decode" "vector")])
1440
1441 (define_expand "movstricthi"
1442   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1443         (match_operand:HI 1 "general_operand" ""))]
1444   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1445 {
1446   /* Don't generate memory->memory moves, go through a register */
1447   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1448     operands[1] = force_reg (HImode, operands[1]);
1449 })
1450
1451 (define_insn "*movstricthi_1"
1452   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1453         (match_operand:HI 1 "general_operand" "rn,m"))]
1454   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1455    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1456   "mov{w}\t{%1, %0|%0, %1}"
1457   [(set_attr "type" "imov")
1458    (set_attr "mode" "HI")])
1459
1460 (define_insn "*movstricthi_xor"
1461   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1462         (match_operand:HI 1 "const0_operand" "i"))
1463    (clobber (reg:CC FLAGS_REG))]
1464   "reload_completed
1465    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1466   "xor{w}\t%0, %0"
1467   [(set_attr "type" "alu1")
1468    (set_attr "mode" "HI")
1469    (set_attr "length_immediate" "0")])
1470
1471 (define_expand "movqi"
1472   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1473         (match_operand:QI 1 "general_operand" ""))]
1474   ""
1475   "ix86_expand_move (QImode, operands); DONE;")
1476
1477 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1478 ;; "push a byte".  But actually we use pushl, which has the effect
1479 ;; of rounding the amount pushed up to a word.
1480
1481 (define_insn "*pushqi2"
1482   [(set (match_operand:QI 0 "push_operand" "=X")
1483         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1484   "!TARGET_64BIT"
1485   "push{l}\t%k1"
1486   [(set_attr "type" "push")
1487    (set_attr "mode" "SI")])
1488
1489 ;; For 64BIT abi we always round up to 8 bytes.
1490 (define_insn "*pushqi2_rex64"
1491   [(set (match_operand:QI 0 "push_operand" "=X")
1492         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1493   "TARGET_64BIT"
1494   "push{q}\t%q1"
1495   [(set_attr "type" "push")
1496    (set_attr "mode" "DI")])
1497
1498 ;; Situation is quite tricky about when to choose full sized (SImode) move
1499 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1500 ;; partial register dependency machines (such as AMD Athlon), where QImode
1501 ;; moves issue extra dependency and for partial register stalls machines
1502 ;; that don't use QImode patterns (and QImode move cause stall on the next
1503 ;; instruction).
1504 ;;
1505 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1506 ;; register stall machines with, where we use QImode instructions, since
1507 ;; partial register stall can be caused there.  Then we use movzx.
1508 (define_insn "*movqi_1"
1509   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1510         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1511   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1512 {
1513   switch (get_attr_type (insn))
1514     {
1515     case TYPE_IMOVX:
1516       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1517       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1518     default:
1519       if (get_attr_mode (insn) == MODE_SI)
1520         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1521       else
1522         return "mov{b}\t{%1, %0|%0, %1}";
1523     }
1524 }
1525   [(set (attr "type")
1526      (cond [(and (eq_attr "alternative" "5")
1527                  (not (match_operand:QI 1 "aligned_operand" "")))
1528               (const_string "imovx")
1529             (ne (symbol_ref "optimize_size") (const_int 0))
1530               (const_string "imov")
1531             (and (eq_attr "alternative" "3")
1532                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1533                           (const_int 0))
1534                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1535                           (const_int 0))))
1536               (const_string "imov")
1537             (eq_attr "alternative" "3,5")
1538               (const_string "imovx")
1539             (and (ne (symbol_ref "TARGET_MOVX")
1540                      (const_int 0))
1541                  (eq_attr "alternative" "2"))
1542               (const_string "imovx")
1543            ]
1544            (const_string "imov")))
1545    (set (attr "mode")
1546       (cond [(eq_attr "alternative" "3,4,5")
1547                (const_string "SI")
1548              (eq_attr "alternative" "6")
1549                (const_string "QI")
1550              (eq_attr "type" "imovx")
1551                (const_string "SI")
1552              (and (eq_attr "type" "imov")
1553                   (and (eq_attr "alternative" "0,1")
1554                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1555                                 (const_int 0))
1556                             (and (eq (symbol_ref "optimize_size")
1557                                      (const_int 0))
1558                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1559                                      (const_int 0))))))
1560                (const_string "SI")
1561              ;; Avoid partial register stalls when not using QImode arithmetic
1562              (and (eq_attr "type" "imov")
1563                   (and (eq_attr "alternative" "0,1")
1564                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1565                                 (const_int 0))
1566                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1567                                 (const_int 0)))))
1568                (const_string "SI")
1569            ]
1570            (const_string "QI")))])
1571
1572 (define_expand "reload_outqi"
1573   [(parallel [(match_operand:QI 0 "" "=m")
1574               (match_operand:QI 1 "register_operand" "r")
1575               (match_operand:QI 2 "register_operand" "=&q")])]
1576   ""
1577 {
1578   rtx op0, op1, op2;
1579   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1580
1581   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1582   if (! q_regs_operand (op1, QImode))
1583     {
1584       emit_insn (gen_movqi (op2, op1));
1585       op1 = op2;
1586     }
1587   emit_insn (gen_movqi (op0, op1));
1588   DONE;
1589 })
1590
1591 (define_insn "*swapqi_1"
1592   [(set (match_operand:QI 0 "register_operand" "+r")
1593         (match_operand:QI 1 "register_operand" "+r"))
1594    (set (match_dup 1)
1595         (match_dup 0))]
1596   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1597   "xchg{l}\t%k1, %k0"
1598   [(set_attr "type" "imov")
1599    (set_attr "mode" "SI")
1600    (set_attr "pent_pair" "np")
1601    (set_attr "athlon_decode" "vector")
1602    (set_attr "amdfam10_decode" "vector")])   
1603
1604 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1605 (define_insn "*swapqi_2"
1606   [(set (match_operand:QI 0 "register_operand" "+q")
1607         (match_operand:QI 1 "register_operand" "+q"))
1608    (set (match_dup 1)
1609         (match_dup 0))]
1610   "TARGET_PARTIAL_REG_STALL"
1611   "xchg{b}\t%1, %0"
1612   [(set_attr "type" "imov")
1613    (set_attr "mode" "QI")
1614    (set_attr "pent_pair" "np")
1615    (set_attr "athlon_decode" "vector")])
1616
1617 (define_expand "movstrictqi"
1618   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1619         (match_operand:QI 1 "general_operand" ""))]
1620   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1621 {
1622   /* Don't generate memory->memory moves, go through a register.  */
1623   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1624     operands[1] = force_reg (QImode, operands[1]);
1625 })
1626
1627 (define_insn "*movstrictqi_1"
1628   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1629         (match_operand:QI 1 "general_operand" "*qn,m"))]
1630   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1631    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1632   "mov{b}\t{%1, %0|%0, %1}"
1633   [(set_attr "type" "imov")
1634    (set_attr "mode" "QI")])
1635
1636 (define_insn "*movstrictqi_xor"
1637   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1638         (match_operand:QI 1 "const0_operand" "i"))
1639    (clobber (reg:CC FLAGS_REG))]
1640   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1641   "xor{b}\t%0, %0"
1642   [(set_attr "type" "alu1")
1643    (set_attr "mode" "QI")
1644    (set_attr "length_immediate" "0")])
1645
1646 (define_insn "*movsi_extv_1"
1647   [(set (match_operand:SI 0 "register_operand" "=R")
1648         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1649                          (const_int 8)
1650                          (const_int 8)))]
1651   ""
1652   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1653   [(set_attr "type" "imovx")
1654    (set_attr "mode" "SI")])
1655
1656 (define_insn "*movhi_extv_1"
1657   [(set (match_operand:HI 0 "register_operand" "=R")
1658         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1659                          (const_int 8)
1660                          (const_int 8)))]
1661   ""
1662   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1663   [(set_attr "type" "imovx")
1664    (set_attr "mode" "SI")])
1665
1666 (define_insn "*movqi_extv_1"
1667   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1668         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1669                          (const_int 8)
1670                          (const_int 8)))]
1671   "!TARGET_64BIT"
1672 {
1673   switch (get_attr_type (insn))
1674     {
1675     case TYPE_IMOVX:
1676       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1677     default:
1678       return "mov{b}\t{%h1, %0|%0, %h1}";
1679     }
1680 }
1681   [(set (attr "type")
1682      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1683                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1684                              (ne (symbol_ref "TARGET_MOVX")
1685                                  (const_int 0))))
1686         (const_string "imovx")
1687         (const_string "imov")))
1688    (set (attr "mode")
1689      (if_then_else (eq_attr "type" "imovx")
1690         (const_string "SI")
1691         (const_string "QI")))])
1692
1693 (define_insn "*movqi_extv_1_rex64"
1694   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1695         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1696                          (const_int 8)
1697                          (const_int 8)))]
1698   "TARGET_64BIT"
1699 {
1700   switch (get_attr_type (insn))
1701     {
1702     case TYPE_IMOVX:
1703       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1704     default:
1705       return "mov{b}\t{%h1, %0|%0, %h1}";
1706     }
1707 }
1708   [(set (attr "type")
1709      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1710                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1711                              (ne (symbol_ref "TARGET_MOVX")
1712                                  (const_int 0))))
1713         (const_string "imovx")
1714         (const_string "imov")))
1715    (set (attr "mode")
1716      (if_then_else (eq_attr "type" "imovx")
1717         (const_string "SI")
1718         (const_string "QI")))])
1719
1720 ;; Stores and loads of ax to arbitrary constant address.
1721 ;; We fake an second form of instruction to force reload to load address
1722 ;; into register when rax is not available
1723 (define_insn "*movabsqi_1_rex64"
1724   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1725         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1726   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1727   "@
1728    movabs{b}\t{%1, %P0|%P0, %1}
1729    mov{b}\t{%1, %a0|%a0, %1}"
1730   [(set_attr "type" "imov")
1731    (set_attr "modrm" "0,*")
1732    (set_attr "length_address" "8,0")
1733    (set_attr "length_immediate" "0,*")
1734    (set_attr "memory" "store")
1735    (set_attr "mode" "QI")])
1736
1737 (define_insn "*movabsqi_2_rex64"
1738   [(set (match_operand:QI 0 "register_operand" "=a,r")
1739         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1740   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1741   "@
1742    movabs{b}\t{%P1, %0|%0, %P1}
1743    mov{b}\t{%a1, %0|%0, %a1}"
1744   [(set_attr "type" "imov")
1745    (set_attr "modrm" "0,*")
1746    (set_attr "length_address" "8,0")
1747    (set_attr "length_immediate" "0")
1748    (set_attr "memory" "load")
1749    (set_attr "mode" "QI")])
1750
1751 (define_insn "*movdi_extzv_1"
1752   [(set (match_operand:DI 0 "register_operand" "=R")
1753         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1754                          (const_int 8)
1755                          (const_int 8)))]
1756   "TARGET_64BIT"
1757   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1758   [(set_attr "type" "imovx")
1759    (set_attr "mode" "DI")])
1760
1761 (define_insn "*movsi_extzv_1"
1762   [(set (match_operand:SI 0 "register_operand" "=R")
1763         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1764                          (const_int 8)
1765                          (const_int 8)))]
1766   ""
1767   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1768   [(set_attr "type" "imovx")
1769    (set_attr "mode" "SI")])
1770
1771 (define_insn "*movqi_extzv_2"
1772   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1773         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1774                                     (const_int 8)
1775                                     (const_int 8)) 0))]
1776   "!TARGET_64BIT"
1777 {
1778   switch (get_attr_type (insn))
1779     {
1780     case TYPE_IMOVX:
1781       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1782     default:
1783       return "mov{b}\t{%h1, %0|%0, %h1}";
1784     }
1785 }
1786   [(set (attr "type")
1787      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1788                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1789                              (ne (symbol_ref "TARGET_MOVX")
1790                                  (const_int 0))))
1791         (const_string "imovx")
1792         (const_string "imov")))
1793    (set (attr "mode")
1794      (if_then_else (eq_attr "type" "imovx")
1795         (const_string "SI")
1796         (const_string "QI")))])
1797
1798 (define_insn "*movqi_extzv_2_rex64"
1799   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1800         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1801                                     (const_int 8)
1802                                     (const_int 8)) 0))]
1803   "TARGET_64BIT"
1804 {
1805   switch (get_attr_type (insn))
1806     {
1807     case TYPE_IMOVX:
1808       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1809     default:
1810       return "mov{b}\t{%h1, %0|%0, %h1}";
1811     }
1812 }
1813   [(set (attr "type")
1814      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1815                         (ne (symbol_ref "TARGET_MOVX")
1816                             (const_int 0)))
1817         (const_string "imovx")
1818         (const_string "imov")))
1819    (set (attr "mode")
1820      (if_then_else (eq_attr "type" "imovx")
1821         (const_string "SI")
1822         (const_string "QI")))])
1823
1824 (define_insn "movsi_insv_1"
1825   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1826                          (const_int 8)
1827                          (const_int 8))
1828         (match_operand:SI 1 "general_operand" "Qmn"))]
1829   "!TARGET_64BIT"
1830   "mov{b}\t{%b1, %h0|%h0, %b1}"
1831   [(set_attr "type" "imov")
1832    (set_attr "mode" "QI")])
1833
1834 (define_insn "*movsi_insv_1_rex64"
1835   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1836                          (const_int 8)
1837                          (const_int 8))
1838         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1839   "TARGET_64BIT"
1840   "mov{b}\t{%b1, %h0|%h0, %b1}"
1841   [(set_attr "type" "imov")
1842    (set_attr "mode" "QI")])
1843
1844 (define_insn "movdi_insv_1_rex64"
1845   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1846                          (const_int 8)
1847                          (const_int 8))
1848         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1849   "TARGET_64BIT"
1850   "mov{b}\t{%b1, %h0|%h0, %b1}"
1851   [(set_attr "type" "imov")
1852    (set_attr "mode" "QI")])
1853
1854 (define_insn "*movqi_insv_2"
1855   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1856                          (const_int 8)
1857                          (const_int 8))
1858         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1859                      (const_int 8)))]
1860   ""
1861   "mov{b}\t{%h1, %h0|%h0, %h1}"
1862   [(set_attr "type" "imov")
1863    (set_attr "mode" "QI")])
1864
1865 (define_expand "movdi"
1866   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1867         (match_operand:DI 1 "general_operand" ""))]
1868   ""
1869   "ix86_expand_move (DImode, operands); DONE;")
1870
1871 (define_insn "*pushdi"
1872   [(set (match_operand:DI 0 "push_operand" "=<")
1873         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1874   "!TARGET_64BIT"
1875   "#")
1876
1877 (define_insn "*pushdi2_rex64"
1878   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1879         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1880   "TARGET_64BIT"
1881   "@
1882    push{q}\t%1
1883    #"
1884   [(set_attr "type" "push,multi")
1885    (set_attr "mode" "DI")])
1886
1887 ;; Convert impossible pushes of immediate to existing instructions.
1888 ;; First try to get scratch register and go through it.  In case this
1889 ;; fails, push sign extended lower part first and then overwrite
1890 ;; upper part by 32bit move.
1891 (define_peephole2
1892   [(match_scratch:DI 2 "r")
1893    (set (match_operand:DI 0 "push_operand" "")
1894         (match_operand:DI 1 "immediate_operand" ""))]
1895   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1896    && !x86_64_immediate_operand (operands[1], DImode)"
1897   [(set (match_dup 2) (match_dup 1))
1898    (set (match_dup 0) (match_dup 2))]
1899   "")
1900
1901 ;; We need to define this as both peepholer and splitter for case
1902 ;; peephole2 pass is not run.
1903 ;; "&& 1" is needed to keep it from matching the previous pattern.
1904 (define_peephole2
1905   [(set (match_operand:DI 0 "push_operand" "")
1906         (match_operand:DI 1 "immediate_operand" ""))]
1907   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1908    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1909   [(set (match_dup 0) (match_dup 1))
1910    (set (match_dup 2) (match_dup 3))]
1911   "split_di (operands + 1, 1, operands + 2, operands + 3);
1912    operands[1] = gen_lowpart (DImode, operands[2]);
1913    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1914                                                     GEN_INT (4)));
1915   ")
1916
1917 (define_split
1918   [(set (match_operand:DI 0 "push_operand" "")
1919         (match_operand:DI 1 "immediate_operand" ""))]
1920   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1921                     ? flow2_completed : reload_completed)
1922    && !symbolic_operand (operands[1], DImode)
1923    && !x86_64_immediate_operand (operands[1], DImode)"
1924   [(set (match_dup 0) (match_dup 1))
1925    (set (match_dup 2) (match_dup 3))]
1926   "split_di (operands + 1, 1, operands + 2, operands + 3);
1927    operands[1] = gen_lowpart (DImode, operands[2]);
1928    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1929                                                     GEN_INT (4)));
1930   ")
1931
1932 (define_insn "*pushdi2_prologue_rex64"
1933   [(set (match_operand:DI 0 "push_operand" "=<")
1934         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1935    (clobber (mem:BLK (scratch)))]
1936   "TARGET_64BIT"
1937   "push{q}\t%1"
1938   [(set_attr "type" "push")
1939    (set_attr "mode" "DI")])
1940
1941 (define_insn "*popdi1_epilogue_rex64"
1942   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1943         (mem:DI (reg:DI SP_REG)))
1944    (set (reg:DI SP_REG)
1945         (plus:DI (reg:DI SP_REG) (const_int 8)))
1946    (clobber (mem:BLK (scratch)))]
1947   "TARGET_64BIT"
1948   "pop{q}\t%0"
1949   [(set_attr "type" "pop")
1950    (set_attr "mode" "DI")])
1951
1952 (define_insn "popdi1"
1953   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1954         (mem:DI (reg:DI SP_REG)))
1955    (set (reg:DI SP_REG)
1956         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1957   "TARGET_64BIT"
1958   "pop{q}\t%0"
1959   [(set_attr "type" "pop")
1960    (set_attr "mode" "DI")])
1961
1962 (define_insn "*movdi_xor_rex64"
1963   [(set (match_operand:DI 0 "register_operand" "=r")
1964         (match_operand:DI 1 "const0_operand" "i"))
1965    (clobber (reg:CC FLAGS_REG))]
1966   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1967    && reload_completed"
1968   "xor{l}\t%k0, %k0";
1969   [(set_attr "type" "alu1")
1970    (set_attr "mode" "SI")
1971    (set_attr "length_immediate" "0")])
1972
1973 (define_insn "*movdi_or_rex64"
1974   [(set (match_operand:DI 0 "register_operand" "=r")
1975         (match_operand:DI 1 "const_int_operand" "i"))
1976    (clobber (reg:CC FLAGS_REG))]
1977   "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
1978    && reload_completed
1979    && operands[1] == constm1_rtx"
1980 {
1981   operands[1] = constm1_rtx;
1982   return "or{q}\t{%1, %0|%0, %1}";
1983 }
1984   [(set_attr "type" "alu1")
1985    (set_attr "mode" "DI")
1986    (set_attr "length_immediate" "1")])
1987
1988 (define_insn "*movdi_2"
1989   [(set (match_operand:DI 0 "nonimmediate_operand"
1990                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
1991         (match_operand:DI 1 "general_operand"
1992                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
1993   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1994   "@
1995    #
1996    #
1997    pxor\t%0, %0
1998    movq\t{%1, %0|%0, %1}
1999    movq\t{%1, %0|%0, %1}
2000    pxor\t%0, %0
2001    movq\t{%1, %0|%0, %1}
2002    movdqa\t{%1, %0|%0, %1}
2003    movq\t{%1, %0|%0, %1}
2004    xorps\t%0, %0
2005    movlps\t{%1, %0|%0, %1}
2006    movaps\t{%1, %0|%0, %1}
2007    movlps\t{%1, %0|%0, %1}"
2008   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2009    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2010
2011 (define_split
2012   [(set (match_operand:DI 0 "push_operand" "")
2013         (match_operand:DI 1 "general_operand" ""))]
2014   "!TARGET_64BIT && reload_completed
2015    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2016   [(const_int 0)]
2017   "ix86_split_long_move (operands); DONE;")
2018
2019 ;; %%% This multiword shite has got to go.
2020 (define_split
2021   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2022         (match_operand:DI 1 "general_operand" ""))]
2023   "!TARGET_64BIT && reload_completed
2024    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2025    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2026   [(const_int 0)]
2027   "ix86_split_long_move (operands); DONE;")
2028
2029 (define_insn "*movdi_1_rex64"
2030   [(set (match_operand:DI 0 "nonimmediate_operand"
2031           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2032         (match_operand:DI 1 "general_operand"
2033           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2034   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2035 {
2036   switch (get_attr_type (insn))
2037     {
2038     case TYPE_SSECVT:
2039       if (SSE_REG_P (operands[0]))
2040         return "movq2dq\t{%1, %0|%0, %1}";
2041       else
2042         return "movdq2q\t{%1, %0|%0, %1}";
2043
2044     case TYPE_SSEMOV:
2045       if (get_attr_mode (insn) == MODE_TI)
2046         return "movdqa\t{%1, %0|%0, %1}";
2047       /* FALLTHRU */
2048
2049     case TYPE_MMXMOV:
2050       /* Moves from and into integer register is done using movd
2051          opcode with REX prefix.  */
2052       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2053         return "movd\t{%1, %0|%0, %1}";
2054       return "movq\t{%1, %0|%0, %1}";
2055
2056     case TYPE_SSELOG1:
2057     case TYPE_MMXADD:
2058       return "pxor\t%0, %0";
2059
2060     case TYPE_MULTI:
2061       return "#";
2062
2063     case TYPE_LEA:
2064       return "lea{q}\t{%a1, %0|%0, %a1}";
2065
2066     default:
2067       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2068       if (get_attr_mode (insn) == MODE_SI)
2069         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2070       else if (which_alternative == 2)
2071         return "movabs{q}\t{%1, %0|%0, %1}";
2072       else
2073         return "mov{q}\t{%1, %0|%0, %1}";
2074     }
2075 }
2076   [(set (attr "type")
2077      (cond [(eq_attr "alternative" "5")
2078               (const_string "mmxadd")
2079             (eq_attr "alternative" "6,7,8,9,10")
2080               (const_string "mmxmov")
2081             (eq_attr "alternative" "11")
2082               (const_string "sselog1")
2083             (eq_attr "alternative" "12,13,14,15,16")
2084               (const_string "ssemov")
2085             (eq_attr "alternative" "17,18")
2086               (const_string "ssecvt")
2087             (eq_attr "alternative" "4")
2088               (const_string "multi")
2089             (match_operand:DI 1 "pic_32bit_operand" "")
2090               (const_string "lea")
2091            ]
2092            (const_string "imov")))
2093    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2094    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2095    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2096
2097 ;; Stores and loads of ax to arbitrary constant address.
2098 ;; We fake an second form of instruction to force reload to load address
2099 ;; into register when rax is not available
2100 (define_insn "*movabsdi_1_rex64"
2101   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2102         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2103   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2104   "@
2105    movabs{q}\t{%1, %P0|%P0, %1}
2106    mov{q}\t{%1, %a0|%a0, %1}"
2107   [(set_attr "type" "imov")
2108    (set_attr "modrm" "0,*")
2109    (set_attr "length_address" "8,0")
2110    (set_attr "length_immediate" "0,*")
2111    (set_attr "memory" "store")
2112    (set_attr "mode" "DI")])
2113
2114 (define_insn "*movabsdi_2_rex64"
2115   [(set (match_operand:DI 0 "register_operand" "=a,r")
2116         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2117   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2118   "@
2119    movabs{q}\t{%P1, %0|%0, %P1}
2120    mov{q}\t{%a1, %0|%0, %a1}"
2121   [(set_attr "type" "imov")
2122    (set_attr "modrm" "0,*")
2123    (set_attr "length_address" "8,0")
2124    (set_attr "length_immediate" "0")
2125    (set_attr "memory" "load")
2126    (set_attr "mode" "DI")])
2127
2128 ;; Convert impossible stores of immediate to existing instructions.
2129 ;; First try to get scratch register and go through it.  In case this
2130 ;; fails, move by 32bit parts.
2131 (define_peephole2
2132   [(match_scratch:DI 2 "r")
2133    (set (match_operand:DI 0 "memory_operand" "")
2134         (match_operand:DI 1 "immediate_operand" ""))]
2135   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2136    && !x86_64_immediate_operand (operands[1], DImode)"
2137   [(set (match_dup 2) (match_dup 1))
2138    (set (match_dup 0) (match_dup 2))]
2139   "")
2140
2141 ;; We need to define this as both peepholer and splitter for case
2142 ;; peephole2 pass is not run.
2143 ;; "&& 1" is needed to keep it from matching the previous pattern.
2144 (define_peephole2
2145   [(set (match_operand:DI 0 "memory_operand" "")
2146         (match_operand:DI 1 "immediate_operand" ""))]
2147   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2148    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2149   [(set (match_dup 2) (match_dup 3))
2150    (set (match_dup 4) (match_dup 5))]
2151   "split_di (operands, 2, operands + 2, operands + 4);")
2152
2153 (define_split
2154   [(set (match_operand:DI 0 "memory_operand" "")
2155         (match_operand:DI 1 "immediate_operand" ""))]
2156   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2157                     ? flow2_completed : reload_completed)
2158    && !symbolic_operand (operands[1], DImode)
2159    && !x86_64_immediate_operand (operands[1], DImode)"
2160   [(set (match_dup 2) (match_dup 3))
2161    (set (match_dup 4) (match_dup 5))]
2162   "split_di (operands, 2, operands + 2, operands + 4);")
2163
2164 (define_insn "*swapdi_rex64"
2165   [(set (match_operand:DI 0 "register_operand" "+r")
2166         (match_operand:DI 1 "register_operand" "+r"))
2167    (set (match_dup 1)
2168         (match_dup 0))]
2169   "TARGET_64BIT"
2170   "xchg{q}\t%1, %0"
2171   [(set_attr "type" "imov")
2172    (set_attr "mode" "DI")
2173    (set_attr "pent_pair" "np")
2174    (set_attr "athlon_decode" "vector")
2175    (set_attr "amdfam10_decode" "double")])   
2176
2177 (define_expand "movti"
2178   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2179         (match_operand:TI 1 "nonimmediate_operand" ""))]
2180   "TARGET_SSE || TARGET_64BIT"
2181 {
2182   if (TARGET_64BIT)
2183     ix86_expand_move (TImode, operands);
2184   else if (push_operand (operands[0], TImode))
2185     ix86_expand_push (TImode, operands[1]);
2186   else
2187     ix86_expand_vector_move (TImode, operands);
2188   DONE;
2189 })
2190
2191 (define_insn "*movti_internal"
2192   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2193         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2194   "TARGET_SSE && !TARGET_64BIT
2195    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2196 {
2197   switch (which_alternative)
2198     {
2199     case 0:
2200       if (get_attr_mode (insn) == MODE_V4SF)
2201         return "xorps\t%0, %0";
2202       else
2203         return "pxor\t%0, %0";
2204     case 1:
2205     case 2:
2206       if (get_attr_mode (insn) == MODE_V4SF)
2207         return "movaps\t{%1, %0|%0, %1}";
2208       else
2209         return "movdqa\t{%1, %0|%0, %1}";
2210     default:
2211       gcc_unreachable ();
2212     }
2213 }
2214   [(set_attr "type" "sselog1,ssemov,ssemov")
2215    (set (attr "mode")
2216         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2217                     (ne (symbol_ref "optimize_size") (const_int 0)))
2218                  (const_string "V4SF")
2219                (and (eq_attr "alternative" "2")
2220                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2221                         (const_int 0)))
2222                  (const_string "V4SF")]
2223               (const_string "TI")))])
2224
2225 (define_insn "*movti_rex64"
2226   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2227         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2228   "TARGET_64BIT
2229    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2230 {
2231   switch (which_alternative)
2232     {
2233     case 0:
2234     case 1:
2235       return "#";
2236     case 2:
2237       if (get_attr_mode (insn) == MODE_V4SF)
2238         return "xorps\t%0, %0";
2239       else
2240         return "pxor\t%0, %0";
2241     case 3:
2242     case 4:
2243       if (get_attr_mode (insn) == MODE_V4SF)
2244         return "movaps\t{%1, %0|%0, %1}";
2245       else
2246         return "movdqa\t{%1, %0|%0, %1}";
2247     default:
2248       gcc_unreachable ();
2249     }
2250 }
2251   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2252    (set (attr "mode")
2253         (cond [(eq_attr "alternative" "2,3")
2254                  (if_then_else
2255                    (ne (symbol_ref "optimize_size")
2256                        (const_int 0))
2257                    (const_string "V4SF")
2258                    (const_string "TI"))
2259                (eq_attr "alternative" "4")
2260                  (if_then_else
2261                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2262                             (const_int 0))
2263                         (ne (symbol_ref "optimize_size")
2264                             (const_int 0)))
2265                    (const_string "V4SF")
2266                    (const_string "TI"))]
2267                (const_string "DI")))])
2268
2269 (define_split
2270   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2271         (match_operand:TI 1 "general_operand" ""))]
2272   "reload_completed && !SSE_REG_P (operands[0])
2273    && !SSE_REG_P (operands[1])"
2274   [(const_int 0)]
2275   "ix86_split_long_move (operands); DONE;")
2276
2277 ;; This expands to what emit_move_complex would generate if we didn't
2278 ;; have a movti pattern.  Having this avoids problems with reload on
2279 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2280 ;; to have around all the time.
2281 (define_expand "movcdi"
2282   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2283         (match_operand:CDI 1 "general_operand" ""))]
2284   ""
2285 {
2286   if (push_operand (operands[0], CDImode))
2287     emit_move_complex_push (CDImode, operands[0], operands[1]);
2288   else
2289     emit_move_complex_parts (operands[0], operands[1]);
2290   DONE;
2291 })
2292
2293 (define_expand "movsf"
2294   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2295         (match_operand:SF 1 "general_operand" ""))]
2296   ""
2297   "ix86_expand_move (SFmode, operands); DONE;")
2298
2299 (define_insn "*pushsf"
2300   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2301         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2302   "!TARGET_64BIT"
2303 {
2304   /* Anything else should be already split before reg-stack.  */
2305   gcc_assert (which_alternative == 1);
2306   return "push{l}\t%1";
2307 }
2308   [(set_attr "type" "multi,push,multi")
2309    (set_attr "unit" "i387,*,*")
2310    (set_attr "mode" "SF,SI,SF")])
2311
2312 (define_insn "*pushsf_rex64"
2313   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2314         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2315   "TARGET_64BIT"
2316 {
2317   /* Anything else should be already split before reg-stack.  */
2318   gcc_assert (which_alternative == 1);
2319   return "push{q}\t%q1";
2320 }
2321   [(set_attr "type" "multi,push,multi")
2322    (set_attr "unit" "i387,*,*")
2323    (set_attr "mode" "SF,DI,SF")])
2324
2325 (define_split
2326   [(set (match_operand:SF 0 "push_operand" "")
2327         (match_operand:SF 1 "memory_operand" ""))]
2328   "reload_completed
2329    && MEM_P (operands[1])
2330    && (operands[2] = find_constant_src (insn))"
2331   [(set (match_dup 0)
2332         (match_dup 2))])
2333
2334
2335 ;; %%% Kill this when call knows how to work this out.
2336 (define_split
2337   [(set (match_operand:SF 0 "push_operand" "")
2338         (match_operand:SF 1 "any_fp_register_operand" ""))]
2339   "!TARGET_64BIT"
2340   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2341    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2342
2343 (define_split
2344   [(set (match_operand:SF 0 "push_operand" "")
2345         (match_operand:SF 1 "any_fp_register_operand" ""))]
2346   "TARGET_64BIT"
2347   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2348    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2349
2350 (define_insn "*movsf_1"
2351   [(set (match_operand:SF 0 "nonimmediate_operand"
2352           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2353         (match_operand:SF 1 "general_operand"
2354           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2355   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2356    && (reload_in_progress || reload_completed
2357        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2358        || (!TARGET_SSE_MATH && optimize_size
2359            && standard_80387_constant_p (operands[1]))
2360        || GET_CODE (operands[1]) != CONST_DOUBLE
2361        || memory_operand (operands[0], SFmode))"
2362 {
2363   switch (which_alternative)
2364     {
2365     case 0:
2366     case 1:
2367       return output_387_reg_move (insn, operands);
2368
2369     case 2:
2370       return standard_80387_constant_opcode (operands[1]);
2371
2372     case 3:
2373     case 4:
2374       return "mov{l}\t{%1, %0|%0, %1}";
2375     case 5:
2376       if (get_attr_mode (insn) == MODE_TI)
2377         return "pxor\t%0, %0";
2378       else
2379         return "xorps\t%0, %0";
2380     case 6:
2381       if (get_attr_mode (insn) == MODE_V4SF)
2382         return "movaps\t{%1, %0|%0, %1}";
2383       else
2384         return "movss\t{%1, %0|%0, %1}";
2385     case 7: case 8:
2386       return "movss\t{%1, %0|%0, %1}";
2387
2388     case 9: case 10:
2389     case 12: case 13: case 14: case 15:
2390       return "movd\t{%1, %0|%0, %1}";
2391
2392     case 11:
2393       return "movq\t{%1, %0|%0, %1}";
2394
2395     default:
2396       gcc_unreachable ();
2397     }
2398 }
2399   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2400    (set (attr "mode")
2401         (cond [(eq_attr "alternative" "3,4,9,10")
2402                  (const_string "SI")
2403                (eq_attr "alternative" "5")
2404                  (if_then_else
2405                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2406                                  (const_int 0))
2407                              (ne (symbol_ref "TARGET_SSE2")
2408                                  (const_int 0)))
2409                         (eq (symbol_ref "optimize_size")
2410                             (const_int 0)))
2411                    (const_string "TI")
2412                    (const_string "V4SF"))
2413                /* For architectures resolving dependencies on
2414                   whole SSE registers use APS move to break dependency
2415                   chains, otherwise use short move to avoid extra work.
2416
2417                   Do the same for architectures resolving dependencies on
2418                   the parts.  While in DF mode it is better to always handle
2419                   just register parts, the SF mode is different due to lack
2420                   of instructions to load just part of the register.  It is
2421                   better to maintain the whole registers in single format
2422                   to avoid problems on using packed logical operations.  */
2423                (eq_attr "alternative" "6")
2424                  (if_then_else
2425                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2426                             (const_int 0))
2427                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2428                             (const_int 0)))
2429                    (const_string "V4SF")
2430                    (const_string "SF"))
2431                (eq_attr "alternative" "11")
2432                  (const_string "DI")]
2433                (const_string "SF")))])
2434
2435 (define_insn "*swapsf"
2436   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2437         (match_operand:SF 1 "fp_register_operand" "+f"))
2438    (set (match_dup 1)
2439         (match_dup 0))]
2440   "reload_completed || TARGET_80387"
2441 {
2442   if (STACK_TOP_P (operands[0]))
2443     return "fxch\t%1";
2444   else
2445     return "fxch\t%0";
2446 }
2447   [(set_attr "type" "fxch")
2448    (set_attr "mode" "SF")])
2449
2450 (define_expand "movdf"
2451   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2452         (match_operand:DF 1 "general_operand" ""))]
2453   ""
2454   "ix86_expand_move (DFmode, operands); DONE;")
2455
2456 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2457 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2458 ;; On the average, pushdf using integers can be still shorter.  Allow this
2459 ;; pattern for optimize_size too.
2460
2461 (define_insn "*pushdf_nointeger"
2462   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2463         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2464   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2465 {
2466   /* This insn should be already split before reg-stack.  */
2467   gcc_unreachable ();
2468 }
2469   [(set_attr "type" "multi")
2470    (set_attr "unit" "i387,*,*,*")
2471    (set_attr "mode" "DF,SI,SI,DF")])
2472
2473 (define_insn "*pushdf_integer"
2474   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2475         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2476   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2477 {
2478   /* This insn should be already split before reg-stack.  */
2479   gcc_unreachable ();
2480 }
2481   [(set_attr "type" "multi")
2482    (set_attr "unit" "i387,*,*")
2483    (set_attr "mode" "DF,SI,DF")])
2484
2485 ;; %%% Kill this when call knows how to work this out.
2486 (define_split
2487   [(set (match_operand:DF 0 "push_operand" "")
2488         (match_operand:DF 1 "any_fp_register_operand" ""))]
2489   "!TARGET_64BIT && reload_completed"
2490   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2491    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2492   "")
2493
2494 (define_split
2495   [(set (match_operand:DF 0 "push_operand" "")
2496         (match_operand:DF 1 "any_fp_register_operand" ""))]
2497   "TARGET_64BIT && reload_completed"
2498   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2499    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2500   "")
2501
2502 (define_split
2503   [(set (match_operand:DF 0 "push_operand" "")
2504         (match_operand:DF 1 "general_operand" ""))]
2505   "reload_completed"
2506   [(const_int 0)]
2507   "ix86_split_long_move (operands); DONE;")
2508
2509 ;; Moving is usually shorter when only FP registers are used. This separate
2510 ;; movdf pattern avoids the use of integer registers for FP operations
2511 ;; when optimizing for size.
2512
2513 (define_insn "*movdf_nointeger"
2514   [(set (match_operand:DF 0 "nonimmediate_operand"
2515                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2516         (match_operand:DF 1 "general_operand"
2517                         "fm,f,G,*roF,F*r,C   ,Y2*x,mY2*x,Y2*x"))]
2518   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2519    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2520    && (reload_in_progress || reload_completed
2521        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2522        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2523            && standard_80387_constant_p (operands[1]))
2524        || GET_CODE (operands[1]) != CONST_DOUBLE
2525        || memory_operand (operands[0], DFmode))"
2526 {
2527   switch (which_alternative)
2528     {
2529     case 0:
2530     case 1:
2531       return output_387_reg_move (insn, operands);
2532
2533     case 2:
2534       return standard_80387_constant_opcode (operands[1]);
2535
2536     case 3:
2537     case 4:
2538       return "#";
2539     case 5:
2540       switch (get_attr_mode (insn))
2541         {
2542         case MODE_V4SF:
2543           return "xorps\t%0, %0";
2544         case MODE_V2DF:
2545           return "xorpd\t%0, %0";
2546         case MODE_TI:
2547           return "pxor\t%0, %0";
2548         default:
2549           gcc_unreachable ();
2550         }
2551     case 6:
2552     case 7:
2553     case 8:
2554       switch (get_attr_mode (insn))
2555         {
2556         case MODE_V4SF:
2557           return "movaps\t{%1, %0|%0, %1}";
2558         case MODE_V2DF:
2559           return "movapd\t{%1, %0|%0, %1}";
2560         case MODE_TI:
2561           return "movdqa\t{%1, %0|%0, %1}";
2562         case MODE_DI:
2563           return "movq\t{%1, %0|%0, %1}";
2564         case MODE_DF:
2565           return "movsd\t{%1, %0|%0, %1}";
2566         case MODE_V1DF:
2567           return "movlpd\t{%1, %0|%0, %1}";
2568         case MODE_V2SF:
2569           return "movlps\t{%1, %0|%0, %1}";
2570         default:
2571           gcc_unreachable ();
2572         }
2573
2574     default:
2575       gcc_unreachable ();
2576     }
2577 }
2578   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2579    (set (attr "mode")
2580         (cond [(eq_attr "alternative" "0,1,2")
2581                  (const_string "DF")
2582                (eq_attr "alternative" "3,4")
2583                  (const_string "SI")
2584
2585                /* For SSE1, we have many fewer alternatives.  */
2586                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2587                  (cond [(eq_attr "alternative" "5,6")
2588                           (const_string "V4SF")
2589                        ]
2590                    (const_string "V2SF"))
2591
2592                /* xorps is one byte shorter.  */
2593                (eq_attr "alternative" "5")
2594                  (cond [(ne (symbol_ref "optimize_size")
2595                             (const_int 0))
2596                           (const_string "V4SF")
2597                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2598                             (const_int 0))
2599                           (const_string "TI")
2600                        ]
2601                        (const_string "V2DF"))
2602
2603                /* For architectures resolving dependencies on
2604                   whole SSE registers use APD move to break dependency
2605                   chains, otherwise use short move to avoid extra work.
2606
2607                   movaps encodes one byte shorter.  */
2608                (eq_attr "alternative" "6")
2609                  (cond
2610                    [(ne (symbol_ref "optimize_size")
2611                         (const_int 0))
2612                       (const_string "V4SF")
2613                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2614                         (const_int 0))
2615                       (const_string "V2DF")
2616                    ]
2617                    (const_string "DF"))
2618                /* For architectures resolving dependencies on register
2619                   parts we may avoid extra work to zero out upper part
2620                   of register.  */
2621                (eq_attr "alternative" "7")
2622                  (if_then_else
2623                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2624                        (const_int 0))
2625                    (const_string "V1DF")
2626                    (const_string "DF"))
2627               ]
2628               (const_string "DF")))])
2629
2630 (define_insn "*movdf_integer_rex64"
2631   [(set (match_operand:DF 0 "nonimmediate_operand"
2632                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2633         (match_operand:DF 1 "general_operand"
2634                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2635   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2636    && (reload_in_progress || reload_completed
2637        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2638        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2639            && standard_80387_constant_p (operands[1]))
2640        || GET_CODE (operands[1]) != CONST_DOUBLE
2641        || memory_operand (operands[0], DFmode))"
2642 {
2643   switch (which_alternative)
2644     {
2645     case 0:
2646     case 1:
2647       return output_387_reg_move (insn, operands);
2648
2649     case 2:
2650       return standard_80387_constant_opcode (operands[1]);
2651
2652     case 3:
2653     case 4:
2654       return "#";
2655
2656     case 5:
2657       switch (get_attr_mode (insn))
2658         {
2659         case MODE_V4SF:
2660           return "xorps\t%0, %0";
2661         case MODE_V2DF:
2662           return "xorpd\t%0, %0";
2663         case MODE_TI:
2664           return "pxor\t%0, %0";
2665         default:
2666           gcc_unreachable ();
2667         }
2668     case 6:
2669     case 7:
2670     case 8:
2671       switch (get_attr_mode (insn))
2672         {
2673         case MODE_V4SF:
2674           return "movaps\t{%1, %0|%0, %1}";
2675         case MODE_V2DF:
2676           return "movapd\t{%1, %0|%0, %1}";
2677         case MODE_TI:
2678           return "movdqa\t{%1, %0|%0, %1}";
2679         case MODE_DI:
2680           return "movq\t{%1, %0|%0, %1}";
2681         case MODE_DF:
2682           return "movsd\t{%1, %0|%0, %1}";
2683         case MODE_V1DF:
2684           return "movlpd\t{%1, %0|%0, %1}";
2685         case MODE_V2SF:
2686           return "movlps\t{%1, %0|%0, %1}";
2687         default:
2688           gcc_unreachable ();
2689         }
2690
2691     case 9:
2692     case 10:
2693       return "movd\t{%1, %0|%0, %1}";
2694
2695     default:
2696       gcc_unreachable();
2697     }
2698 }
2699   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2700    (set (attr "mode")
2701         (cond [(eq_attr "alternative" "0,1,2")
2702                  (const_string "DF")
2703                (eq_attr "alternative" "3,4,9,10")
2704                  (const_string "DI")
2705
2706                /* For SSE1, we have many fewer alternatives.  */
2707                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2708                  (cond [(eq_attr "alternative" "5,6")
2709                           (const_string "V4SF")
2710                        ]
2711                    (const_string "V2SF"))
2712
2713                /* xorps is one byte shorter.  */
2714                (eq_attr "alternative" "5")
2715                  (cond [(ne (symbol_ref "optimize_size")
2716                             (const_int 0))
2717                           (const_string "V4SF")
2718                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2719                             (const_int 0))
2720                           (const_string "TI")
2721                        ]
2722                        (const_string "V2DF"))
2723
2724                /* For architectures resolving dependencies on
2725                   whole SSE registers use APD move to break dependency
2726                   chains, otherwise use short move to avoid extra work.
2727
2728                   movaps encodes one byte shorter.  */
2729                (eq_attr "alternative" "6")
2730                  (cond
2731                    [(ne (symbol_ref "optimize_size")
2732                         (const_int 0))
2733                       (const_string "V4SF")
2734                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2735                         (const_int 0))
2736                       (const_string "V2DF")
2737                    ]
2738                    (const_string "DF"))
2739                /* For architectures resolving dependencies on register
2740                   parts we may avoid extra work to zero out upper part
2741                   of register.  */
2742                (eq_attr "alternative" "7")
2743                  (if_then_else
2744                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2745                        (const_int 0))
2746                    (const_string "V1DF")
2747                    (const_string "DF"))
2748               ]
2749               (const_string "DF")))])
2750
2751 (define_insn "*movdf_integer"
2752   [(set (match_operand:DF 0 "nonimmediate_operand"
2753                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
2754         (match_operand:DF 1 "general_operand"
2755                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
2756   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2757    && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2758    && (reload_in_progress || reload_completed
2759        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2760        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2761            && standard_80387_constant_p (operands[1]))
2762        || GET_CODE (operands[1]) != CONST_DOUBLE
2763        || memory_operand (operands[0], DFmode))"
2764 {
2765   switch (which_alternative)
2766     {
2767     case 0:
2768     case 1:
2769       return output_387_reg_move (insn, operands);
2770
2771     case 2:
2772       return standard_80387_constant_opcode (operands[1]);
2773
2774     case 3:
2775     case 4:
2776       return "#";
2777
2778     case 5:
2779       switch (get_attr_mode (insn))
2780         {
2781         case MODE_V4SF:
2782           return "xorps\t%0, %0";
2783         case MODE_V2DF:
2784           return "xorpd\t%0, %0";
2785         case MODE_TI:
2786           return "pxor\t%0, %0";
2787         default:
2788           gcc_unreachable ();
2789         }
2790     case 6:
2791     case 7:
2792     case 8:
2793       switch (get_attr_mode (insn))
2794         {
2795         case MODE_V4SF:
2796           return "movaps\t{%1, %0|%0, %1}";
2797         case MODE_V2DF:
2798           return "movapd\t{%1, %0|%0, %1}";
2799         case MODE_TI:
2800           return "movdqa\t{%1, %0|%0, %1}";
2801         case MODE_DI:
2802           return "movq\t{%1, %0|%0, %1}";
2803         case MODE_DF:
2804           return "movsd\t{%1, %0|%0, %1}";
2805         case MODE_V1DF:
2806           return "movlpd\t{%1, %0|%0, %1}";
2807         case MODE_V2SF:
2808           return "movlps\t{%1, %0|%0, %1}";
2809         default:
2810           gcc_unreachable ();
2811         }
2812
2813     default:
2814       gcc_unreachable();
2815     }
2816 }
2817   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2818    (set (attr "mode")
2819         (cond [(eq_attr "alternative" "0,1,2")
2820                  (const_string "DF")
2821                (eq_attr "alternative" "3,4")
2822                  (const_string "SI")
2823
2824                /* For SSE1, we have many fewer alternatives.  */
2825                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2826                  (cond [(eq_attr "alternative" "5,6")
2827                           (const_string "V4SF")
2828                        ]
2829                    (const_string "V2SF"))
2830
2831                /* xorps is one byte shorter.  */
2832                (eq_attr "alternative" "5")
2833                  (cond [(ne (symbol_ref "optimize_size")
2834                             (const_int 0))
2835                           (const_string "V4SF")
2836                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2837                             (const_int 0))
2838                           (const_string "TI")
2839                        ]
2840                        (const_string "V2DF"))
2841
2842                /* For architectures resolving dependencies on
2843                   whole SSE registers use APD move to break dependency
2844                   chains, otherwise use short move to avoid extra work.
2845
2846                   movaps encodes one byte shorter.  */
2847                (eq_attr "alternative" "6")
2848                  (cond
2849                    [(ne (symbol_ref "optimize_size")
2850                         (const_int 0))
2851                       (const_string "V4SF")
2852                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2853                         (const_int 0))
2854                       (const_string "V2DF")
2855                    ]
2856                    (const_string "DF"))
2857                /* For architectures resolving dependencies on register
2858                   parts we may avoid extra work to zero out upper part
2859                   of register.  */
2860                (eq_attr "alternative" "7")
2861                  (if_then_else
2862                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2863                        (const_int 0))
2864                    (const_string "V1DF")
2865                    (const_string "DF"))
2866               ]
2867               (const_string "DF")))])
2868
2869 (define_split
2870   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2871         (match_operand:DF 1 "general_operand" ""))]
2872   "reload_completed
2873    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2874    && ! (ANY_FP_REG_P (operands[0]) ||
2875          (GET_CODE (operands[0]) == SUBREG
2876           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2877    && ! (ANY_FP_REG_P (operands[1]) ||
2878          (GET_CODE (operands[1]) == SUBREG
2879           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2880   [(const_int 0)]
2881   "ix86_split_long_move (operands); DONE;")
2882
2883 (define_insn "*swapdf"
2884   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2885         (match_operand:DF 1 "fp_register_operand" "+f"))
2886    (set (match_dup 1)
2887         (match_dup 0))]
2888   "reload_completed || TARGET_80387"
2889 {
2890   if (STACK_TOP_P (operands[0]))
2891     return "fxch\t%1";
2892   else
2893     return "fxch\t%0";
2894 }
2895   [(set_attr "type" "fxch")
2896    (set_attr "mode" "DF")])
2897
2898 (define_expand "movxf"
2899   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2900         (match_operand:XF 1 "general_operand" ""))]
2901   ""
2902   "ix86_expand_move (XFmode, operands); DONE;")
2903
2904 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2905 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2906 ;; Pushing using integer instructions is longer except for constants
2907 ;; and direct memory references.
2908 ;; (assuming that any given constant is pushed only once, but this ought to be
2909 ;;  handled elsewhere).
2910
2911 (define_insn "*pushxf_nointeger"
2912   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2913         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2914   "optimize_size"
2915 {
2916   /* This insn should be already split before reg-stack.  */
2917   gcc_unreachable ();
2918 }
2919   [(set_attr "type" "multi")
2920    (set_attr "unit" "i387,*,*")
2921    (set_attr "mode" "XF,SI,SI")])
2922
2923 (define_insn "*pushxf_integer"
2924   [(set (match_operand:XF 0 "push_operand" "=<,<")
2925         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2926   "!optimize_size"
2927 {
2928   /* This insn should be already split before reg-stack.  */
2929   gcc_unreachable ();
2930 }
2931   [(set_attr "type" "multi")
2932    (set_attr "unit" "i387,*")
2933    (set_attr "mode" "XF,SI")])
2934
2935 (define_split
2936   [(set (match_operand 0 "push_operand" "")
2937         (match_operand 1 "general_operand" ""))]
2938   "reload_completed
2939    && (GET_MODE (operands[0]) == XFmode
2940        || GET_MODE (operands[0]) == DFmode)
2941    && !ANY_FP_REG_P (operands[1])"
2942   [(const_int 0)]
2943   "ix86_split_long_move (operands); DONE;")
2944
2945 (define_split
2946   [(set (match_operand:XF 0 "push_operand" "")
2947         (match_operand:XF 1 "any_fp_register_operand" ""))]
2948   "!TARGET_64BIT"
2949   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2950    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2951   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2952
2953 (define_split
2954   [(set (match_operand:XF 0 "push_operand" "")
2955         (match_operand:XF 1 "any_fp_register_operand" ""))]
2956   "TARGET_64BIT"
2957   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2958    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2959   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2960
2961 ;; Do not use integer registers when optimizing for size
2962 (define_insn "*movxf_nointeger"
2963   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2964         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2965   "optimize_size
2966    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2967    && (reload_in_progress || reload_completed
2968        || (optimize_size && standard_80387_constant_p (operands[1]))
2969        || GET_CODE (operands[1]) != CONST_DOUBLE
2970        || memory_operand (operands[0], XFmode))"
2971 {
2972   switch (which_alternative)
2973     {
2974     case 0:
2975     case 1:
2976       return output_387_reg_move (insn, operands);
2977
2978     case 2:
2979       return standard_80387_constant_opcode (operands[1]);
2980
2981     case 3: case 4:
2982       return "#";
2983     default:
2984       gcc_unreachable ();
2985     }
2986 }
2987   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2988    (set_attr "mode" "XF,XF,XF,SI,SI")])
2989
2990 (define_insn "*movxf_integer"
2991   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2992         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2993   "!optimize_size
2994    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2995    && (reload_in_progress || reload_completed
2996        || (optimize_size && standard_80387_constant_p (operands[1]))
2997        || GET_CODE (operands[1]) != CONST_DOUBLE
2998        || memory_operand (operands[0], XFmode))"
2999 {
3000   switch (which_alternative)
3001     {
3002     case 0:
3003     case 1:
3004       return output_387_reg_move (insn, operands);
3005
3006     case 2:
3007       return standard_80387_constant_opcode (operands[1]);
3008
3009     case 3: case 4:
3010       return "#";
3011
3012     default:
3013       gcc_unreachable ();
3014     }
3015 }
3016   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3017    (set_attr "mode" "XF,XF,XF,SI,SI")])
3018
3019 (define_split
3020   [(set (match_operand 0 "nonimmediate_operand" "")
3021         (match_operand 1 "general_operand" ""))]
3022   "reload_completed
3023    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3024    && GET_MODE (operands[0]) == XFmode
3025    && ! (ANY_FP_REG_P (operands[0]) ||
3026          (GET_CODE (operands[0]) == SUBREG
3027           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3028    && ! (ANY_FP_REG_P (operands[1]) ||
3029          (GET_CODE (operands[1]) == SUBREG
3030           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3031   [(const_int 0)]
3032   "ix86_split_long_move (operands); DONE;")
3033
3034 (define_split
3035   [(set (match_operand 0 "register_operand" "")
3036         (match_operand 1 "memory_operand" ""))]
3037   "reload_completed
3038    && MEM_P (operands[1])
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,*Y2")
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,*Y2")
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,Y2")
3910         (float_truncate:SF
3911           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Y2m")))
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,?fY2*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 "Y2")
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 "copysignsf3"
9656   [(match_operand:SF 0 "register_operand" "")
9657    (match_operand:SF 1 "nonmemory_operand" "")
9658    (match_operand:SF 2 "register_operand" "")]
9659   "TARGET_SSE_MATH"
9660 {
9661   ix86_expand_copysign (operands);
9662   DONE;
9663 })
9664
9665 (define_insn_and_split "copysignsf3_const"
9666   [(set (match_operand:SF 0 "register_operand"          "=x")
9667         (unspec:SF
9668           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9669            (match_operand:SF 2 "register_operand"       "0")
9670            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9671           UNSPEC_COPYSIGN))]
9672   "TARGET_SSE_MATH"
9673   "#"
9674   "&& reload_completed"
9675   [(const_int 0)]
9676 {
9677   ix86_split_copysign_const (operands);
9678   DONE;
9679 })
9680
9681 (define_insn "copysignsf3_var"
9682   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9683         (unspec:SF
9684           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9685            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9686            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9687            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9688           UNSPEC_COPYSIGN))
9689    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9690   "TARGET_SSE_MATH"
9691   "#")
9692
9693 (define_split
9694   [(set (match_operand:SF 0 "register_operand" "")
9695         (unspec:SF
9696           [(match_operand:SF 2 "register_operand" "")
9697            (match_operand:SF 3 "register_operand" "")
9698            (match_operand:V4SF 4 "" "")
9699            (match_operand:V4SF 5 "" "")]
9700           UNSPEC_COPYSIGN))
9701    (clobber (match_scratch:V4SF 1 ""))]
9702   "TARGET_SSE_MATH && reload_completed"
9703   [(const_int 0)]
9704 {
9705   ix86_split_copysign_var (operands);
9706   DONE;
9707 })
9708
9709 (define_expand "negdf2"
9710   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9711         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9712   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9713   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9714
9715 (define_expand "absdf2"
9716   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9717         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9718   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9719   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9720
9721 (define_insn "*absnegdf2_mixed"
9722   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,f,rm")
9723         (match_operator:DF 3 "absneg_operator"
9724           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
9725    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X,X"))
9726    (clobber (reg:CC FLAGS_REG))]
9727   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9728    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9729   "#")
9730
9731 (define_insn "*absnegdf2_sse"
9732   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,rm")
9733         (match_operator:DF 3 "absneg_operator"
9734           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
9735    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X "))
9736    (clobber (reg:CC FLAGS_REG))]
9737   "TARGET_SSE2 && TARGET_SSE_MATH
9738    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9739   "#")
9740
9741 (define_insn "*absnegdf2_i387"
9742   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9743         (match_operator:DF 3 "absneg_operator"
9744           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9745    (use (match_operand 2 "" ""))
9746    (clobber (reg:CC FLAGS_REG))]
9747   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9748    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9749   "#")
9750
9751 (define_expand "copysigndf3"
9752   [(match_operand:DF 0 "register_operand" "")
9753    (match_operand:DF 1 "nonmemory_operand" "")
9754    (match_operand:DF 2 "register_operand" "")]
9755   "TARGET_SSE2 && TARGET_SSE_MATH"
9756 {
9757   ix86_expand_copysign (operands);
9758   DONE;
9759 })
9760
9761 (define_insn_and_split "copysigndf3_const"
9762   [(set (match_operand:DF 0 "register_operand"          "=x")
9763         (unspec:DF
9764           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9765            (match_operand:DF 2 "register_operand"       "0")
9766            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9767           UNSPEC_COPYSIGN))]
9768   "TARGET_SSE2 && TARGET_SSE_MATH"
9769   "#"
9770   "&& reload_completed"
9771   [(const_int 0)]
9772 {
9773   ix86_split_copysign_const (operands);
9774   DONE;
9775 })
9776
9777 (define_insn "copysigndf3_var"
9778   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9779         (unspec:DF
9780           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9781            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9782            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9783            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9784           UNSPEC_COPYSIGN))
9785    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9786   "TARGET_SSE2 && TARGET_SSE_MATH"
9787   "#")
9788
9789 (define_split
9790   [(set (match_operand:DF 0 "register_operand" "")
9791         (unspec:DF
9792           [(match_operand:DF 2 "register_operand" "")
9793            (match_operand:DF 3 "register_operand" "")
9794            (match_operand:V2DF 4 "" "")
9795            (match_operand:V2DF 5 "" "")]
9796           UNSPEC_COPYSIGN))
9797    (clobber (match_scratch:V2DF 1 ""))]
9798   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9799   [(const_int 0)]
9800 {
9801   ix86_split_copysign_var (operands);
9802   DONE;
9803 })
9804
9805 (define_expand "negxf2"
9806   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9807         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9808   "TARGET_80387"
9809   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9810
9811 (define_expand "absxf2"
9812   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9813         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9814   "TARGET_80387"
9815   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9816
9817 (define_insn "*absnegxf2_i387"
9818   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9819         (match_operator:XF 3 "absneg_operator"
9820           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9821    (use (match_operand 2 "" ""))
9822    (clobber (reg:CC FLAGS_REG))]
9823   "TARGET_80387
9824    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9825   "#")
9826
9827 ;; Splitters for fp abs and neg.
9828
9829 (define_split
9830   [(set (match_operand 0 "fp_register_operand" "")
9831         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9832    (use (match_operand 2 "" ""))
9833    (clobber (reg:CC FLAGS_REG))]
9834   "reload_completed"
9835   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9836
9837 (define_split
9838   [(set (match_operand 0 "register_operand" "")
9839         (match_operator 3 "absneg_operator"
9840           [(match_operand 1 "register_operand" "")]))
9841    (use (match_operand 2 "nonimmediate_operand" ""))
9842    (clobber (reg:CC FLAGS_REG))]
9843   "reload_completed && SSE_REG_P (operands[0])"
9844   [(set (match_dup 0) (match_dup 3))]
9845 {
9846   enum machine_mode mode = GET_MODE (operands[0]);
9847   enum machine_mode vmode = GET_MODE (operands[2]);
9848   rtx tmp;
9849
9850   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9851   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9852   if (operands_match_p (operands[0], operands[2]))
9853     {
9854       tmp = operands[1];
9855       operands[1] = operands[2];
9856       operands[2] = tmp;
9857     }
9858   if (GET_CODE (operands[3]) == ABS)
9859     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9860   else
9861     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9862   operands[3] = tmp;
9863 })
9864
9865 (define_split
9866   [(set (match_operand:SF 0 "register_operand" "")
9867         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9868    (use (match_operand:V4SF 2 "" ""))
9869    (clobber (reg:CC FLAGS_REG))]
9870   "reload_completed"
9871   [(parallel [(set (match_dup 0) (match_dup 1))
9872               (clobber (reg:CC FLAGS_REG))])]
9873 {
9874   rtx tmp;
9875   operands[0] = gen_lowpart (SImode, operands[0]);
9876   if (GET_CODE (operands[1]) == ABS)
9877     {
9878       tmp = gen_int_mode (0x7fffffff, SImode);
9879       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9880     }
9881   else
9882     {
9883       tmp = gen_int_mode (0x80000000, SImode);
9884       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9885     }
9886   operands[1] = tmp;
9887 })
9888
9889 (define_split
9890   [(set (match_operand:DF 0 "register_operand" "")
9891         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9892    (use (match_operand 2 "" ""))
9893    (clobber (reg:CC FLAGS_REG))]
9894   "reload_completed"
9895   [(parallel [(set (match_dup 0) (match_dup 1))
9896               (clobber (reg:CC FLAGS_REG))])]
9897 {
9898   rtx tmp;
9899   if (TARGET_64BIT)
9900     {
9901       tmp = gen_lowpart (DImode, operands[0]);
9902       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9903       operands[0] = tmp;
9904
9905       if (GET_CODE (operands[1]) == ABS)
9906         tmp = const0_rtx;
9907       else
9908         tmp = gen_rtx_NOT (DImode, tmp);
9909     }
9910   else
9911     {
9912       operands[0] = gen_highpart (SImode, operands[0]);
9913       if (GET_CODE (operands[1]) == ABS)
9914         {
9915           tmp = gen_int_mode (0x7fffffff, SImode);
9916           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9917         }
9918       else
9919         {
9920           tmp = gen_int_mode (0x80000000, SImode);
9921           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9922         }
9923     }
9924   operands[1] = tmp;
9925 })
9926
9927 (define_split
9928   [(set (match_operand:XF 0 "register_operand" "")
9929         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9930    (use (match_operand 2 "" ""))
9931    (clobber (reg:CC FLAGS_REG))]
9932   "reload_completed"
9933   [(parallel [(set (match_dup 0) (match_dup 1))
9934               (clobber (reg:CC FLAGS_REG))])]
9935 {
9936   rtx tmp;
9937   operands[0] = gen_rtx_REG (SImode,
9938                              true_regnum (operands[0])
9939                              + (TARGET_64BIT ? 1 : 2));
9940   if (GET_CODE (operands[1]) == ABS)
9941     {
9942       tmp = GEN_INT (0x7fff);
9943       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9944     }
9945   else
9946     {
9947       tmp = GEN_INT (0x8000);
9948       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9949     }
9950   operands[1] = tmp;
9951 })
9952
9953 (define_split
9954   [(set (match_operand 0 "memory_operand" "")
9955         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9956    (use (match_operand 2 "" ""))
9957    (clobber (reg:CC FLAGS_REG))]
9958   "reload_completed"
9959   [(parallel [(set (match_dup 0) (match_dup 1))
9960               (clobber (reg:CC FLAGS_REG))])]
9961 {
9962   enum machine_mode mode = GET_MODE (operands[0]);
9963   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9964   rtx tmp;
9965
9966   operands[0] = adjust_address (operands[0], QImode, size - 1);
9967   if (GET_CODE (operands[1]) == ABS)
9968     {
9969       tmp = gen_int_mode (0x7f, QImode);
9970       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9971     }
9972   else
9973     {
9974       tmp = gen_int_mode (0x80, QImode);
9975       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9976     }
9977   operands[1] = tmp;
9978 })
9979
9980 ;; Conditionalize these after reload. If they match before reload, we
9981 ;; lose the clobber and ability to use integer instructions.
9982
9983 (define_insn "*negsf2_1"
9984   [(set (match_operand:SF 0 "register_operand" "=f")
9985         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9986   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9987   "fchs"
9988   [(set_attr "type" "fsgn")
9989    (set_attr "mode" "SF")])
9990
9991 (define_insn "*negdf2_1"
9992   [(set (match_operand:DF 0 "register_operand" "=f")
9993         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9994   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9995   "fchs"
9996   [(set_attr "type" "fsgn")
9997    (set_attr "mode" "DF")])
9998
9999 (define_insn "*negxf2_1"
10000   [(set (match_operand:XF 0 "register_operand" "=f")
10001         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10002   "TARGET_80387"
10003   "fchs"
10004   [(set_attr "type" "fsgn")
10005    (set_attr "mode" "XF")])
10006
10007 (define_insn "*abssf2_1"
10008   [(set (match_operand:SF 0 "register_operand" "=f")
10009         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10010   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10011   "fabs"
10012   [(set_attr "type" "fsgn")
10013    (set_attr "mode" "SF")])
10014
10015 (define_insn "*absdf2_1"
10016   [(set (match_operand:DF 0 "register_operand" "=f")
10017         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10018   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10019   "fabs"
10020   [(set_attr "type" "fsgn")
10021    (set_attr "mode" "DF")])
10022
10023 (define_insn "*absxf2_1"
10024   [(set (match_operand:XF 0 "register_operand" "=f")
10025         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10026   "TARGET_80387"
10027   "fabs"
10028   [(set_attr "type" "fsgn")
10029    (set_attr "mode" "DF")])
10030
10031 (define_insn "*negextendsfdf2"
10032   [(set (match_operand:DF 0 "register_operand" "=f")
10033         (neg:DF (float_extend:DF
10034                   (match_operand:SF 1 "register_operand" "0"))))]
10035   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10036   "fchs"
10037   [(set_attr "type" "fsgn")
10038    (set_attr "mode" "DF")])
10039
10040 (define_insn "*negextenddfxf2"
10041   [(set (match_operand:XF 0 "register_operand" "=f")
10042         (neg:XF (float_extend:XF
10043                   (match_operand:DF 1 "register_operand" "0"))))]
10044   "TARGET_80387"
10045   "fchs"
10046   [(set_attr "type" "fsgn")
10047    (set_attr "mode" "XF")])
10048
10049 (define_insn "*negextendsfxf2"
10050   [(set (match_operand:XF 0 "register_operand" "=f")
10051         (neg:XF (float_extend:XF
10052                   (match_operand:SF 1 "register_operand" "0"))))]
10053   "TARGET_80387"
10054   "fchs"
10055   [(set_attr "type" "fsgn")
10056    (set_attr "mode" "XF")])
10057
10058 (define_insn "*absextendsfdf2"
10059   [(set (match_operand:DF 0 "register_operand" "=f")
10060         (abs:DF (float_extend:DF
10061                   (match_operand:SF 1 "register_operand" "0"))))]
10062   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10063   "fabs"
10064   [(set_attr "type" "fsgn")
10065    (set_attr "mode" "DF")])
10066
10067 (define_insn "*absextenddfxf2"
10068   [(set (match_operand:XF 0 "register_operand" "=f")
10069         (abs:XF (float_extend:XF
10070           (match_operand:DF 1 "register_operand" "0"))))]
10071   "TARGET_80387"
10072   "fabs"
10073   [(set_attr "type" "fsgn")
10074    (set_attr "mode" "XF")])
10075
10076 (define_insn "*absextendsfxf2"
10077   [(set (match_operand:XF 0 "register_operand" "=f")
10078         (abs:XF (float_extend:XF
10079           (match_operand:SF 1 "register_operand" "0"))))]
10080   "TARGET_80387"
10081   "fabs"
10082   [(set_attr "type" "fsgn")
10083    (set_attr "mode" "XF")])
10084 \f
10085 ;; One complement instructions
10086
10087 (define_expand "one_cmpldi2"
10088   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10089         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10090   "TARGET_64BIT"
10091   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10092
10093 (define_insn "*one_cmpldi2_1_rex64"
10094   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10095         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10096   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10097   "not{q}\t%0"
10098   [(set_attr "type" "negnot")
10099    (set_attr "mode" "DI")])
10100
10101 (define_insn "*one_cmpldi2_2_rex64"
10102   [(set (reg FLAGS_REG)
10103         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10104                  (const_int 0)))
10105    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10106         (not:DI (match_dup 1)))]
10107   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10108    && ix86_unary_operator_ok (NOT, DImode, operands)"
10109   "#"
10110   [(set_attr "type" "alu1")
10111    (set_attr "mode" "DI")])
10112
10113 (define_split
10114   [(set (match_operand 0 "flags_reg_operand" "")
10115         (match_operator 2 "compare_operator"
10116           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10117            (const_int 0)]))
10118    (set (match_operand:DI 1 "nonimmediate_operand" "")
10119         (not:DI (match_dup 3)))]
10120   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10121   [(parallel [(set (match_dup 0)
10122                    (match_op_dup 2
10123                      [(xor:DI (match_dup 3) (const_int -1))
10124                       (const_int 0)]))
10125               (set (match_dup 1)
10126                    (xor:DI (match_dup 3) (const_int -1)))])]
10127   "")
10128
10129 (define_expand "one_cmplsi2"
10130   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10131         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10132   ""
10133   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10134
10135 (define_insn "*one_cmplsi2_1"
10136   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10137         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10138   "ix86_unary_operator_ok (NOT, SImode, operands)"
10139   "not{l}\t%0"
10140   [(set_attr "type" "negnot")
10141    (set_attr "mode" "SI")])
10142
10143 ;; ??? Currently never generated - xor is used instead.
10144 (define_insn "*one_cmplsi2_1_zext"
10145   [(set (match_operand:DI 0 "register_operand" "=r")
10146         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10147   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10148   "not{l}\t%k0"
10149   [(set_attr "type" "negnot")
10150    (set_attr "mode" "SI")])
10151
10152 (define_insn "*one_cmplsi2_2"
10153   [(set (reg FLAGS_REG)
10154         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10155                  (const_int 0)))
10156    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10157         (not:SI (match_dup 1)))]
10158   "ix86_match_ccmode (insn, CCNOmode)
10159    && ix86_unary_operator_ok (NOT, SImode, operands)"
10160   "#"
10161   [(set_attr "type" "alu1")
10162    (set_attr "mode" "SI")])
10163
10164 (define_split
10165   [(set (match_operand 0 "flags_reg_operand" "")
10166         (match_operator 2 "compare_operator"
10167           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10168            (const_int 0)]))
10169    (set (match_operand:SI 1 "nonimmediate_operand" "")
10170         (not:SI (match_dup 3)))]
10171   "ix86_match_ccmode (insn, CCNOmode)"
10172   [(parallel [(set (match_dup 0)
10173                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10174                                     (const_int 0)]))
10175               (set (match_dup 1)
10176                    (xor:SI (match_dup 3) (const_int -1)))])]
10177   "")
10178
10179 ;; ??? Currently never generated - xor is used instead.
10180 (define_insn "*one_cmplsi2_2_zext"
10181   [(set (reg FLAGS_REG)
10182         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10183                  (const_int 0)))
10184    (set (match_operand:DI 0 "register_operand" "=r")
10185         (zero_extend:DI (not:SI (match_dup 1))))]
10186   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10187    && ix86_unary_operator_ok (NOT, SImode, operands)"
10188   "#"
10189   [(set_attr "type" "alu1")
10190    (set_attr "mode" "SI")])
10191
10192 (define_split
10193   [(set (match_operand 0 "flags_reg_operand" "")
10194         (match_operator 2 "compare_operator"
10195           [(not:SI (match_operand:SI 3 "register_operand" ""))
10196            (const_int 0)]))
10197    (set (match_operand:DI 1 "register_operand" "")
10198         (zero_extend:DI (not:SI (match_dup 3))))]
10199   "ix86_match_ccmode (insn, CCNOmode)"
10200   [(parallel [(set (match_dup 0)
10201                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10202                                     (const_int 0)]))
10203               (set (match_dup 1)
10204                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10205   "")
10206
10207 (define_expand "one_cmplhi2"
10208   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10209         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10210   "TARGET_HIMODE_MATH"
10211   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10212
10213 (define_insn "*one_cmplhi2_1"
10214   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10215         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10216   "ix86_unary_operator_ok (NOT, HImode, operands)"
10217   "not{w}\t%0"
10218   [(set_attr "type" "negnot")
10219    (set_attr "mode" "HI")])
10220
10221 (define_insn "*one_cmplhi2_2"
10222   [(set (reg FLAGS_REG)
10223         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10224                  (const_int 0)))
10225    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10226         (not:HI (match_dup 1)))]
10227   "ix86_match_ccmode (insn, CCNOmode)
10228    && ix86_unary_operator_ok (NEG, HImode, operands)"
10229   "#"
10230   [(set_attr "type" "alu1")
10231    (set_attr "mode" "HI")])
10232
10233 (define_split
10234   [(set (match_operand 0 "flags_reg_operand" "")
10235         (match_operator 2 "compare_operator"
10236           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10237            (const_int 0)]))
10238    (set (match_operand:HI 1 "nonimmediate_operand" "")
10239         (not:HI (match_dup 3)))]
10240   "ix86_match_ccmode (insn, CCNOmode)"
10241   [(parallel [(set (match_dup 0)
10242                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10243                                     (const_int 0)]))
10244               (set (match_dup 1)
10245                    (xor:HI (match_dup 3) (const_int -1)))])]
10246   "")
10247
10248 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10249 (define_expand "one_cmplqi2"
10250   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10251         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10252   "TARGET_QIMODE_MATH"
10253   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10254
10255 (define_insn "*one_cmplqi2_1"
10256   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10257         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10258   "ix86_unary_operator_ok (NOT, QImode, operands)"
10259   "@
10260    not{b}\t%0
10261    not{l}\t%k0"
10262   [(set_attr "type" "negnot")
10263    (set_attr "mode" "QI,SI")])
10264
10265 (define_insn "*one_cmplqi2_2"
10266   [(set (reg FLAGS_REG)
10267         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10268                  (const_int 0)))
10269    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10270         (not:QI (match_dup 1)))]
10271   "ix86_match_ccmode (insn, CCNOmode)
10272    && ix86_unary_operator_ok (NOT, QImode, operands)"
10273   "#"
10274   [(set_attr "type" "alu1")
10275    (set_attr "mode" "QI")])
10276
10277 (define_split
10278   [(set (match_operand 0 "flags_reg_operand" "")
10279         (match_operator 2 "compare_operator"
10280           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10281            (const_int 0)]))
10282    (set (match_operand:QI 1 "nonimmediate_operand" "")
10283         (not:QI (match_dup 3)))]
10284   "ix86_match_ccmode (insn, CCNOmode)"
10285   [(parallel [(set (match_dup 0)
10286                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10287                                     (const_int 0)]))
10288               (set (match_dup 1)
10289                    (xor:QI (match_dup 3) (const_int -1)))])]
10290   "")
10291 \f
10292 ;; Arithmetic shift instructions
10293
10294 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10295 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10296 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10297 ;; from the assembler input.
10298 ;;
10299 ;; This instruction shifts the target reg/mem as usual, but instead of
10300 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10301 ;; is a left shift double, bits are taken from the high order bits of
10302 ;; reg, else if the insn is a shift right double, bits are taken from the
10303 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10304 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10305 ;;
10306 ;; Since sh[lr]d does not change the `reg' operand, that is done
10307 ;; separately, making all shifts emit pairs of shift double and normal
10308 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10309 ;; support a 63 bit shift, each shift where the count is in a reg expands
10310 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10311 ;;
10312 ;; If the shift count is a constant, we need never emit more than one
10313 ;; shift pair, instead using moves and sign extension for counts greater
10314 ;; than 31.
10315
10316 (define_expand "ashlti3"
10317   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10318                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10319                               (match_operand:QI 2 "nonmemory_operand" "")))
10320               (clobber (reg:CC FLAGS_REG))])]
10321   "TARGET_64BIT"
10322 {
10323   if (! immediate_operand (operands[2], QImode))
10324     {
10325       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10326       DONE;
10327     }
10328   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10329   DONE;
10330 })
10331
10332 (define_insn "ashlti3_1"
10333   [(set (match_operand:TI 0 "register_operand" "=r")
10334         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10335                    (match_operand:QI 2 "register_operand" "c")))
10336    (clobber (match_scratch:DI 3 "=&r"))
10337    (clobber (reg:CC FLAGS_REG))]
10338   "TARGET_64BIT"
10339   "#"
10340   [(set_attr "type" "multi")])
10341
10342 (define_insn "*ashlti3_2"
10343   [(set (match_operand:TI 0 "register_operand" "=r")
10344         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10345                    (match_operand:QI 2 "immediate_operand" "O")))
10346    (clobber (reg:CC FLAGS_REG))]
10347   "TARGET_64BIT"
10348   "#"
10349   [(set_attr "type" "multi")])
10350
10351 (define_split
10352   [(set (match_operand:TI 0 "register_operand" "")
10353         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10354                    (match_operand:QI 2 "register_operand" "")))
10355    (clobber (match_scratch:DI 3 ""))
10356    (clobber (reg:CC FLAGS_REG))]
10357   "TARGET_64BIT && reload_completed"
10358   [(const_int 0)]
10359   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10360
10361 (define_split
10362   [(set (match_operand:TI 0 "register_operand" "")
10363         (ashift:TI (match_operand:TI 1 "register_operand" "")
10364                    (match_operand:QI 2 "immediate_operand" "")))
10365    (clobber (reg:CC FLAGS_REG))]
10366   "TARGET_64BIT && reload_completed"
10367   [(const_int 0)]
10368   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10369
10370 (define_insn "x86_64_shld"
10371   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10372         (ior:DI (ashift:DI (match_dup 0)
10373                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10374                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10375                   (minus:QI (const_int 64) (match_dup 2)))))
10376    (clobber (reg:CC FLAGS_REG))]
10377   "TARGET_64BIT"
10378   "@
10379    shld{q}\t{%2, %1, %0|%0, %1, %2}
10380    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10381   [(set_attr "type" "ishift")
10382    (set_attr "prefix_0f" "1")
10383    (set_attr "mode" "DI")
10384    (set_attr "athlon_decode" "vector")
10385    (set_attr "amdfam10_decode" "vector")])   
10386
10387 (define_expand "x86_64_shift_adj"
10388   [(set (reg:CCZ FLAGS_REG)
10389         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10390                              (const_int 64))
10391                      (const_int 0)))
10392    (set (match_operand:DI 0 "register_operand" "")
10393         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10394                          (match_operand:DI 1 "register_operand" "")
10395                          (match_dup 0)))
10396    (set (match_dup 1)
10397         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10398                          (match_operand:DI 3 "register_operand" "r")
10399                          (match_dup 1)))]
10400   "TARGET_64BIT"
10401   "")
10402
10403 (define_expand "ashldi3"
10404   [(set (match_operand:DI 0 "shiftdi_operand" "")
10405         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10406                    (match_operand:QI 2 "nonmemory_operand" "")))]
10407   ""
10408   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10409
10410 (define_insn "*ashldi3_1_rex64"
10411   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10412         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10413                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10414    (clobber (reg:CC FLAGS_REG))]
10415   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10416 {
10417   switch (get_attr_type (insn))
10418     {
10419     case TYPE_ALU:
10420       gcc_assert (operands[2] == const1_rtx);
10421       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10422       return "add{q}\t%0, %0";
10423
10424     case TYPE_LEA:
10425       gcc_assert (CONST_INT_P (operands[2]));
10426       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10427       operands[1] = gen_rtx_MULT (DImode, operands[1],
10428                                   GEN_INT (1 << INTVAL (operands[2])));
10429       return "lea{q}\t{%a1, %0|%0, %a1}";
10430
10431     default:
10432       if (REG_P (operands[2]))
10433         return "sal{q}\t{%b2, %0|%0, %b2}";
10434       else if (operands[2] == const1_rtx
10435                && (TARGET_SHIFT1 || optimize_size))
10436         return "sal{q}\t%0";
10437       else
10438         return "sal{q}\t{%2, %0|%0, %2}";
10439     }
10440 }
10441   [(set (attr "type")
10442      (cond [(eq_attr "alternative" "1")
10443               (const_string "lea")
10444             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10445                           (const_int 0))
10446                       (match_operand 0 "register_operand" ""))
10447                  (match_operand 2 "const1_operand" ""))
10448               (const_string "alu")
10449            ]
10450            (const_string "ishift")))
10451    (set_attr "mode" "DI")])
10452
10453 ;; Convert lea to the lea pattern to avoid flags dependency.
10454 (define_split
10455   [(set (match_operand:DI 0 "register_operand" "")
10456         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10457                    (match_operand:QI 2 "immediate_operand" "")))
10458    (clobber (reg:CC FLAGS_REG))]
10459   "TARGET_64BIT && reload_completed
10460    && true_regnum (operands[0]) != true_regnum (operands[1])"
10461   [(set (match_dup 0)
10462         (mult:DI (match_dup 1)
10463                  (match_dup 2)))]
10464   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10465
10466 ;; This pattern can't accept a variable shift count, since shifts by
10467 ;; zero don't affect the flags.  We assume that shifts by constant
10468 ;; zero are optimized away.
10469 (define_insn "*ashldi3_cmp_rex64"
10470   [(set (reg FLAGS_REG)
10471         (compare
10472           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10473                      (match_operand:QI 2 "immediate_operand" "e"))
10474           (const_int 0)))
10475    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10476         (ashift:DI (match_dup 1) (match_dup 2)))]
10477   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10478    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10479    && (optimize_size
10480        || !TARGET_PARTIAL_FLAG_REG_STALL
10481        || (operands[2] == const1_rtx
10482            && (TARGET_SHIFT1
10483                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10484 {
10485   switch (get_attr_type (insn))
10486     {
10487     case TYPE_ALU:
10488       gcc_assert (operands[2] == const1_rtx);
10489       return "add{q}\t%0, %0";
10490
10491     default:
10492       if (REG_P (operands[2]))
10493         return "sal{q}\t{%b2, %0|%0, %b2}";
10494       else if (operands[2] == const1_rtx
10495                && (TARGET_SHIFT1 || optimize_size))
10496         return "sal{q}\t%0";
10497       else
10498         return "sal{q}\t{%2, %0|%0, %2}";
10499     }
10500 }
10501   [(set (attr "type")
10502      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10503                           (const_int 0))
10504                       (match_operand 0 "register_operand" ""))
10505                  (match_operand 2 "const1_operand" ""))
10506               (const_string "alu")
10507            ]
10508            (const_string "ishift")))
10509    (set_attr "mode" "DI")])
10510
10511 (define_insn "*ashldi3_cconly_rex64"
10512   [(set (reg FLAGS_REG)
10513         (compare
10514           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10515                      (match_operand:QI 2 "immediate_operand" "e"))
10516           (const_int 0)))
10517    (clobber (match_scratch:DI 0 "=r"))]
10518   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10519    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10520    && (optimize_size
10521        || !TARGET_PARTIAL_FLAG_REG_STALL
10522        || (operands[2] == const1_rtx
10523            && (TARGET_SHIFT1
10524                || TARGET_DOUBLE_WITH_ADD)))"
10525 {
10526   switch (get_attr_type (insn))
10527     {
10528     case TYPE_ALU:
10529       gcc_assert (operands[2] == const1_rtx);
10530       return "add{q}\t%0, %0";
10531
10532     default:
10533       if (REG_P (operands[2]))
10534         return "sal{q}\t{%b2, %0|%0, %b2}";
10535       else if (operands[2] == const1_rtx
10536                && (TARGET_SHIFT1 || optimize_size))
10537         return "sal{q}\t%0";
10538       else
10539         return "sal{q}\t{%2, %0|%0, %2}";
10540     }
10541 }
10542   [(set (attr "type")
10543      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10544                           (const_int 0))
10545                       (match_operand 0 "register_operand" ""))
10546                  (match_operand 2 "const1_operand" ""))
10547               (const_string "alu")
10548            ]
10549            (const_string "ishift")))
10550    (set_attr "mode" "DI")])
10551
10552 (define_insn "*ashldi3_1"
10553   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10554         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10555                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10556    (clobber (reg:CC FLAGS_REG))]
10557   "!TARGET_64BIT"
10558   "#"
10559   [(set_attr "type" "multi")])
10560
10561 ;; By default we don't ask for a scratch register, because when DImode
10562 ;; values are manipulated, registers are already at a premium.  But if
10563 ;; we have one handy, we won't turn it away.
10564 (define_peephole2
10565   [(match_scratch:SI 3 "r")
10566    (parallel [(set (match_operand:DI 0 "register_operand" "")
10567                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10568                               (match_operand:QI 2 "nonmemory_operand" "")))
10569               (clobber (reg:CC FLAGS_REG))])
10570    (match_dup 3)]
10571   "!TARGET_64BIT && TARGET_CMOVE"
10572   [(const_int 0)]
10573   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10574
10575 (define_split
10576   [(set (match_operand:DI 0 "register_operand" "")
10577         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10578                    (match_operand:QI 2 "nonmemory_operand" "")))
10579    (clobber (reg:CC FLAGS_REG))]
10580   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10581                      ? flow2_completed : reload_completed)"
10582   [(const_int 0)]
10583   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10584
10585 (define_insn "x86_shld_1"
10586   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10587         (ior:SI (ashift:SI (match_dup 0)
10588                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10589                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10590                   (minus:QI (const_int 32) (match_dup 2)))))
10591    (clobber (reg:CC FLAGS_REG))]
10592   ""
10593   "@
10594    shld{l}\t{%2, %1, %0|%0, %1, %2}
10595    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10596   [(set_attr "type" "ishift")
10597    (set_attr "prefix_0f" "1")
10598    (set_attr "mode" "SI")
10599    (set_attr "pent_pair" "np")
10600    (set_attr "athlon_decode" "vector")
10601    (set_attr "amdfam10_decode" "vector")])   
10602
10603 (define_expand "x86_shift_adj_1"
10604   [(set (reg:CCZ FLAGS_REG)
10605         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10606                              (const_int 32))
10607                      (const_int 0)))
10608    (set (match_operand:SI 0 "register_operand" "")
10609         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10610                          (match_operand:SI 1 "register_operand" "")
10611                          (match_dup 0)))
10612    (set (match_dup 1)
10613         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10614                          (match_operand:SI 3 "register_operand" "r")
10615                          (match_dup 1)))]
10616   "TARGET_CMOVE"
10617   "")
10618
10619 (define_expand "x86_shift_adj_2"
10620   [(use (match_operand:SI 0 "register_operand" ""))
10621    (use (match_operand:SI 1 "register_operand" ""))
10622    (use (match_operand:QI 2 "register_operand" ""))]
10623   ""
10624 {
10625   rtx label = gen_label_rtx ();
10626   rtx tmp;
10627
10628   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10629
10630   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10631   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10632   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10633                               gen_rtx_LABEL_REF (VOIDmode, label),
10634                               pc_rtx);
10635   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10636   JUMP_LABEL (tmp) = label;
10637
10638   emit_move_insn (operands[0], operands[1]);
10639   ix86_expand_clear (operands[1]);
10640
10641   emit_label (label);
10642   LABEL_NUSES (label) = 1;
10643
10644   DONE;
10645 })
10646
10647 (define_expand "ashlsi3"
10648   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10649         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10650                    (match_operand:QI 2 "nonmemory_operand" "")))
10651    (clobber (reg:CC FLAGS_REG))]
10652   ""
10653   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10654
10655 (define_insn "*ashlsi3_1"
10656   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10657         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10658                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10659    (clobber (reg:CC FLAGS_REG))]
10660   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10661 {
10662   switch (get_attr_type (insn))
10663     {
10664     case TYPE_ALU:
10665       gcc_assert (operands[2] == const1_rtx);
10666       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10667       return "add{l}\t%0, %0";
10668
10669     case TYPE_LEA:
10670       return "#";
10671
10672     default:
10673       if (REG_P (operands[2]))
10674         return "sal{l}\t{%b2, %0|%0, %b2}";
10675       else if (operands[2] == const1_rtx
10676                && (TARGET_SHIFT1 || optimize_size))
10677         return "sal{l}\t%0";
10678       else
10679         return "sal{l}\t{%2, %0|%0, %2}";
10680     }
10681 }
10682   [(set (attr "type")
10683      (cond [(eq_attr "alternative" "1")
10684               (const_string "lea")
10685             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10686                           (const_int 0))
10687                       (match_operand 0 "register_operand" ""))
10688                  (match_operand 2 "const1_operand" ""))
10689               (const_string "alu")
10690            ]
10691            (const_string "ishift")))
10692    (set_attr "mode" "SI")])
10693
10694 ;; Convert lea to the lea pattern to avoid flags dependency.
10695 (define_split
10696   [(set (match_operand 0 "register_operand" "")
10697         (ashift (match_operand 1 "index_register_operand" "")
10698                 (match_operand:QI 2 "const_int_operand" "")))
10699    (clobber (reg:CC FLAGS_REG))]
10700   "reload_completed
10701    && true_regnum (operands[0]) != true_regnum (operands[1])
10702    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10703   [(const_int 0)]
10704 {
10705   rtx pat;
10706   enum machine_mode mode = GET_MODE (operands[0]);
10707
10708   if (GET_MODE_SIZE (mode) < 4)
10709     operands[0] = gen_lowpart (SImode, operands[0]);
10710   if (mode != Pmode)
10711     operands[1] = gen_lowpart (Pmode, operands[1]);
10712   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10713
10714   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10715   if (Pmode != SImode)
10716     pat = gen_rtx_SUBREG (SImode, pat, 0);
10717   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10718   DONE;
10719 })
10720
10721 ;; Rare case of shifting RSP is handled by generating move and shift
10722 (define_split
10723   [(set (match_operand 0 "register_operand" "")
10724         (ashift (match_operand 1 "register_operand" "")
10725                 (match_operand:QI 2 "const_int_operand" "")))
10726    (clobber (reg:CC FLAGS_REG))]
10727   "reload_completed
10728    && true_regnum (operands[0]) != true_regnum (operands[1])"
10729   [(const_int 0)]
10730 {
10731   rtx pat, clob;
10732   emit_move_insn (operands[0], operands[1]);
10733   pat = gen_rtx_SET (VOIDmode, operands[0],
10734                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10735                                      operands[0], operands[2]));
10736   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10737   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10738   DONE;
10739 })
10740
10741 (define_insn "*ashlsi3_1_zext"
10742   [(set (match_operand:DI 0 "register_operand" "=r,r")
10743         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10744                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10745    (clobber (reg:CC FLAGS_REG))]
10746   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10747 {
10748   switch (get_attr_type (insn))
10749     {
10750     case TYPE_ALU:
10751       gcc_assert (operands[2] == const1_rtx);
10752       return "add{l}\t%k0, %k0";
10753
10754     case TYPE_LEA:
10755       return "#";
10756
10757     default:
10758       if (REG_P (operands[2]))
10759         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10760       else if (operands[2] == const1_rtx
10761                && (TARGET_SHIFT1 || optimize_size))
10762         return "sal{l}\t%k0";
10763       else
10764         return "sal{l}\t{%2, %k0|%k0, %2}";
10765     }
10766 }
10767   [(set (attr "type")
10768      (cond [(eq_attr "alternative" "1")
10769               (const_string "lea")
10770             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10771                      (const_int 0))
10772                  (match_operand 2 "const1_operand" ""))
10773               (const_string "alu")
10774            ]
10775            (const_string "ishift")))
10776    (set_attr "mode" "SI")])
10777
10778 ;; Convert lea to the lea pattern to avoid flags dependency.
10779 (define_split
10780   [(set (match_operand:DI 0 "register_operand" "")
10781         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10782                                 (match_operand:QI 2 "const_int_operand" ""))))
10783    (clobber (reg:CC FLAGS_REG))]
10784   "TARGET_64BIT && reload_completed
10785    && true_regnum (operands[0]) != true_regnum (operands[1])"
10786   [(set (match_dup 0) (zero_extend:DI
10787                         (subreg:SI (mult:SI (match_dup 1)
10788                                             (match_dup 2)) 0)))]
10789 {
10790   operands[1] = gen_lowpart (Pmode, operands[1]);
10791   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10792 })
10793
10794 ;; This pattern can't accept a variable shift count, since shifts by
10795 ;; zero don't affect the flags.  We assume that shifts by constant
10796 ;; zero are optimized away.
10797 (define_insn "*ashlsi3_cmp"
10798   [(set (reg FLAGS_REG)
10799         (compare
10800           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10801                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10802           (const_int 0)))
10803    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10804         (ashift:SI (match_dup 1) (match_dup 2)))]
10805   "ix86_match_ccmode (insn, CCGOCmode)
10806    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10807    && (optimize_size
10808        || !TARGET_PARTIAL_FLAG_REG_STALL
10809        || (operands[2] == const1_rtx
10810            && (TARGET_SHIFT1
10811                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10812 {
10813   switch (get_attr_type (insn))
10814     {
10815     case TYPE_ALU:
10816       gcc_assert (operands[2] == const1_rtx);
10817       return "add{l}\t%0, %0";
10818
10819     default:
10820       if (REG_P (operands[2]))
10821         return "sal{l}\t{%b2, %0|%0, %b2}";
10822       else if (operands[2] == const1_rtx
10823                && (TARGET_SHIFT1 || optimize_size))
10824         return "sal{l}\t%0";
10825       else
10826         return "sal{l}\t{%2, %0|%0, %2}";
10827     }
10828 }
10829   [(set (attr "type")
10830      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10831                           (const_int 0))
10832                       (match_operand 0 "register_operand" ""))
10833                  (match_operand 2 "const1_operand" ""))
10834               (const_string "alu")
10835            ]
10836            (const_string "ishift")))
10837    (set_attr "mode" "SI")])
10838
10839 (define_insn "*ashlsi3_cconly"
10840   [(set (reg FLAGS_REG)
10841         (compare
10842           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10843                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10844           (const_int 0)))
10845    (clobber (match_scratch:SI 0 "=r"))]
10846   "ix86_match_ccmode (insn, CCGOCmode)
10847    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10848    && (optimize_size
10849        || !TARGET_PARTIAL_FLAG_REG_STALL
10850        || (operands[2] == const1_rtx
10851            && (TARGET_SHIFT1
10852                || TARGET_DOUBLE_WITH_ADD)))"
10853 {
10854   switch (get_attr_type (insn))
10855     {
10856     case TYPE_ALU:
10857       gcc_assert (operands[2] == const1_rtx);
10858       return "add{l}\t%0, %0";
10859
10860     default:
10861       if (REG_P (operands[2]))
10862         return "sal{l}\t{%b2, %0|%0, %b2}";
10863       else if (operands[2] == const1_rtx
10864                && (TARGET_SHIFT1 || optimize_size))
10865         return "sal{l}\t%0";
10866       else
10867         return "sal{l}\t{%2, %0|%0, %2}";
10868     }
10869 }
10870   [(set (attr "type")
10871      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10872                           (const_int 0))
10873                       (match_operand 0 "register_operand" ""))
10874                  (match_operand 2 "const1_operand" ""))
10875               (const_string "alu")
10876            ]
10877            (const_string "ishift")))
10878    (set_attr "mode" "SI")])
10879
10880 (define_insn "*ashlsi3_cmp_zext"
10881   [(set (reg FLAGS_REG)
10882         (compare
10883           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10884                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10885           (const_int 0)))
10886    (set (match_operand:DI 0 "register_operand" "=r")
10887         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10888   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10889    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10890    && (optimize_size
10891        || !TARGET_PARTIAL_FLAG_REG_STALL
10892        || (operands[2] == const1_rtx
10893            && (TARGET_SHIFT1
10894                || TARGET_DOUBLE_WITH_ADD)))"
10895 {
10896   switch (get_attr_type (insn))
10897     {
10898     case TYPE_ALU:
10899       gcc_assert (operands[2] == const1_rtx);
10900       return "add{l}\t%k0, %k0";
10901
10902     default:
10903       if (REG_P (operands[2]))
10904         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10905       else if (operands[2] == const1_rtx
10906                && (TARGET_SHIFT1 || optimize_size))
10907         return "sal{l}\t%k0";
10908       else
10909         return "sal{l}\t{%2, %k0|%k0, %2}";
10910     }
10911 }
10912   [(set (attr "type")
10913      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10914                      (const_int 0))
10915                  (match_operand 2 "const1_operand" ""))
10916               (const_string "alu")
10917            ]
10918            (const_string "ishift")))
10919    (set_attr "mode" "SI")])
10920
10921 (define_expand "ashlhi3"
10922   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10923         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10924                    (match_operand:QI 2 "nonmemory_operand" "")))
10925    (clobber (reg:CC FLAGS_REG))]
10926   "TARGET_HIMODE_MATH"
10927   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10928
10929 (define_insn "*ashlhi3_1_lea"
10930   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10931         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10932                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10933    (clobber (reg:CC FLAGS_REG))]
10934   "!TARGET_PARTIAL_REG_STALL
10935    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10936 {
10937   switch (get_attr_type (insn))
10938     {
10939     case TYPE_LEA:
10940       return "#";
10941     case TYPE_ALU:
10942       gcc_assert (operands[2] == const1_rtx);
10943       return "add{w}\t%0, %0";
10944
10945     default:
10946       if (REG_P (operands[2]))
10947         return "sal{w}\t{%b2, %0|%0, %b2}";
10948       else if (operands[2] == const1_rtx
10949                && (TARGET_SHIFT1 || optimize_size))
10950         return "sal{w}\t%0";
10951       else
10952         return "sal{w}\t{%2, %0|%0, %2}";
10953     }
10954 }
10955   [(set (attr "type")
10956      (cond [(eq_attr "alternative" "1")
10957               (const_string "lea")
10958             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10959                           (const_int 0))
10960                       (match_operand 0 "register_operand" ""))
10961                  (match_operand 2 "const1_operand" ""))
10962               (const_string "alu")
10963            ]
10964            (const_string "ishift")))
10965    (set_attr "mode" "HI,SI")])
10966
10967 (define_insn "*ashlhi3_1"
10968   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10969         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10970                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10971    (clobber (reg:CC FLAGS_REG))]
10972   "TARGET_PARTIAL_REG_STALL
10973    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10974 {
10975   switch (get_attr_type (insn))
10976     {
10977     case TYPE_ALU:
10978       gcc_assert (operands[2] == const1_rtx);
10979       return "add{w}\t%0, %0";
10980
10981     default:
10982       if (REG_P (operands[2]))
10983         return "sal{w}\t{%b2, %0|%0, %b2}";
10984       else if (operands[2] == const1_rtx
10985                && (TARGET_SHIFT1 || optimize_size))
10986         return "sal{w}\t%0";
10987       else
10988         return "sal{w}\t{%2, %0|%0, %2}";
10989     }
10990 }
10991   [(set (attr "type")
10992      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10993                           (const_int 0))
10994                       (match_operand 0 "register_operand" ""))
10995                  (match_operand 2 "const1_operand" ""))
10996               (const_string "alu")
10997            ]
10998            (const_string "ishift")))
10999    (set_attr "mode" "HI")])
11000
11001 ;; This pattern can't accept a variable shift count, since shifts by
11002 ;; zero don't affect the flags.  We assume that shifts by constant
11003 ;; zero are optimized away.
11004 (define_insn "*ashlhi3_cmp"
11005   [(set (reg FLAGS_REG)
11006         (compare
11007           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11008                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11009           (const_int 0)))
11010    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11011         (ashift:HI (match_dup 1) (match_dup 2)))]
11012   "ix86_match_ccmode (insn, CCGOCmode)
11013    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11014    && (optimize_size
11015        || !TARGET_PARTIAL_FLAG_REG_STALL
11016        || (operands[2] == const1_rtx
11017            && (TARGET_SHIFT1
11018                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11019 {
11020   switch (get_attr_type (insn))
11021     {
11022     case TYPE_ALU:
11023       gcc_assert (operands[2] == const1_rtx);
11024       return "add{w}\t%0, %0";
11025
11026     default:
11027       if (REG_P (operands[2]))
11028         return "sal{w}\t{%b2, %0|%0, %b2}";
11029       else if (operands[2] == const1_rtx
11030                && (TARGET_SHIFT1 || optimize_size))
11031         return "sal{w}\t%0";
11032       else
11033         return "sal{w}\t{%2, %0|%0, %2}";
11034     }
11035 }
11036   [(set (attr "type")
11037      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11038                           (const_int 0))
11039                       (match_operand 0 "register_operand" ""))
11040                  (match_operand 2 "const1_operand" ""))
11041               (const_string "alu")
11042            ]
11043            (const_string "ishift")))
11044    (set_attr "mode" "HI")])
11045
11046 (define_insn "*ashlhi3_cconly"
11047   [(set (reg FLAGS_REG)
11048         (compare
11049           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11050                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11051           (const_int 0)))
11052    (clobber (match_scratch:HI 0 "=r"))]
11053   "ix86_match_ccmode (insn, CCGOCmode)
11054    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11055    && (optimize_size
11056        || !TARGET_PARTIAL_FLAG_REG_STALL
11057        || (operands[2] == const1_rtx
11058            && (TARGET_SHIFT1
11059                || TARGET_DOUBLE_WITH_ADD)))"
11060 {
11061   switch (get_attr_type (insn))
11062     {
11063     case TYPE_ALU:
11064       gcc_assert (operands[2] == const1_rtx);
11065       return "add{w}\t%0, %0";
11066
11067     default:
11068       if (REG_P (operands[2]))
11069         return "sal{w}\t{%b2, %0|%0, %b2}";
11070       else if (operands[2] == const1_rtx
11071                && (TARGET_SHIFT1 || optimize_size))
11072         return "sal{w}\t%0";
11073       else
11074         return "sal{w}\t{%2, %0|%0, %2}";
11075     }
11076 }
11077   [(set (attr "type")
11078      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11079                           (const_int 0))
11080                       (match_operand 0 "register_operand" ""))
11081                  (match_operand 2 "const1_operand" ""))
11082               (const_string "alu")
11083            ]
11084            (const_string "ishift")))
11085    (set_attr "mode" "HI")])
11086
11087 (define_expand "ashlqi3"
11088   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11089         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11090                    (match_operand:QI 2 "nonmemory_operand" "")))
11091    (clobber (reg:CC FLAGS_REG))]
11092   "TARGET_QIMODE_MATH"
11093   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11094
11095 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11096
11097 (define_insn "*ashlqi3_1_lea"
11098   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11099         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11100                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11101    (clobber (reg:CC FLAGS_REG))]
11102   "!TARGET_PARTIAL_REG_STALL
11103    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11104 {
11105   switch (get_attr_type (insn))
11106     {
11107     case TYPE_LEA:
11108       return "#";
11109     case TYPE_ALU:
11110       gcc_assert (operands[2] == const1_rtx);
11111       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11112         return "add{l}\t%k0, %k0";
11113       else
11114         return "add{b}\t%0, %0";
11115
11116     default:
11117       if (REG_P (operands[2]))
11118         {
11119           if (get_attr_mode (insn) == MODE_SI)
11120             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11121           else
11122             return "sal{b}\t{%b2, %0|%0, %b2}";
11123         }
11124       else if (operands[2] == const1_rtx
11125                && (TARGET_SHIFT1 || optimize_size))
11126         {
11127           if (get_attr_mode (insn) == MODE_SI)
11128             return "sal{l}\t%0";
11129           else
11130             return "sal{b}\t%0";
11131         }
11132       else
11133         {
11134           if (get_attr_mode (insn) == MODE_SI)
11135             return "sal{l}\t{%2, %k0|%k0, %2}";
11136           else
11137             return "sal{b}\t{%2, %0|%0, %2}";
11138         }
11139     }
11140 }
11141   [(set (attr "type")
11142      (cond [(eq_attr "alternative" "2")
11143               (const_string "lea")
11144             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11145                           (const_int 0))
11146                       (match_operand 0 "register_operand" ""))
11147                  (match_operand 2 "const1_operand" ""))
11148               (const_string "alu")
11149            ]
11150            (const_string "ishift")))
11151    (set_attr "mode" "QI,SI,SI")])
11152
11153 (define_insn "*ashlqi3_1"
11154   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11155         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11156                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11157    (clobber (reg:CC FLAGS_REG))]
11158   "TARGET_PARTIAL_REG_STALL
11159    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11160 {
11161   switch (get_attr_type (insn))
11162     {
11163     case TYPE_ALU:
11164       gcc_assert (operands[2] == const1_rtx);
11165       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11166         return "add{l}\t%k0, %k0";
11167       else
11168         return "add{b}\t%0, %0";
11169
11170     default:
11171       if (REG_P (operands[2]))
11172         {
11173           if (get_attr_mode (insn) == MODE_SI)
11174             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11175           else
11176             return "sal{b}\t{%b2, %0|%0, %b2}";
11177         }
11178       else if (operands[2] == const1_rtx
11179                && (TARGET_SHIFT1 || optimize_size))
11180         {
11181           if (get_attr_mode (insn) == MODE_SI)
11182             return "sal{l}\t%0";
11183           else
11184             return "sal{b}\t%0";
11185         }
11186       else
11187         {
11188           if (get_attr_mode (insn) == MODE_SI)
11189             return "sal{l}\t{%2, %k0|%k0, %2}";
11190           else
11191             return "sal{b}\t{%2, %0|%0, %2}";
11192         }
11193     }
11194 }
11195   [(set (attr "type")
11196      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11197                           (const_int 0))
11198                       (match_operand 0 "register_operand" ""))
11199                  (match_operand 2 "const1_operand" ""))
11200               (const_string "alu")
11201            ]
11202            (const_string "ishift")))
11203    (set_attr "mode" "QI,SI")])
11204
11205 ;; This pattern can't accept a variable shift count, since shifts by
11206 ;; zero don't affect the flags.  We assume that shifts by constant
11207 ;; zero are optimized away.
11208 (define_insn "*ashlqi3_cmp"
11209   [(set (reg FLAGS_REG)
11210         (compare
11211           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11212                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11213           (const_int 0)))
11214    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11215         (ashift:QI (match_dup 1) (match_dup 2)))]
11216   "ix86_match_ccmode (insn, CCGOCmode)
11217    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11218    && (optimize_size
11219        || !TARGET_PARTIAL_FLAG_REG_STALL
11220        || (operands[2] == const1_rtx
11221            && (TARGET_SHIFT1
11222                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11223 {
11224   switch (get_attr_type (insn))
11225     {
11226     case TYPE_ALU:
11227       gcc_assert (operands[2] == const1_rtx);
11228       return "add{b}\t%0, %0";
11229
11230     default:
11231       if (REG_P (operands[2]))
11232         return "sal{b}\t{%b2, %0|%0, %b2}";
11233       else if (operands[2] == const1_rtx
11234                && (TARGET_SHIFT1 || optimize_size))
11235         return "sal{b}\t%0";
11236       else
11237         return "sal{b}\t{%2, %0|%0, %2}";
11238     }
11239 }
11240   [(set (attr "type")
11241      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11242                           (const_int 0))
11243                       (match_operand 0 "register_operand" ""))
11244                  (match_operand 2 "const1_operand" ""))
11245               (const_string "alu")
11246            ]
11247            (const_string "ishift")))
11248    (set_attr "mode" "QI")])
11249
11250 (define_insn "*ashlqi3_cconly"
11251   [(set (reg FLAGS_REG)
11252         (compare
11253           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11254                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11255           (const_int 0)))
11256    (clobber (match_scratch:QI 0 "=q"))]
11257   "ix86_match_ccmode (insn, CCGOCmode)
11258    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11259    && (optimize_size
11260        || !TARGET_PARTIAL_FLAG_REG_STALL
11261        || (operands[2] == const1_rtx
11262            && (TARGET_SHIFT1
11263                || TARGET_DOUBLE_WITH_ADD)))"
11264 {
11265   switch (get_attr_type (insn))
11266     {
11267     case TYPE_ALU:
11268       gcc_assert (operands[2] == const1_rtx);
11269       return "add{b}\t%0, %0";
11270
11271     default:
11272       if (REG_P (operands[2]))
11273         return "sal{b}\t{%b2, %0|%0, %b2}";
11274       else if (operands[2] == const1_rtx
11275                && (TARGET_SHIFT1 || optimize_size))
11276         return "sal{b}\t%0";
11277       else
11278         return "sal{b}\t{%2, %0|%0, %2}";
11279     }
11280 }
11281   [(set (attr "type")
11282      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11283                           (const_int 0))
11284                       (match_operand 0 "register_operand" ""))
11285                  (match_operand 2 "const1_operand" ""))
11286               (const_string "alu")
11287            ]
11288            (const_string "ishift")))
11289    (set_attr "mode" "QI")])
11290
11291 ;; See comment above `ashldi3' about how this works.
11292
11293 (define_expand "ashrti3"
11294   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11295                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11296                                 (match_operand:QI 2 "nonmemory_operand" "")))
11297               (clobber (reg:CC FLAGS_REG))])]
11298   "TARGET_64BIT"
11299 {
11300   if (! immediate_operand (operands[2], QImode))
11301     {
11302       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11303       DONE;
11304     }
11305   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11306   DONE;
11307 })
11308
11309 (define_insn "ashrti3_1"
11310   [(set (match_operand:TI 0 "register_operand" "=r")
11311         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11312                      (match_operand:QI 2 "register_operand" "c")))
11313    (clobber (match_scratch:DI 3 "=&r"))
11314    (clobber (reg:CC FLAGS_REG))]
11315   "TARGET_64BIT"
11316   "#"
11317   [(set_attr "type" "multi")])
11318
11319 (define_insn "*ashrti3_2"
11320   [(set (match_operand:TI 0 "register_operand" "=r")
11321         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11322                      (match_operand:QI 2 "immediate_operand" "O")))
11323    (clobber (reg:CC FLAGS_REG))]
11324   "TARGET_64BIT"
11325   "#"
11326   [(set_attr "type" "multi")])
11327
11328 (define_split
11329   [(set (match_operand:TI 0 "register_operand" "")
11330         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11331                      (match_operand:QI 2 "register_operand" "")))
11332    (clobber (match_scratch:DI 3 ""))
11333    (clobber (reg:CC FLAGS_REG))]
11334   "TARGET_64BIT && reload_completed"
11335   [(const_int 0)]
11336   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11337
11338 (define_split
11339   [(set (match_operand:TI 0 "register_operand" "")
11340         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11341                      (match_operand:QI 2 "immediate_operand" "")))
11342    (clobber (reg:CC FLAGS_REG))]
11343   "TARGET_64BIT && reload_completed"
11344   [(const_int 0)]
11345   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11346
11347 (define_insn "x86_64_shrd"
11348   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11349         (ior:DI (ashiftrt:DI (match_dup 0)
11350                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11351                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11352                   (minus:QI (const_int 64) (match_dup 2)))))
11353    (clobber (reg:CC FLAGS_REG))]
11354   "TARGET_64BIT"
11355   "@
11356    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11357    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11358   [(set_attr "type" "ishift")
11359    (set_attr "prefix_0f" "1")
11360    (set_attr "mode" "DI")
11361    (set_attr "athlon_decode" "vector")
11362    (set_attr "amdfam10_decode" "vector")])   
11363
11364 (define_expand "ashrdi3"
11365   [(set (match_operand:DI 0 "shiftdi_operand" "")
11366         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11367                      (match_operand:QI 2 "nonmemory_operand" "")))]
11368   ""
11369   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11370
11371 (define_insn "*ashrdi3_63_rex64"
11372   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11373         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11374                      (match_operand:DI 2 "const_int_operand" "i,i")))
11375    (clobber (reg:CC FLAGS_REG))]
11376   "TARGET_64BIT && INTVAL (operands[2]) == 63
11377    && (TARGET_USE_CLTD || optimize_size)
11378    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11379   "@
11380    {cqto|cqo}
11381    sar{q}\t{%2, %0|%0, %2}"
11382   [(set_attr "type" "imovx,ishift")
11383    (set_attr "prefix_0f" "0,*")
11384    (set_attr "length_immediate" "0,*")
11385    (set_attr "modrm" "0,1")
11386    (set_attr "mode" "DI")])
11387
11388 (define_insn "*ashrdi3_1_one_bit_rex64"
11389   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11390         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11391                      (match_operand:QI 2 "const1_operand" "")))
11392    (clobber (reg:CC FLAGS_REG))]
11393   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11394    && (TARGET_SHIFT1 || optimize_size)"
11395   "sar{q}\t%0"
11396   [(set_attr "type" "ishift")
11397    (set (attr "length")
11398      (if_then_else (match_operand:DI 0 "register_operand" "")
11399         (const_string "2")
11400         (const_string "*")))])
11401
11402 (define_insn "*ashrdi3_1_rex64"
11403   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11404         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11405                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11406    (clobber (reg:CC FLAGS_REG))]
11407   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11408   "@
11409    sar{q}\t{%2, %0|%0, %2}
11410    sar{q}\t{%b2, %0|%0, %b2}"
11411   [(set_attr "type" "ishift")
11412    (set_attr "mode" "DI")])
11413
11414 ;; This pattern can't accept a variable shift count, since shifts by
11415 ;; zero don't affect the flags.  We assume that shifts by constant
11416 ;; zero are optimized away.
11417 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11418   [(set (reg FLAGS_REG)
11419         (compare
11420           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11421                        (match_operand:QI 2 "const1_operand" ""))
11422           (const_int 0)))
11423    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11424         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11425   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11426    && (TARGET_SHIFT1 || optimize_size)
11427    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11428   "sar{q}\t%0"
11429   [(set_attr "type" "ishift")
11430    (set (attr "length")
11431      (if_then_else (match_operand:DI 0 "register_operand" "")
11432         (const_string "2")
11433         (const_string "*")))])
11434
11435 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11436   [(set (reg FLAGS_REG)
11437         (compare
11438           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11439                        (match_operand:QI 2 "const1_operand" ""))
11440           (const_int 0)))
11441    (clobber (match_scratch:DI 0 "=r"))]
11442   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11443    && (TARGET_SHIFT1 || optimize_size)
11444    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11445   "sar{q}\t%0"
11446   [(set_attr "type" "ishift")
11447    (set_attr "length" "2")])
11448
11449 ;; This pattern can't accept a variable shift count, since shifts by
11450 ;; zero don't affect the flags.  We assume that shifts by constant
11451 ;; zero are optimized away.
11452 (define_insn "*ashrdi3_cmp_rex64"
11453   [(set (reg FLAGS_REG)
11454         (compare
11455           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11456                        (match_operand:QI 2 "const_int_operand" "n"))
11457           (const_int 0)))
11458    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11459         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11460   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11461    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11462    && (optimize_size
11463        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11464   "sar{q}\t{%2, %0|%0, %2}"
11465   [(set_attr "type" "ishift")
11466    (set_attr "mode" "DI")])
11467
11468 (define_insn "*ashrdi3_cconly_rex64"
11469   [(set (reg FLAGS_REG)
11470         (compare
11471           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11472                        (match_operand:QI 2 "const_int_operand" "n"))
11473           (const_int 0)))
11474    (clobber (match_scratch:DI 0 "=r"))]
11475   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11476    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11477    && (optimize_size
11478        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11479   "sar{q}\t{%2, %0|%0, %2}"
11480   [(set_attr "type" "ishift")
11481    (set_attr "mode" "DI")])
11482
11483 (define_insn "*ashrdi3_1"
11484   [(set (match_operand:DI 0 "register_operand" "=r")
11485         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11486                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11487    (clobber (reg:CC FLAGS_REG))]
11488   "!TARGET_64BIT"
11489   "#"
11490   [(set_attr "type" "multi")])
11491
11492 ;; By default we don't ask for a scratch register, because when DImode
11493 ;; values are manipulated, registers are already at a premium.  But if
11494 ;; we have one handy, we won't turn it away.
11495 (define_peephole2
11496   [(match_scratch:SI 3 "r")
11497    (parallel [(set (match_operand:DI 0 "register_operand" "")
11498                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11499                                 (match_operand:QI 2 "nonmemory_operand" "")))
11500               (clobber (reg:CC FLAGS_REG))])
11501    (match_dup 3)]
11502   "!TARGET_64BIT && TARGET_CMOVE"
11503   [(const_int 0)]
11504   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11505
11506 (define_split
11507   [(set (match_operand:DI 0 "register_operand" "")
11508         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11509                      (match_operand:QI 2 "nonmemory_operand" "")))
11510    (clobber (reg:CC FLAGS_REG))]
11511   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11512                      ? flow2_completed : reload_completed)"
11513   [(const_int 0)]
11514   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11515
11516 (define_insn "x86_shrd_1"
11517   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11518         (ior:SI (ashiftrt:SI (match_dup 0)
11519                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11520                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11521                   (minus:QI (const_int 32) (match_dup 2)))))
11522    (clobber (reg:CC FLAGS_REG))]
11523   ""
11524   "@
11525    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11526    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11527   [(set_attr "type" "ishift")
11528    (set_attr "prefix_0f" "1")
11529    (set_attr "pent_pair" "np")
11530    (set_attr "mode" "SI")])
11531
11532 (define_expand "x86_shift_adj_3"
11533   [(use (match_operand:SI 0 "register_operand" ""))
11534    (use (match_operand:SI 1 "register_operand" ""))
11535    (use (match_operand:QI 2 "register_operand" ""))]
11536   ""
11537 {
11538   rtx label = gen_label_rtx ();
11539   rtx tmp;
11540
11541   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11542
11543   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11544   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11545   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11546                               gen_rtx_LABEL_REF (VOIDmode, label),
11547                               pc_rtx);
11548   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11549   JUMP_LABEL (tmp) = label;
11550
11551   emit_move_insn (operands[0], operands[1]);
11552   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11553
11554   emit_label (label);
11555   LABEL_NUSES (label) = 1;
11556
11557   DONE;
11558 })
11559
11560 (define_insn "ashrsi3_31"
11561   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11562         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11563                      (match_operand:SI 2 "const_int_operand" "i,i")))
11564    (clobber (reg:CC FLAGS_REG))]
11565   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11566    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11567   "@
11568    {cltd|cdq}
11569    sar{l}\t{%2, %0|%0, %2}"
11570   [(set_attr "type" "imovx,ishift")
11571    (set_attr "prefix_0f" "0,*")
11572    (set_attr "length_immediate" "0,*")
11573    (set_attr "modrm" "0,1")
11574    (set_attr "mode" "SI")])
11575
11576 (define_insn "*ashrsi3_31_zext"
11577   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11578         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11579                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11580    (clobber (reg:CC FLAGS_REG))]
11581   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11582    && INTVAL (operands[2]) == 31
11583    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11584   "@
11585    {cltd|cdq}
11586    sar{l}\t{%2, %k0|%k0, %2}"
11587   [(set_attr "type" "imovx,ishift")
11588    (set_attr "prefix_0f" "0,*")
11589    (set_attr "length_immediate" "0,*")
11590    (set_attr "modrm" "0,1")
11591    (set_attr "mode" "SI")])
11592
11593 (define_expand "ashrsi3"
11594   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11595         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11596                      (match_operand:QI 2 "nonmemory_operand" "")))
11597    (clobber (reg:CC FLAGS_REG))]
11598   ""
11599   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11600
11601 (define_insn "*ashrsi3_1_one_bit"
11602   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11603         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11604                      (match_operand:QI 2 "const1_operand" "")))
11605    (clobber (reg:CC FLAGS_REG))]
11606   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11607    && (TARGET_SHIFT1 || optimize_size)"
11608   "sar{l}\t%0"
11609   [(set_attr "type" "ishift")
11610    (set (attr "length")
11611      (if_then_else (match_operand:SI 0 "register_operand" "")
11612         (const_string "2")
11613         (const_string "*")))])
11614
11615 (define_insn "*ashrsi3_1_one_bit_zext"
11616   [(set (match_operand:DI 0 "register_operand" "=r")
11617         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11618                                      (match_operand:QI 2 "const1_operand" ""))))
11619    (clobber (reg:CC FLAGS_REG))]
11620   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11621    && (TARGET_SHIFT1 || optimize_size)"
11622   "sar{l}\t%k0"
11623   [(set_attr "type" "ishift")
11624    (set_attr "length" "2")])
11625
11626 (define_insn "*ashrsi3_1"
11627   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11628         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11629                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11630    (clobber (reg:CC FLAGS_REG))]
11631   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11632   "@
11633    sar{l}\t{%2, %0|%0, %2}
11634    sar{l}\t{%b2, %0|%0, %b2}"
11635   [(set_attr "type" "ishift")
11636    (set_attr "mode" "SI")])
11637
11638 (define_insn "*ashrsi3_1_zext"
11639   [(set (match_operand:DI 0 "register_operand" "=r,r")
11640         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11641                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11642    (clobber (reg:CC FLAGS_REG))]
11643   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11644   "@
11645    sar{l}\t{%2, %k0|%k0, %2}
11646    sar{l}\t{%b2, %k0|%k0, %b2}"
11647   [(set_attr "type" "ishift")
11648    (set_attr "mode" "SI")])
11649
11650 ;; This pattern can't accept a variable shift count, since shifts by
11651 ;; zero don't affect the flags.  We assume that shifts by constant
11652 ;; zero are optimized away.
11653 (define_insn "*ashrsi3_one_bit_cmp"
11654   [(set (reg FLAGS_REG)
11655         (compare
11656           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11657                        (match_operand:QI 2 "const1_operand" ""))
11658           (const_int 0)))
11659    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11660         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11661   "ix86_match_ccmode (insn, CCGOCmode)
11662    && (TARGET_SHIFT1 || optimize_size)
11663    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11664   "sar{l}\t%0"
11665   [(set_attr "type" "ishift")
11666    (set (attr "length")
11667      (if_then_else (match_operand:SI 0 "register_operand" "")
11668         (const_string "2")
11669         (const_string "*")))])
11670
11671 (define_insn "*ashrsi3_one_bit_cconly"
11672   [(set (reg FLAGS_REG)
11673         (compare
11674           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11675                        (match_operand:QI 2 "const1_operand" ""))
11676           (const_int 0)))
11677    (clobber (match_scratch:SI 0 "=r"))]
11678   "ix86_match_ccmode (insn, CCGOCmode)
11679    && (TARGET_SHIFT1 || optimize_size)
11680    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11681   "sar{l}\t%0"
11682   [(set_attr "type" "ishift")
11683    (set_attr "length" "2")])
11684
11685 (define_insn "*ashrsi3_one_bit_cmp_zext"
11686   [(set (reg FLAGS_REG)
11687         (compare
11688           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11689                        (match_operand:QI 2 "const1_operand" ""))
11690           (const_int 0)))
11691    (set (match_operand:DI 0 "register_operand" "=r")
11692         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11693   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11694    && (TARGET_SHIFT1 || optimize_size)
11695    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11696   "sar{l}\t%k0"
11697   [(set_attr "type" "ishift")
11698    (set_attr "length" "2")])
11699
11700 ;; This pattern can't accept a variable shift count, since shifts by
11701 ;; zero don't affect the flags.  We assume that shifts by constant
11702 ;; zero are optimized away.
11703 (define_insn "*ashrsi3_cmp"
11704   [(set (reg FLAGS_REG)
11705         (compare
11706           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11707                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11708           (const_int 0)))
11709    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11710         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11711   "ix86_match_ccmode (insn, CCGOCmode)
11712    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11713    && (optimize_size
11714        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11715   "sar{l}\t{%2, %0|%0, %2}"
11716   [(set_attr "type" "ishift")
11717    (set_attr "mode" "SI")])
11718
11719 (define_insn "*ashrsi3_cconly"
11720   [(set (reg FLAGS_REG)
11721         (compare
11722           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11723                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11724           (const_int 0)))
11725    (clobber (match_scratch:SI 0 "=r"))]
11726   "ix86_match_ccmode (insn, CCGOCmode)
11727    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11728    && (optimize_size
11729        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11730   "sar{l}\t{%2, %0|%0, %2}"
11731   [(set_attr "type" "ishift")
11732    (set_attr "mode" "SI")])
11733
11734 (define_insn "*ashrsi3_cmp_zext"
11735   [(set (reg FLAGS_REG)
11736         (compare
11737           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11738                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11739           (const_int 0)))
11740    (set (match_operand:DI 0 "register_operand" "=r")
11741         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11742   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11743    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11744    && (optimize_size
11745        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11746   "sar{l}\t{%2, %k0|%k0, %2}"
11747   [(set_attr "type" "ishift")
11748    (set_attr "mode" "SI")])
11749
11750 (define_expand "ashrhi3"
11751   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11752         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11753                      (match_operand:QI 2 "nonmemory_operand" "")))
11754    (clobber (reg:CC FLAGS_REG))]
11755   "TARGET_HIMODE_MATH"
11756   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11757
11758 (define_insn "*ashrhi3_1_one_bit"
11759   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11760         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11761                      (match_operand:QI 2 "const1_operand" "")))
11762    (clobber (reg:CC FLAGS_REG))]
11763   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11764    && (TARGET_SHIFT1 || optimize_size)"
11765   "sar{w}\t%0"
11766   [(set_attr "type" "ishift")
11767    (set (attr "length")
11768      (if_then_else (match_operand 0 "register_operand" "")
11769         (const_string "2")
11770         (const_string "*")))])
11771
11772 (define_insn "*ashrhi3_1"
11773   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11774         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11775                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11776    (clobber (reg:CC FLAGS_REG))]
11777   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11778   "@
11779    sar{w}\t{%2, %0|%0, %2}
11780    sar{w}\t{%b2, %0|%0, %b2}"
11781   [(set_attr "type" "ishift")
11782    (set_attr "mode" "HI")])
11783
11784 ;; This pattern can't accept a variable shift count, since shifts by
11785 ;; zero don't affect the flags.  We assume that shifts by constant
11786 ;; zero are optimized away.
11787 (define_insn "*ashrhi3_one_bit_cmp"
11788   [(set (reg FLAGS_REG)
11789         (compare
11790           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11791                        (match_operand:QI 2 "const1_operand" ""))
11792           (const_int 0)))
11793    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11794         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11795   "ix86_match_ccmode (insn, CCGOCmode)
11796    && (TARGET_SHIFT1 || optimize_size)
11797    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11798   "sar{w}\t%0"
11799   [(set_attr "type" "ishift")
11800    (set (attr "length")
11801      (if_then_else (match_operand 0 "register_operand" "")
11802         (const_string "2")
11803         (const_string "*")))])
11804
11805 (define_insn "*ashrhi3_one_bit_cconly"
11806   [(set (reg FLAGS_REG)
11807         (compare
11808           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11809                        (match_operand:QI 2 "const1_operand" ""))
11810           (const_int 0)))
11811    (clobber (match_scratch:HI 0 "=r"))]
11812   "ix86_match_ccmode (insn, CCGOCmode)
11813    && (TARGET_SHIFT1 || optimize_size)
11814    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11815   "sar{w}\t%0"
11816   [(set_attr "type" "ishift")
11817    (set_attr "length" "2")])
11818
11819 ;; This pattern can't accept a variable shift count, since shifts by
11820 ;; zero don't affect the flags.  We assume that shifts by constant
11821 ;; zero are optimized away.
11822 (define_insn "*ashrhi3_cmp"
11823   [(set (reg FLAGS_REG)
11824         (compare
11825           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11826                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11827           (const_int 0)))
11828    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11829         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11830   "ix86_match_ccmode (insn, CCGOCmode)
11831    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11832    && (optimize_size
11833        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11834   "sar{w}\t{%2, %0|%0, %2}"
11835   [(set_attr "type" "ishift")
11836    (set_attr "mode" "HI")])
11837
11838 (define_insn "*ashrhi3_cconly"
11839   [(set (reg FLAGS_REG)
11840         (compare
11841           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11842                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11843           (const_int 0)))
11844    (clobber (match_scratch:HI 0 "=r"))]
11845   "ix86_match_ccmode (insn, CCGOCmode)
11846    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11847    && (optimize_size
11848        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11849   "sar{w}\t{%2, %0|%0, %2}"
11850   [(set_attr "type" "ishift")
11851    (set_attr "mode" "HI")])
11852
11853 (define_expand "ashrqi3"
11854   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11855         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11856                      (match_operand:QI 2 "nonmemory_operand" "")))
11857    (clobber (reg:CC FLAGS_REG))]
11858   "TARGET_QIMODE_MATH"
11859   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11860
11861 (define_insn "*ashrqi3_1_one_bit"
11862   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11863         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11864                      (match_operand:QI 2 "const1_operand" "")))
11865    (clobber (reg:CC FLAGS_REG))]
11866   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11867    && (TARGET_SHIFT1 || optimize_size)"
11868   "sar{b}\t%0"
11869   [(set_attr "type" "ishift")
11870    (set (attr "length")
11871      (if_then_else (match_operand 0 "register_operand" "")
11872         (const_string "2")
11873         (const_string "*")))])
11874
11875 (define_insn "*ashrqi3_1_one_bit_slp"
11876   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11877         (ashiftrt:QI (match_dup 0)
11878                      (match_operand:QI 1 "const1_operand" "")))
11879    (clobber (reg:CC FLAGS_REG))]
11880   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11881    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11882    && (TARGET_SHIFT1 || optimize_size)"
11883   "sar{b}\t%0"
11884   [(set_attr "type" "ishift1")
11885    (set (attr "length")
11886      (if_then_else (match_operand 0 "register_operand" "")
11887         (const_string "2")
11888         (const_string "*")))])
11889
11890 (define_insn "*ashrqi3_1"
11891   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11892         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11893                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11894    (clobber (reg:CC FLAGS_REG))]
11895   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11896   "@
11897    sar{b}\t{%2, %0|%0, %2}
11898    sar{b}\t{%b2, %0|%0, %b2}"
11899   [(set_attr "type" "ishift")
11900    (set_attr "mode" "QI")])
11901
11902 (define_insn "*ashrqi3_1_slp"
11903   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11904         (ashiftrt:QI (match_dup 0)
11905                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11906    (clobber (reg:CC FLAGS_REG))]
11907   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11908    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11909   "@
11910    sar{b}\t{%1, %0|%0, %1}
11911    sar{b}\t{%b1, %0|%0, %b1}"
11912   [(set_attr "type" "ishift1")
11913    (set_attr "mode" "QI")])
11914
11915 ;; This pattern can't accept a variable shift count, since shifts by
11916 ;; zero don't affect the flags.  We assume that shifts by constant
11917 ;; zero are optimized away.
11918 (define_insn "*ashrqi3_one_bit_cmp"
11919   [(set (reg FLAGS_REG)
11920         (compare
11921           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11922                        (match_operand:QI 2 "const1_operand" "I"))
11923           (const_int 0)))
11924    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11925         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11926   "ix86_match_ccmode (insn, CCGOCmode)
11927    && (TARGET_SHIFT1 || optimize_size)
11928    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11929   "sar{b}\t%0"
11930   [(set_attr "type" "ishift")
11931    (set (attr "length")
11932      (if_then_else (match_operand 0 "register_operand" "")
11933         (const_string "2")
11934         (const_string "*")))])
11935
11936 (define_insn "*ashrqi3_one_bit_cconly"
11937   [(set (reg FLAGS_REG)
11938         (compare
11939           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11940                        (match_operand:QI 2 "const1_operand" "I"))
11941           (const_int 0)))
11942    (clobber (match_scratch:QI 0 "=q"))]
11943   "ix86_match_ccmode (insn, CCGOCmode)
11944    && (TARGET_SHIFT1 || optimize_size)
11945    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11946   "sar{b}\t%0"
11947   [(set_attr "type" "ishift")
11948    (set_attr "length" "2")])
11949
11950 ;; This pattern can't accept a variable shift count, since shifts by
11951 ;; zero don't affect the flags.  We assume that shifts by constant
11952 ;; zero are optimized away.
11953 (define_insn "*ashrqi3_cmp"
11954   [(set (reg FLAGS_REG)
11955         (compare
11956           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11957                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11958           (const_int 0)))
11959    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11960         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11961   "ix86_match_ccmode (insn, CCGOCmode)
11962    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11963    && (optimize_size
11964        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11965   "sar{b}\t{%2, %0|%0, %2}"
11966   [(set_attr "type" "ishift")
11967    (set_attr "mode" "QI")])
11968
11969 (define_insn "*ashrqi3_cconly"
11970   [(set (reg FLAGS_REG)
11971         (compare
11972           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11973                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11974           (const_int 0)))
11975    (clobber (match_scratch:QI 0 "=q"))]
11976   "ix86_match_ccmode (insn, CCGOCmode)
11977    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11978    && (optimize_size
11979        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11980   "sar{b}\t{%2, %0|%0, %2}"
11981   [(set_attr "type" "ishift")
11982    (set_attr "mode" "QI")])
11983
11984 \f
11985 ;; Logical shift instructions
11986
11987 ;; See comment above `ashldi3' about how this works.
11988
11989 (define_expand "lshrti3"
11990   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11991                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11992                                 (match_operand:QI 2 "nonmemory_operand" "")))
11993               (clobber (reg:CC FLAGS_REG))])]
11994   "TARGET_64BIT"
11995 {
11996   if (! immediate_operand (operands[2], QImode))
11997     {
11998       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11999       DONE;
12000     }
12001   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12002   DONE;
12003 })
12004
12005 (define_insn "lshrti3_1"
12006   [(set (match_operand:TI 0 "register_operand" "=r")
12007         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12008                      (match_operand:QI 2 "register_operand" "c")))
12009    (clobber (match_scratch:DI 3 "=&r"))
12010    (clobber (reg:CC FLAGS_REG))]
12011   "TARGET_64BIT"
12012   "#"
12013   [(set_attr "type" "multi")])
12014
12015 (define_insn "*lshrti3_2"
12016   [(set (match_operand:TI 0 "register_operand" "=r")
12017         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12018                      (match_operand:QI 2 "immediate_operand" "O")))
12019    (clobber (reg:CC FLAGS_REG))]
12020   "TARGET_64BIT"
12021   "#"
12022   [(set_attr "type" "multi")])
12023
12024 (define_split
12025   [(set (match_operand:TI 0 "register_operand" "")
12026         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12027                      (match_operand:QI 2 "register_operand" "")))
12028    (clobber (match_scratch:DI 3 ""))
12029    (clobber (reg:CC FLAGS_REG))]
12030   "TARGET_64BIT && reload_completed"
12031   [(const_int 0)]
12032   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12033
12034 (define_split
12035   [(set (match_operand:TI 0 "register_operand" "")
12036         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12037                      (match_operand:QI 2 "immediate_operand" "")))
12038    (clobber (reg:CC FLAGS_REG))]
12039   "TARGET_64BIT && reload_completed"
12040   [(const_int 0)]
12041   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12042
12043 (define_expand "lshrdi3"
12044   [(set (match_operand:DI 0 "shiftdi_operand" "")
12045         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12046                      (match_operand:QI 2 "nonmemory_operand" "")))]
12047   ""
12048   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12049
12050 (define_insn "*lshrdi3_1_one_bit_rex64"
12051   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12052         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12053                      (match_operand:QI 2 "const1_operand" "")))
12054    (clobber (reg:CC FLAGS_REG))]
12055   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12056    && (TARGET_SHIFT1 || optimize_size)"
12057   "shr{q}\t%0"
12058   [(set_attr "type" "ishift")
12059    (set (attr "length")
12060      (if_then_else (match_operand:DI 0 "register_operand" "")
12061         (const_string "2")
12062         (const_string "*")))])
12063
12064 (define_insn "*lshrdi3_1_rex64"
12065   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12066         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12067                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12068    (clobber (reg:CC FLAGS_REG))]
12069   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12070   "@
12071    shr{q}\t{%2, %0|%0, %2}
12072    shr{q}\t{%b2, %0|%0, %b2}"
12073   [(set_attr "type" "ishift")
12074    (set_attr "mode" "DI")])
12075
12076 ;; This pattern can't accept a variable shift count, since shifts by
12077 ;; zero don't affect the flags.  We assume that shifts by constant
12078 ;; zero are optimized away.
12079 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12080   [(set (reg FLAGS_REG)
12081         (compare
12082           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12083                        (match_operand:QI 2 "const1_operand" ""))
12084           (const_int 0)))
12085    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12086         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12087   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12088    && (TARGET_SHIFT1 || optimize_size)
12089    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12090   "shr{q}\t%0"
12091   [(set_attr "type" "ishift")
12092    (set (attr "length")
12093      (if_then_else (match_operand:DI 0 "register_operand" "")
12094         (const_string "2")
12095         (const_string "*")))])
12096
12097 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12098   [(set (reg FLAGS_REG)
12099         (compare
12100           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12101                        (match_operand:QI 2 "const1_operand" ""))
12102           (const_int 0)))
12103    (clobber (match_scratch:DI 0 "=r"))]
12104   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12105    && (TARGET_SHIFT1 || optimize_size)
12106    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12107   "shr{q}\t%0"
12108   [(set_attr "type" "ishift")
12109    (set_attr "length" "2")])
12110
12111 ;; This pattern can't accept a variable shift count, since shifts by
12112 ;; zero don't affect the flags.  We assume that shifts by constant
12113 ;; zero are optimized away.
12114 (define_insn "*lshrdi3_cmp_rex64"
12115   [(set (reg FLAGS_REG)
12116         (compare
12117           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12118                        (match_operand:QI 2 "const_int_operand" "e"))
12119           (const_int 0)))
12120    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12121         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12122   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12123    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12124    && (optimize_size
12125        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12126   "shr{q}\t{%2, %0|%0, %2}"
12127   [(set_attr "type" "ishift")
12128    (set_attr "mode" "DI")])
12129
12130 (define_insn "*lshrdi3_cconly_rex64"
12131   [(set (reg FLAGS_REG)
12132         (compare
12133           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12134                        (match_operand:QI 2 "const_int_operand" "e"))
12135           (const_int 0)))
12136    (clobber (match_scratch:DI 0 "=r"))]
12137   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12138    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12139    && (optimize_size
12140        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12141   "shr{q}\t{%2, %0|%0, %2}"
12142   [(set_attr "type" "ishift")
12143    (set_attr "mode" "DI")])
12144
12145 (define_insn "*lshrdi3_1"
12146   [(set (match_operand:DI 0 "register_operand" "=r")
12147         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12148                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12149    (clobber (reg:CC FLAGS_REG))]
12150   "!TARGET_64BIT"
12151   "#"
12152   [(set_attr "type" "multi")])
12153
12154 ;; By default we don't ask for a scratch register, because when DImode
12155 ;; values are manipulated, registers are already at a premium.  But if
12156 ;; we have one handy, we won't turn it away.
12157 (define_peephole2
12158   [(match_scratch:SI 3 "r")
12159    (parallel [(set (match_operand:DI 0 "register_operand" "")
12160                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12161                                 (match_operand:QI 2 "nonmemory_operand" "")))
12162               (clobber (reg:CC FLAGS_REG))])
12163    (match_dup 3)]
12164   "!TARGET_64BIT && TARGET_CMOVE"
12165   [(const_int 0)]
12166   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12167
12168 (define_split
12169   [(set (match_operand:DI 0 "register_operand" "")
12170         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12171                      (match_operand:QI 2 "nonmemory_operand" "")))
12172    (clobber (reg:CC FLAGS_REG))]
12173   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12174                      ? flow2_completed : reload_completed)"
12175   [(const_int 0)]
12176   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12177
12178 (define_expand "lshrsi3"
12179   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12180         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12181                      (match_operand:QI 2 "nonmemory_operand" "")))
12182    (clobber (reg:CC FLAGS_REG))]
12183   ""
12184   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12185
12186 (define_insn "*lshrsi3_1_one_bit"
12187   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12188         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12189                      (match_operand:QI 2 "const1_operand" "")))
12190    (clobber (reg:CC FLAGS_REG))]
12191   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12192    && (TARGET_SHIFT1 || optimize_size)"
12193   "shr{l}\t%0"
12194   [(set_attr "type" "ishift")
12195    (set (attr "length")
12196      (if_then_else (match_operand:SI 0 "register_operand" "")
12197         (const_string "2")
12198         (const_string "*")))])
12199
12200 (define_insn "*lshrsi3_1_one_bit_zext"
12201   [(set (match_operand:DI 0 "register_operand" "=r")
12202         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12203                      (match_operand:QI 2 "const1_operand" "")))
12204    (clobber (reg:CC FLAGS_REG))]
12205   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12206    && (TARGET_SHIFT1 || optimize_size)"
12207   "shr{l}\t%k0"
12208   [(set_attr "type" "ishift")
12209    (set_attr "length" "2")])
12210
12211 (define_insn "*lshrsi3_1"
12212   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12213         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12214                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12215    (clobber (reg:CC FLAGS_REG))]
12216   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12217   "@
12218    shr{l}\t{%2, %0|%0, %2}
12219    shr{l}\t{%b2, %0|%0, %b2}"
12220   [(set_attr "type" "ishift")
12221    (set_attr "mode" "SI")])
12222
12223 (define_insn "*lshrsi3_1_zext"
12224   [(set (match_operand:DI 0 "register_operand" "=r,r")
12225         (zero_extend:DI
12226           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12227                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12228    (clobber (reg:CC FLAGS_REG))]
12229   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12230   "@
12231    shr{l}\t{%2, %k0|%k0, %2}
12232    shr{l}\t{%b2, %k0|%k0, %b2}"
12233   [(set_attr "type" "ishift")
12234    (set_attr "mode" "SI")])
12235
12236 ;; This pattern can't accept a variable shift count, since shifts by
12237 ;; zero don't affect the flags.  We assume that shifts by constant
12238 ;; zero are optimized away.
12239 (define_insn "*lshrsi3_one_bit_cmp"
12240   [(set (reg FLAGS_REG)
12241         (compare
12242           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12243                        (match_operand:QI 2 "const1_operand" ""))
12244           (const_int 0)))
12245    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12246         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12247   "ix86_match_ccmode (insn, CCGOCmode)
12248    && (TARGET_SHIFT1 || optimize_size)
12249    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12250   "shr{l}\t%0"
12251   [(set_attr "type" "ishift")
12252    (set (attr "length")
12253      (if_then_else (match_operand:SI 0 "register_operand" "")
12254         (const_string "2")
12255         (const_string "*")))])
12256
12257 (define_insn "*lshrsi3_one_bit_cconly"
12258   [(set (reg FLAGS_REG)
12259         (compare
12260           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12261                        (match_operand:QI 2 "const1_operand" ""))
12262           (const_int 0)))
12263    (clobber (match_scratch:SI 0 "=r"))]
12264   "ix86_match_ccmode (insn, CCGOCmode)
12265    && (TARGET_SHIFT1 || optimize_size)
12266    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12267   "shr{l}\t%0"
12268   [(set_attr "type" "ishift")
12269    (set_attr "length" "2")])
12270
12271 (define_insn "*lshrsi3_cmp_one_bit_zext"
12272   [(set (reg FLAGS_REG)
12273         (compare
12274           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12275                        (match_operand:QI 2 "const1_operand" ""))
12276           (const_int 0)))
12277    (set (match_operand:DI 0 "register_operand" "=r")
12278         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12279   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12280    && (TARGET_SHIFT1 || optimize_size)
12281    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12282   "shr{l}\t%k0"
12283   [(set_attr "type" "ishift")
12284    (set_attr "length" "2")])
12285
12286 ;; This pattern can't accept a variable shift count, since shifts by
12287 ;; zero don't affect the flags.  We assume that shifts by constant
12288 ;; zero are optimized away.
12289 (define_insn "*lshrsi3_cmp"
12290   [(set (reg FLAGS_REG)
12291         (compare
12292           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12293                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12294           (const_int 0)))
12295    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12296         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12297   "ix86_match_ccmode (insn, CCGOCmode)
12298    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12299    && (optimize_size
12300        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12301   "shr{l}\t{%2, %0|%0, %2}"
12302   [(set_attr "type" "ishift")
12303    (set_attr "mode" "SI")])
12304
12305 (define_insn "*lshrsi3_cconly"
12306   [(set (reg FLAGS_REG)
12307       (compare
12308         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12309                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12310         (const_int 0)))
12311    (clobber (match_scratch:SI 0 "=r"))]
12312   "ix86_match_ccmode (insn, CCGOCmode)
12313    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12314    && (optimize_size
12315        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12316   "shr{l}\t{%2, %0|%0, %2}"
12317   [(set_attr "type" "ishift")
12318    (set_attr "mode" "SI")])
12319
12320 (define_insn "*lshrsi3_cmp_zext"
12321   [(set (reg FLAGS_REG)
12322         (compare
12323           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12324                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12325           (const_int 0)))
12326    (set (match_operand:DI 0 "register_operand" "=r")
12327         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12328   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12329    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12330    && (optimize_size
12331        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12332   "shr{l}\t{%2, %k0|%k0, %2}"
12333   [(set_attr "type" "ishift")
12334    (set_attr "mode" "SI")])
12335
12336 (define_expand "lshrhi3"
12337   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12338         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12339                      (match_operand:QI 2 "nonmemory_operand" "")))
12340    (clobber (reg:CC FLAGS_REG))]
12341   "TARGET_HIMODE_MATH"
12342   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12343
12344 (define_insn "*lshrhi3_1_one_bit"
12345   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12346         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12347                      (match_operand:QI 2 "const1_operand" "")))
12348    (clobber (reg:CC FLAGS_REG))]
12349   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12350    && (TARGET_SHIFT1 || optimize_size)"
12351   "shr{w}\t%0"
12352   [(set_attr "type" "ishift")
12353    (set (attr "length")
12354      (if_then_else (match_operand 0 "register_operand" "")
12355         (const_string "2")
12356         (const_string "*")))])
12357
12358 (define_insn "*lshrhi3_1"
12359   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12360         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12361                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12362    (clobber (reg:CC FLAGS_REG))]
12363   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12364   "@
12365    shr{w}\t{%2, %0|%0, %2}
12366    shr{w}\t{%b2, %0|%0, %b2}"
12367   [(set_attr "type" "ishift")
12368    (set_attr "mode" "HI")])
12369
12370 ;; This pattern can't accept a variable shift count, since shifts by
12371 ;; zero don't affect the flags.  We assume that shifts by constant
12372 ;; zero are optimized away.
12373 (define_insn "*lshrhi3_one_bit_cmp"
12374   [(set (reg FLAGS_REG)
12375         (compare
12376           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12377                        (match_operand:QI 2 "const1_operand" ""))
12378           (const_int 0)))
12379    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12380         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12381   "ix86_match_ccmode (insn, CCGOCmode)
12382    && (TARGET_SHIFT1 || optimize_size)
12383    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12384   "shr{w}\t%0"
12385   [(set_attr "type" "ishift")
12386    (set (attr "length")
12387      (if_then_else (match_operand:SI 0 "register_operand" "")
12388         (const_string "2")
12389         (const_string "*")))])
12390
12391 (define_insn "*lshrhi3_one_bit_cconly"
12392   [(set (reg FLAGS_REG)
12393         (compare
12394           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12395                        (match_operand:QI 2 "const1_operand" ""))
12396           (const_int 0)))
12397    (clobber (match_scratch:HI 0 "=r"))]
12398   "ix86_match_ccmode (insn, CCGOCmode)
12399    && (TARGET_SHIFT1 || optimize_size)
12400    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12401   "shr{w}\t%0"
12402   [(set_attr "type" "ishift")
12403    (set_attr "length" "2")])
12404
12405 ;; This pattern can't accept a variable shift count, since shifts by
12406 ;; zero don't affect the flags.  We assume that shifts by constant
12407 ;; zero are optimized away.
12408 (define_insn "*lshrhi3_cmp"
12409   [(set (reg FLAGS_REG)
12410         (compare
12411           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12412                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12413           (const_int 0)))
12414    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12415         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12416   "ix86_match_ccmode (insn, CCGOCmode)
12417    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12418    && (optimize_size
12419        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12420   "shr{w}\t{%2, %0|%0, %2}"
12421   [(set_attr "type" "ishift")
12422    (set_attr "mode" "HI")])
12423
12424 (define_insn "*lshrhi3_cconly"
12425   [(set (reg FLAGS_REG)
12426         (compare
12427           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12428                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12429           (const_int 0)))
12430    (clobber (match_scratch:HI 0 "=r"))]
12431   "ix86_match_ccmode (insn, CCGOCmode)
12432    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12433    && (optimize_size
12434        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12435   "shr{w}\t{%2, %0|%0, %2}"
12436   [(set_attr "type" "ishift")
12437    (set_attr "mode" "HI")])
12438
12439 (define_expand "lshrqi3"
12440   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12441         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12442                      (match_operand:QI 2 "nonmemory_operand" "")))
12443    (clobber (reg:CC FLAGS_REG))]
12444   "TARGET_QIMODE_MATH"
12445   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12446
12447 (define_insn "*lshrqi3_1_one_bit"
12448   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12449         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12450                      (match_operand:QI 2 "const1_operand" "")))
12451    (clobber (reg:CC FLAGS_REG))]
12452   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12453    && (TARGET_SHIFT1 || optimize_size)"
12454   "shr{b}\t%0"
12455   [(set_attr "type" "ishift")
12456    (set (attr "length")
12457      (if_then_else (match_operand 0 "register_operand" "")
12458         (const_string "2")
12459         (const_string "*")))])
12460
12461 (define_insn "*lshrqi3_1_one_bit_slp"
12462   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12463         (lshiftrt:QI (match_dup 0)
12464                      (match_operand:QI 1 "const1_operand" "")))
12465    (clobber (reg:CC FLAGS_REG))]
12466   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12467    && (TARGET_SHIFT1 || optimize_size)"
12468   "shr{b}\t%0"
12469   [(set_attr "type" "ishift1")
12470    (set (attr "length")
12471      (if_then_else (match_operand 0 "register_operand" "")
12472         (const_string "2")
12473         (const_string "*")))])
12474
12475 (define_insn "*lshrqi3_1"
12476   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12477         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12478                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12479    (clobber (reg:CC FLAGS_REG))]
12480   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12481   "@
12482    shr{b}\t{%2, %0|%0, %2}
12483    shr{b}\t{%b2, %0|%0, %b2}"
12484   [(set_attr "type" "ishift")
12485    (set_attr "mode" "QI")])
12486
12487 (define_insn "*lshrqi3_1_slp"
12488   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12489         (lshiftrt:QI (match_dup 0)
12490                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12491    (clobber (reg:CC FLAGS_REG))]
12492   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12493    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12494   "@
12495    shr{b}\t{%1, %0|%0, %1}
12496    shr{b}\t{%b1, %0|%0, %b1}"
12497   [(set_attr "type" "ishift1")
12498    (set_attr "mode" "QI")])
12499
12500 ;; This pattern can't accept a variable shift count, since shifts by
12501 ;; zero don't affect the flags.  We assume that shifts by constant
12502 ;; zero are optimized away.
12503 (define_insn "*lshrqi2_one_bit_cmp"
12504   [(set (reg FLAGS_REG)
12505         (compare
12506           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12507                        (match_operand:QI 2 "const1_operand" ""))
12508           (const_int 0)))
12509    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12510         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12511   "ix86_match_ccmode (insn, CCGOCmode)
12512    && (TARGET_SHIFT1 || optimize_size)
12513    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12514   "shr{b}\t%0"
12515   [(set_attr "type" "ishift")
12516    (set (attr "length")
12517      (if_then_else (match_operand:SI 0 "register_operand" "")
12518         (const_string "2")
12519         (const_string "*")))])
12520
12521 (define_insn "*lshrqi2_one_bit_cconly"
12522   [(set (reg FLAGS_REG)
12523         (compare
12524           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12525                        (match_operand:QI 2 "const1_operand" ""))
12526           (const_int 0)))
12527    (clobber (match_scratch:QI 0 "=q"))]
12528   "ix86_match_ccmode (insn, CCGOCmode)
12529    && (TARGET_SHIFT1 || optimize_size)
12530    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12531   "shr{b}\t%0"
12532   [(set_attr "type" "ishift")
12533    (set_attr "length" "2")])
12534
12535 ;; This pattern can't accept a variable shift count, since shifts by
12536 ;; zero don't affect the flags.  We assume that shifts by constant
12537 ;; zero are optimized away.
12538 (define_insn "*lshrqi2_cmp"
12539   [(set (reg FLAGS_REG)
12540         (compare
12541           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12542                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12543           (const_int 0)))
12544    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12545         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12546   "ix86_match_ccmode (insn, CCGOCmode)
12547    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12548    && (optimize_size
12549        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12550   "shr{b}\t{%2, %0|%0, %2}"
12551   [(set_attr "type" "ishift")
12552    (set_attr "mode" "QI")])
12553
12554 (define_insn "*lshrqi2_cconly"
12555   [(set (reg FLAGS_REG)
12556         (compare
12557           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12558                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12559           (const_int 0)))
12560    (clobber (match_scratch:QI 0 "=q"))]
12561   "ix86_match_ccmode (insn, CCGOCmode)
12562    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12563    && (optimize_size
12564        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12565   "shr{b}\t{%2, %0|%0, %2}"
12566   [(set_attr "type" "ishift")
12567    (set_attr "mode" "QI")])
12568 \f
12569 ;; Rotate instructions
12570
12571 (define_expand "rotldi3"
12572   [(set (match_operand:DI 0 "shiftdi_operand" "")
12573         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12574                    (match_operand:QI 2 "nonmemory_operand" "")))
12575    (clobber (reg:CC FLAGS_REG))]
12576  ""
12577 {
12578   if (TARGET_64BIT)
12579     {
12580       ix86_expand_binary_operator (ROTATE, DImode, operands);
12581       DONE;
12582     }
12583   if (!const_1_to_31_operand (operands[2], VOIDmode))
12584     FAIL;
12585   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12586   DONE;
12587 })
12588
12589 ;; Implement rotation using two double-precision shift instructions
12590 ;; and a scratch register.
12591 (define_insn_and_split "ix86_rotldi3"
12592  [(set (match_operand:DI 0 "register_operand" "=r")
12593        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12594                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12595   (clobber (reg:CC FLAGS_REG))
12596   (clobber (match_scratch:SI 3 "=&r"))]
12597  "!TARGET_64BIT"
12598  ""
12599  "&& reload_completed"
12600  [(set (match_dup 3) (match_dup 4))
12601   (parallel
12602    [(set (match_dup 4)
12603          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12604                  (lshiftrt:SI (match_dup 5)
12605                               (minus:QI (const_int 32) (match_dup 2)))))
12606     (clobber (reg:CC FLAGS_REG))])
12607   (parallel
12608    [(set (match_dup 5)
12609          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12610                  (lshiftrt:SI (match_dup 3)
12611                               (minus:QI (const_int 32) (match_dup 2)))))
12612     (clobber (reg:CC FLAGS_REG))])]
12613  "split_di (operands, 1, operands + 4, operands + 5);")
12614
12615 (define_insn "*rotlsi3_1_one_bit_rex64"
12616   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12617         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12618                    (match_operand:QI 2 "const1_operand" "")))
12619    (clobber (reg:CC FLAGS_REG))]
12620   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12621    && (TARGET_SHIFT1 || optimize_size)"
12622   "rol{q}\t%0"
12623   [(set_attr "type" "rotate")
12624    (set (attr "length")
12625      (if_then_else (match_operand:DI 0 "register_operand" "")
12626         (const_string "2")
12627         (const_string "*")))])
12628
12629 (define_insn "*rotldi3_1_rex64"
12630   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12631         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12632                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12633    (clobber (reg:CC FLAGS_REG))]
12634   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12635   "@
12636    rol{q}\t{%2, %0|%0, %2}
12637    rol{q}\t{%b2, %0|%0, %b2}"
12638   [(set_attr "type" "rotate")
12639    (set_attr "mode" "DI")])
12640
12641 (define_expand "rotlsi3"
12642   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12643         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12644                    (match_operand:QI 2 "nonmemory_operand" "")))
12645    (clobber (reg:CC FLAGS_REG))]
12646   ""
12647   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12648
12649 (define_insn "*rotlsi3_1_one_bit"
12650   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12651         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12652                    (match_operand:QI 2 "const1_operand" "")))
12653    (clobber (reg:CC FLAGS_REG))]
12654   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12655    && (TARGET_SHIFT1 || optimize_size)"
12656   "rol{l}\t%0"
12657   [(set_attr "type" "rotate")
12658    (set (attr "length")
12659      (if_then_else (match_operand:SI 0 "register_operand" "")
12660         (const_string "2")
12661         (const_string "*")))])
12662
12663 (define_insn "*rotlsi3_1_one_bit_zext"
12664   [(set (match_operand:DI 0 "register_operand" "=r")
12665         (zero_extend:DI
12666           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12667                      (match_operand:QI 2 "const1_operand" ""))))
12668    (clobber (reg:CC FLAGS_REG))]
12669   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12670    && (TARGET_SHIFT1 || optimize_size)"
12671   "rol{l}\t%k0"
12672   [(set_attr "type" "rotate")
12673    (set_attr "length" "2")])
12674
12675 (define_insn "*rotlsi3_1"
12676   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12677         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12678                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12679    (clobber (reg:CC FLAGS_REG))]
12680   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12681   "@
12682    rol{l}\t{%2, %0|%0, %2}
12683    rol{l}\t{%b2, %0|%0, %b2}"
12684   [(set_attr "type" "rotate")
12685    (set_attr "mode" "SI")])
12686
12687 (define_insn "*rotlsi3_1_zext"
12688   [(set (match_operand:DI 0 "register_operand" "=r,r")
12689         (zero_extend:DI
12690           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12691                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12692    (clobber (reg:CC FLAGS_REG))]
12693   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12694   "@
12695    rol{l}\t{%2, %k0|%k0, %2}
12696    rol{l}\t{%b2, %k0|%k0, %b2}"
12697   [(set_attr "type" "rotate")
12698    (set_attr "mode" "SI")])
12699
12700 (define_expand "rotlhi3"
12701   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12702         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12703                    (match_operand:QI 2 "nonmemory_operand" "")))
12704    (clobber (reg:CC FLAGS_REG))]
12705   "TARGET_HIMODE_MATH"
12706   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12707
12708 (define_insn "*rotlhi3_1_one_bit"
12709   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12710         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12711                    (match_operand:QI 2 "const1_operand" "")))
12712    (clobber (reg:CC FLAGS_REG))]
12713   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12714    && (TARGET_SHIFT1 || optimize_size)"
12715   "rol{w}\t%0"
12716   [(set_attr "type" "rotate")
12717    (set (attr "length")
12718      (if_then_else (match_operand 0 "register_operand" "")
12719         (const_string "2")
12720         (const_string "*")))])
12721
12722 (define_insn "*rotlhi3_1"
12723   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12724         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12725                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12726    (clobber (reg:CC FLAGS_REG))]
12727   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12728   "@
12729    rol{w}\t{%2, %0|%0, %2}
12730    rol{w}\t{%b2, %0|%0, %b2}"
12731   [(set_attr "type" "rotate")
12732    (set_attr "mode" "HI")])
12733
12734 (define_split
12735  [(set (match_operand:HI 0 "register_operand" "")
12736        (rotate:HI (match_dup 0) (const_int 8)))
12737   (clobber (reg:CC FLAGS_REG))]
12738  "reload_completed"
12739  [(parallel [(set (strict_low_part (match_dup 0))
12740                   (bswap:HI (match_dup 0)))
12741              (clobber (reg:CC FLAGS_REG))])]
12742  "")
12743
12744 (define_expand "rotlqi3"
12745   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12746         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12747                    (match_operand:QI 2 "nonmemory_operand" "")))
12748    (clobber (reg:CC FLAGS_REG))]
12749   "TARGET_QIMODE_MATH"
12750   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12751
12752 (define_insn "*rotlqi3_1_one_bit_slp"
12753   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12754         (rotate:QI (match_dup 0)
12755                    (match_operand:QI 1 "const1_operand" "")))
12756    (clobber (reg:CC FLAGS_REG))]
12757   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12758    && (TARGET_SHIFT1 || optimize_size)"
12759   "rol{b}\t%0"
12760   [(set_attr "type" "rotate1")
12761    (set (attr "length")
12762      (if_then_else (match_operand 0 "register_operand" "")
12763         (const_string "2")
12764         (const_string "*")))])
12765
12766 (define_insn "*rotlqi3_1_one_bit"
12767   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12768         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12769                    (match_operand:QI 2 "const1_operand" "")))
12770    (clobber (reg:CC FLAGS_REG))]
12771   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12772    && (TARGET_SHIFT1 || optimize_size)"
12773   "rol{b}\t%0"
12774   [(set_attr "type" "rotate")
12775    (set (attr "length")
12776      (if_then_else (match_operand 0 "register_operand" "")
12777         (const_string "2")
12778         (const_string "*")))])
12779
12780 (define_insn "*rotlqi3_1_slp"
12781   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12782         (rotate:QI (match_dup 0)
12783                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12784    (clobber (reg:CC FLAGS_REG))]
12785   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12786    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12787   "@
12788    rol{b}\t{%1, %0|%0, %1}
12789    rol{b}\t{%b1, %0|%0, %b1}"
12790   [(set_attr "type" "rotate1")
12791    (set_attr "mode" "QI")])
12792
12793 (define_insn "*rotlqi3_1"
12794   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12795         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12796                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12797    (clobber (reg:CC FLAGS_REG))]
12798   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12799   "@
12800    rol{b}\t{%2, %0|%0, %2}
12801    rol{b}\t{%b2, %0|%0, %b2}"
12802   [(set_attr "type" "rotate")
12803    (set_attr "mode" "QI")])
12804
12805 (define_expand "rotrdi3"
12806   [(set (match_operand:DI 0 "shiftdi_operand" "")
12807         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12808                    (match_operand:QI 2 "nonmemory_operand" "")))
12809    (clobber (reg:CC FLAGS_REG))]
12810  ""
12811 {
12812   if (TARGET_64BIT)
12813     {
12814       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12815       DONE;
12816     }
12817   if (!const_1_to_31_operand (operands[2], VOIDmode))
12818     FAIL;
12819   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12820   DONE;
12821 })
12822
12823 ;; Implement rotation using two double-precision shift instructions
12824 ;; and a scratch register.
12825 (define_insn_and_split "ix86_rotrdi3"
12826  [(set (match_operand:DI 0 "register_operand" "=r")
12827        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12828                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12829   (clobber (reg:CC FLAGS_REG))
12830   (clobber (match_scratch:SI 3 "=&r"))]
12831  "!TARGET_64BIT"
12832  ""
12833  "&& reload_completed"
12834  [(set (match_dup 3) (match_dup 4))
12835   (parallel
12836    [(set (match_dup 4)
12837          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12838                  (ashift:SI (match_dup 5)
12839                             (minus:QI (const_int 32) (match_dup 2)))))
12840     (clobber (reg:CC FLAGS_REG))])
12841   (parallel
12842    [(set (match_dup 5)
12843          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12844                  (ashift:SI (match_dup 3)
12845                             (minus:QI (const_int 32) (match_dup 2)))))
12846     (clobber (reg:CC FLAGS_REG))])]
12847  "split_di (operands, 1, operands + 4, operands + 5);")
12848
12849 (define_insn "*rotrdi3_1_one_bit_rex64"
12850   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12851         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12852                      (match_operand:QI 2 "const1_operand" "")))
12853    (clobber (reg:CC FLAGS_REG))]
12854   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12855    && (TARGET_SHIFT1 || optimize_size)"
12856   "ror{q}\t%0"
12857   [(set_attr "type" "rotate")
12858    (set (attr "length")
12859      (if_then_else (match_operand:DI 0 "register_operand" "")
12860         (const_string "2")
12861         (const_string "*")))])
12862
12863 (define_insn "*rotrdi3_1_rex64"
12864   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12865         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12866                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12867    (clobber (reg:CC FLAGS_REG))]
12868   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12869   "@
12870    ror{q}\t{%2, %0|%0, %2}
12871    ror{q}\t{%b2, %0|%0, %b2}"
12872   [(set_attr "type" "rotate")
12873    (set_attr "mode" "DI")])
12874
12875 (define_expand "rotrsi3"
12876   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12877         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12878                      (match_operand:QI 2 "nonmemory_operand" "")))
12879    (clobber (reg:CC FLAGS_REG))]
12880   ""
12881   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12882
12883 (define_insn "*rotrsi3_1_one_bit"
12884   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12885         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12886                      (match_operand:QI 2 "const1_operand" "")))
12887    (clobber (reg:CC FLAGS_REG))]
12888   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12889    && (TARGET_SHIFT1 || optimize_size)"
12890   "ror{l}\t%0"
12891   [(set_attr "type" "rotate")
12892    (set (attr "length")
12893      (if_then_else (match_operand:SI 0 "register_operand" "")
12894         (const_string "2")
12895         (const_string "*")))])
12896
12897 (define_insn "*rotrsi3_1_one_bit_zext"
12898   [(set (match_operand:DI 0 "register_operand" "=r")
12899         (zero_extend:DI
12900           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12901                        (match_operand:QI 2 "const1_operand" ""))))
12902    (clobber (reg:CC FLAGS_REG))]
12903   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12904    && (TARGET_SHIFT1 || optimize_size)"
12905   "ror{l}\t%k0"
12906   [(set_attr "type" "rotate")
12907    (set (attr "length")
12908      (if_then_else (match_operand:SI 0 "register_operand" "")
12909         (const_string "2")
12910         (const_string "*")))])
12911
12912 (define_insn "*rotrsi3_1"
12913   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12914         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12915                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12916    (clobber (reg:CC FLAGS_REG))]
12917   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12918   "@
12919    ror{l}\t{%2, %0|%0, %2}
12920    ror{l}\t{%b2, %0|%0, %b2}"
12921   [(set_attr "type" "rotate")
12922    (set_attr "mode" "SI")])
12923
12924 (define_insn "*rotrsi3_1_zext"
12925   [(set (match_operand:DI 0 "register_operand" "=r,r")
12926         (zero_extend:DI
12927           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12928                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12929    (clobber (reg:CC FLAGS_REG))]
12930   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12931   "@
12932    ror{l}\t{%2, %k0|%k0, %2}
12933    ror{l}\t{%b2, %k0|%k0, %b2}"
12934   [(set_attr "type" "rotate")
12935    (set_attr "mode" "SI")])
12936
12937 (define_expand "rotrhi3"
12938   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12939         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12940                      (match_operand:QI 2 "nonmemory_operand" "")))
12941    (clobber (reg:CC FLAGS_REG))]
12942   "TARGET_HIMODE_MATH"
12943   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12944
12945 (define_insn "*rotrhi3_one_bit"
12946   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12947         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12948                      (match_operand:QI 2 "const1_operand" "")))
12949    (clobber (reg:CC FLAGS_REG))]
12950   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12951    && (TARGET_SHIFT1 || optimize_size)"
12952   "ror{w}\t%0"
12953   [(set_attr "type" "rotate")
12954    (set (attr "length")
12955      (if_then_else (match_operand 0 "register_operand" "")
12956         (const_string "2")
12957         (const_string "*")))])
12958
12959 (define_insn "*rotrhi3_1"
12960   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12961         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12962                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12963    (clobber (reg:CC FLAGS_REG))]
12964   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12965   "@
12966    ror{w}\t{%2, %0|%0, %2}
12967    ror{w}\t{%b2, %0|%0, %b2}"
12968   [(set_attr "type" "rotate")
12969    (set_attr "mode" "HI")])
12970
12971 (define_split
12972  [(set (match_operand:HI 0 "register_operand" "")
12973        (rotatert:HI (match_dup 0) (const_int 8)))
12974   (clobber (reg:CC FLAGS_REG))]
12975  "reload_completed"
12976  [(parallel [(set (strict_low_part (match_dup 0))
12977                   (bswap:HI (match_dup 0)))
12978              (clobber (reg:CC FLAGS_REG))])]
12979  "")
12980
12981 (define_expand "rotrqi3"
12982   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12983         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12984                      (match_operand:QI 2 "nonmemory_operand" "")))
12985    (clobber (reg:CC FLAGS_REG))]
12986   "TARGET_QIMODE_MATH"
12987   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12988
12989 (define_insn "*rotrqi3_1_one_bit"
12990   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12991         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12992                      (match_operand:QI 2 "const1_operand" "")))
12993    (clobber (reg:CC FLAGS_REG))]
12994   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12995    && (TARGET_SHIFT1 || optimize_size)"
12996   "ror{b}\t%0"
12997   [(set_attr "type" "rotate")
12998    (set (attr "length")
12999      (if_then_else (match_operand 0 "register_operand" "")
13000         (const_string "2")
13001         (const_string "*")))])
13002
13003 (define_insn "*rotrqi3_1_one_bit_slp"
13004   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13005         (rotatert:QI (match_dup 0)
13006                      (match_operand:QI 1 "const1_operand" "")))
13007    (clobber (reg:CC FLAGS_REG))]
13008   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13009    && (TARGET_SHIFT1 || optimize_size)"
13010   "ror{b}\t%0"
13011   [(set_attr "type" "rotate1")
13012    (set (attr "length")
13013      (if_then_else (match_operand 0 "register_operand" "")
13014         (const_string "2")
13015         (const_string "*")))])
13016
13017 (define_insn "*rotrqi3_1"
13018   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13019         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13020                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13021    (clobber (reg:CC FLAGS_REG))]
13022   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13023   "@
13024    ror{b}\t{%2, %0|%0, %2}
13025    ror{b}\t{%b2, %0|%0, %b2}"
13026   [(set_attr "type" "rotate")
13027    (set_attr "mode" "QI")])
13028
13029 (define_insn "*rotrqi3_1_slp"
13030   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13031         (rotatert:QI (match_dup 0)
13032                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13033    (clobber (reg:CC FLAGS_REG))]
13034   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13035    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13036   "@
13037    ror{b}\t{%1, %0|%0, %1}
13038    ror{b}\t{%b1, %0|%0, %b1}"
13039   [(set_attr "type" "rotate1")
13040    (set_attr "mode" "QI")])
13041 \f
13042 ;; Bit set / bit test instructions
13043
13044 (define_expand "extv"
13045   [(set (match_operand:SI 0 "register_operand" "")
13046         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13047                          (match_operand:SI 2 "const8_operand" "")
13048                          (match_operand:SI 3 "const8_operand" "")))]
13049   ""
13050 {
13051   /* Handle extractions from %ah et al.  */
13052   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13053     FAIL;
13054
13055   /* From mips.md: extract_bit_field doesn't verify that our source
13056      matches the predicate, so check it again here.  */
13057   if (! ext_register_operand (operands[1], VOIDmode))
13058     FAIL;
13059 })
13060
13061 (define_expand "extzv"
13062   [(set (match_operand:SI 0 "register_operand" "")
13063         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13064                          (match_operand:SI 2 "const8_operand" "")
13065                          (match_operand:SI 3 "const8_operand" "")))]
13066   ""
13067 {
13068   /* Handle extractions from %ah et al.  */
13069   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13070     FAIL;
13071
13072   /* From mips.md: extract_bit_field doesn't verify that our source
13073      matches the predicate, so check it again here.  */
13074   if (! ext_register_operand (operands[1], VOIDmode))
13075     FAIL;
13076 })
13077
13078 (define_expand "insv"
13079   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13080                       (match_operand 1 "const8_operand" "")
13081                       (match_operand 2 "const8_operand" ""))
13082         (match_operand 3 "register_operand" ""))]
13083   ""
13084 {
13085   /* Handle insertions to %ah et al.  */
13086   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13087     FAIL;
13088
13089   /* From mips.md: insert_bit_field doesn't verify that our source
13090      matches the predicate, so check it again here.  */
13091   if (! ext_register_operand (operands[0], VOIDmode))
13092     FAIL;
13093
13094   if (TARGET_64BIT)
13095     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13096   else
13097     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13098
13099   DONE;
13100 })
13101
13102 ;; %%% bts, btr, btc, bt.
13103 ;; In general these instructions are *slow* when applied to memory,
13104 ;; since they enforce atomic operation.  When applied to registers,
13105 ;; it depends on the cpu implementation.  They're never faster than
13106 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13107 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13108 ;; within the instruction itself, so operating on bits in the high
13109 ;; 32-bits of a register becomes easier.
13110 ;;
13111 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13112 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13113 ;; negdf respectively, so they can never be disabled entirely.
13114
13115 (define_insn "*btsq"
13116   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13117                          (const_int 1)
13118                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13119         (const_int 1))
13120    (clobber (reg:CC FLAGS_REG))]
13121   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13122   "bts{q} %1,%0"
13123   [(set_attr "type" "alu1")])
13124
13125 (define_insn "*btrq"
13126   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13127                          (const_int 1)
13128                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13129         (const_int 0))
13130    (clobber (reg:CC FLAGS_REG))]
13131   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13132   "btr{q} %1,%0"
13133   [(set_attr "type" "alu1")])
13134
13135 (define_insn "*btcq"
13136   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13137                          (const_int 1)
13138                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13139         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13140    (clobber (reg:CC FLAGS_REG))]
13141   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13142   "btc{q} %1,%0"
13143   [(set_attr "type" "alu1")])
13144
13145 ;; Allow Nocona to avoid these instructions if a register is available.
13146
13147 (define_peephole2
13148   [(match_scratch:DI 2 "r")
13149    (parallel [(set (zero_extract:DI
13150                      (match_operand:DI 0 "register_operand" "")
13151                      (const_int 1)
13152                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13153                    (const_int 1))
13154               (clobber (reg:CC FLAGS_REG))])]
13155   "TARGET_64BIT && !TARGET_USE_BT"
13156   [(const_int 0)]
13157 {
13158   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13159   rtx op1;
13160
13161   if (HOST_BITS_PER_WIDE_INT >= 64)
13162     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13163   else if (i < HOST_BITS_PER_WIDE_INT)
13164     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13165   else
13166     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13167
13168   op1 = immed_double_const (lo, hi, DImode);
13169   if (i >= 31)
13170     {
13171       emit_move_insn (operands[2], op1);
13172       op1 = operands[2];
13173     }
13174
13175   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13176   DONE;
13177 })
13178
13179 (define_peephole2
13180   [(match_scratch:DI 2 "r")
13181    (parallel [(set (zero_extract:DI
13182                      (match_operand:DI 0 "register_operand" "")
13183                      (const_int 1)
13184                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13185                    (const_int 0))
13186               (clobber (reg:CC FLAGS_REG))])]
13187   "TARGET_64BIT && !TARGET_USE_BT"
13188   [(const_int 0)]
13189 {
13190   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13191   rtx op1;
13192
13193   if (HOST_BITS_PER_WIDE_INT >= 64)
13194     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13195   else if (i < HOST_BITS_PER_WIDE_INT)
13196     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13197   else
13198     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13199
13200   op1 = immed_double_const (~lo, ~hi, DImode);
13201   if (i >= 32)
13202     {
13203       emit_move_insn (operands[2], op1);
13204       op1 = operands[2];
13205     }
13206
13207   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13208   DONE;
13209 })
13210
13211 (define_peephole2
13212   [(match_scratch:DI 2 "r")
13213    (parallel [(set (zero_extract:DI
13214                      (match_operand:DI 0 "register_operand" "")
13215                      (const_int 1)
13216                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13217               (not:DI (zero_extract:DI
13218                         (match_dup 0) (const_int 1) (match_dup 1))))
13219               (clobber (reg:CC FLAGS_REG))])]
13220   "TARGET_64BIT && !TARGET_USE_BT"
13221   [(const_int 0)]
13222 {
13223   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13224   rtx op1;
13225
13226   if (HOST_BITS_PER_WIDE_INT >= 64)
13227     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13228   else if (i < HOST_BITS_PER_WIDE_INT)
13229     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13230   else
13231     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13232
13233   op1 = immed_double_const (lo, hi, DImode);
13234   if (i >= 31)
13235     {
13236       emit_move_insn (operands[2], op1);
13237       op1 = operands[2];
13238     }
13239
13240   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13241   DONE;
13242 })
13243 \f
13244 ;; Store-flag instructions.
13245
13246 ;; For all sCOND expanders, also expand the compare or test insn that
13247 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13248
13249 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13250 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13251 ;; way, which can later delete the movzx if only QImode is needed.
13252
13253 (define_expand "seq"
13254   [(set (match_operand:QI 0 "register_operand" "")
13255         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13256   ""
13257   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13258
13259 (define_expand "sne"
13260   [(set (match_operand:QI 0 "register_operand" "")
13261         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13262   ""
13263   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13264
13265 (define_expand "sgt"
13266   [(set (match_operand:QI 0 "register_operand" "")
13267         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13268   ""
13269   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13270
13271 (define_expand "sgtu"
13272   [(set (match_operand:QI 0 "register_operand" "")
13273         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13274   ""
13275   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13276
13277 (define_expand "slt"
13278   [(set (match_operand:QI 0 "register_operand" "")
13279         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13280   ""
13281   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13282
13283 (define_expand "sltu"
13284   [(set (match_operand:QI 0 "register_operand" "")
13285         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13286   ""
13287   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13288
13289 (define_expand "sge"
13290   [(set (match_operand:QI 0 "register_operand" "")
13291         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13292   ""
13293   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13294
13295 (define_expand "sgeu"
13296   [(set (match_operand:QI 0 "register_operand" "")
13297         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13298   ""
13299   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13300
13301 (define_expand "sle"
13302   [(set (match_operand:QI 0 "register_operand" "")
13303         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13304   ""
13305   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13306
13307 (define_expand "sleu"
13308   [(set (match_operand:QI 0 "register_operand" "")
13309         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13310   ""
13311   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13312
13313 (define_expand "sunordered"
13314   [(set (match_operand:QI 0 "register_operand" "")
13315         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13316   "TARGET_80387 || TARGET_SSE"
13317   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13318
13319 (define_expand "sordered"
13320   [(set (match_operand:QI 0 "register_operand" "")
13321         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13322   "TARGET_80387"
13323   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13324
13325 (define_expand "suneq"
13326   [(set (match_operand:QI 0 "register_operand" "")
13327         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13328   "TARGET_80387 || TARGET_SSE"
13329   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13330
13331 (define_expand "sunge"
13332   [(set (match_operand:QI 0 "register_operand" "")
13333         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13334   "TARGET_80387 || TARGET_SSE"
13335   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13336
13337 (define_expand "sungt"
13338   [(set (match_operand:QI 0 "register_operand" "")
13339         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13340   "TARGET_80387 || TARGET_SSE"
13341   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13342
13343 (define_expand "sunle"
13344   [(set (match_operand:QI 0 "register_operand" "")
13345         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13346   "TARGET_80387 || TARGET_SSE"
13347   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13348
13349 (define_expand "sunlt"
13350   [(set (match_operand:QI 0 "register_operand" "")
13351         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13352   "TARGET_80387 || TARGET_SSE"
13353   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13354
13355 (define_expand "sltgt"
13356   [(set (match_operand:QI 0 "register_operand" "")
13357         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13358   "TARGET_80387 || TARGET_SSE"
13359   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13360
13361 (define_insn "*setcc_1"
13362   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13363         (match_operator:QI 1 "ix86_comparison_operator"
13364           [(reg FLAGS_REG) (const_int 0)]))]
13365   ""
13366   "set%C1\t%0"
13367   [(set_attr "type" "setcc")
13368    (set_attr "mode" "QI")])
13369
13370 (define_insn "*setcc_2"
13371   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13372         (match_operator:QI 1 "ix86_comparison_operator"
13373           [(reg FLAGS_REG) (const_int 0)]))]
13374   ""
13375   "set%C1\t%0"
13376   [(set_attr "type" "setcc")
13377    (set_attr "mode" "QI")])
13378
13379 ;; In general it is not safe to assume too much about CCmode registers,
13380 ;; so simplify-rtx stops when it sees a second one.  Under certain
13381 ;; conditions this is safe on x86, so help combine not create
13382 ;;
13383 ;;      seta    %al
13384 ;;      testb   %al, %al
13385 ;;      sete    %al
13386
13387 (define_split
13388   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13389         (ne: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   PUT_MODE (operands[1], QImode);
13396 })
13397
13398 (define_split
13399   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13400         (ne:QI (match_operator 1 "ix86_comparison_operator"
13401                  [(reg FLAGS_REG) (const_int 0)])
13402             (const_int 0)))]
13403   ""
13404   [(set (match_dup 0) (match_dup 1))]
13405 {
13406   PUT_MODE (operands[1], QImode);
13407 })
13408
13409 (define_split
13410   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13411         (eq:QI (match_operator 1 "ix86_comparison_operator"
13412                  [(reg FLAGS_REG) (const_int 0)])
13413             (const_int 0)))]
13414   ""
13415   [(set (match_dup 0) (match_dup 1))]
13416 {
13417   rtx new_op1 = copy_rtx (operands[1]);
13418   operands[1] = new_op1;
13419   PUT_MODE (new_op1, QImode);
13420   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13421                                              GET_MODE (XEXP (new_op1, 0))));
13422
13423   /* Make sure that (a) the CCmode we have for the flags is strong
13424      enough for the reversed compare or (b) we have a valid FP compare.  */
13425   if (! ix86_comparison_operator (new_op1, VOIDmode))
13426     FAIL;
13427 })
13428
13429 (define_split
13430   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13431         (eq:QI (match_operator 1 "ix86_comparison_operator"
13432                  [(reg FLAGS_REG) (const_int 0)])
13433             (const_int 0)))]
13434   ""
13435   [(set (match_dup 0) (match_dup 1))]
13436 {
13437   rtx new_op1 = copy_rtx (operands[1]);
13438   operands[1] = new_op1;
13439   PUT_MODE (new_op1, QImode);
13440   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13441                                              GET_MODE (XEXP (new_op1, 0))));
13442
13443   /* Make sure that (a) the CCmode we have for the flags is strong
13444      enough for the reversed compare or (b) we have a valid FP compare.  */
13445   if (! ix86_comparison_operator (new_op1, VOIDmode))
13446     FAIL;
13447 })
13448
13449 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13450 ;; subsequent logical operations are used to imitate conditional moves.
13451 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13452 ;; it directly.
13453
13454 (define_insn "*sse_setccsf"
13455   [(set (match_operand:SF 0 "register_operand" "=x")
13456         (match_operator:SF 1 "sse_comparison_operator"
13457           [(match_operand:SF 2 "register_operand" "0")
13458            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13459   "TARGET_SSE"
13460   "cmp%D1ss\t{%3, %0|%0, %3}"
13461   [(set_attr "type" "ssecmp")
13462    (set_attr "mode" "SF")])
13463
13464 (define_insn "*sse_setccdf"
13465   [(set (match_operand:DF 0 "register_operand" "=x")
13466         (match_operator:DF 1 "sse_comparison_operator"
13467           [(match_operand:DF 2 "register_operand" "0")
13468            (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13469   "TARGET_SSE2"
13470   "cmp%D1sd\t{%3, %0|%0, %3}"
13471   [(set_attr "type" "ssecmp")
13472    (set_attr "mode" "DF")])
13473 \f
13474 ;; Basic conditional jump instructions.
13475 ;; We ignore the overflow flag for signed branch instructions.
13476
13477 ;; For all bCOND expanders, also expand the compare or test insn that
13478 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13479
13480 (define_expand "beq"
13481   [(set (pc)
13482         (if_then_else (match_dup 1)
13483                       (label_ref (match_operand 0 "" ""))
13484                       (pc)))]
13485   ""
13486   "ix86_expand_branch (EQ, operands[0]); DONE;")
13487
13488 (define_expand "bne"
13489   [(set (pc)
13490         (if_then_else (match_dup 1)
13491                       (label_ref (match_operand 0 "" ""))
13492                       (pc)))]
13493   ""
13494   "ix86_expand_branch (NE, operands[0]); DONE;")
13495
13496 (define_expand "bgt"
13497   [(set (pc)
13498         (if_then_else (match_dup 1)
13499                       (label_ref (match_operand 0 "" ""))
13500                       (pc)))]
13501   ""
13502   "ix86_expand_branch (GT, operands[0]); DONE;")
13503
13504 (define_expand "bgtu"
13505   [(set (pc)
13506         (if_then_else (match_dup 1)
13507                       (label_ref (match_operand 0 "" ""))
13508                       (pc)))]
13509   ""
13510   "ix86_expand_branch (GTU, operands[0]); DONE;")
13511
13512 (define_expand "blt"
13513   [(set (pc)
13514         (if_then_else (match_dup 1)
13515                       (label_ref (match_operand 0 "" ""))
13516                       (pc)))]
13517   ""
13518   "ix86_expand_branch (LT, operands[0]); DONE;")
13519
13520 (define_expand "bltu"
13521   [(set (pc)
13522         (if_then_else (match_dup 1)
13523                       (label_ref (match_operand 0 "" ""))
13524                       (pc)))]
13525   ""
13526   "ix86_expand_branch (LTU, operands[0]); DONE;")
13527
13528 (define_expand "bge"
13529   [(set (pc)
13530         (if_then_else (match_dup 1)
13531                       (label_ref (match_operand 0 "" ""))
13532                       (pc)))]
13533   ""
13534   "ix86_expand_branch (GE, operands[0]); DONE;")
13535
13536 (define_expand "bgeu"
13537   [(set (pc)
13538         (if_then_else (match_dup 1)
13539                       (label_ref (match_operand 0 "" ""))
13540                       (pc)))]
13541   ""
13542   "ix86_expand_branch (GEU, operands[0]); DONE;")
13543
13544 (define_expand "ble"
13545   [(set (pc)
13546         (if_then_else (match_dup 1)
13547                       (label_ref (match_operand 0 "" ""))
13548                       (pc)))]
13549   ""
13550   "ix86_expand_branch (LE, operands[0]); DONE;")
13551
13552 (define_expand "bleu"
13553   [(set (pc)
13554         (if_then_else (match_dup 1)
13555                       (label_ref (match_operand 0 "" ""))
13556                       (pc)))]
13557   ""
13558   "ix86_expand_branch (LEU, operands[0]); DONE;")
13559
13560 (define_expand "bunordered"
13561   [(set (pc)
13562         (if_then_else (match_dup 1)
13563                       (label_ref (match_operand 0 "" ""))
13564                       (pc)))]
13565   "TARGET_80387 || TARGET_SSE_MATH"
13566   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13567
13568 (define_expand "bordered"
13569   [(set (pc)
13570         (if_then_else (match_dup 1)
13571                       (label_ref (match_operand 0 "" ""))
13572                       (pc)))]
13573   "TARGET_80387 || TARGET_SSE_MATH"
13574   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13575
13576 (define_expand "buneq"
13577   [(set (pc)
13578         (if_then_else (match_dup 1)
13579                       (label_ref (match_operand 0 "" ""))
13580                       (pc)))]
13581   "TARGET_80387 || TARGET_SSE_MATH"
13582   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13583
13584 (define_expand "bunge"
13585   [(set (pc)
13586         (if_then_else (match_dup 1)
13587                       (label_ref (match_operand 0 "" ""))
13588                       (pc)))]
13589   "TARGET_80387 || TARGET_SSE_MATH"
13590   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13591
13592 (define_expand "bungt"
13593   [(set (pc)
13594         (if_then_else (match_dup 1)
13595                       (label_ref (match_operand 0 "" ""))
13596                       (pc)))]
13597   "TARGET_80387 || TARGET_SSE_MATH"
13598   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13599
13600 (define_expand "bunle"
13601   [(set (pc)
13602         (if_then_else (match_dup 1)
13603                       (label_ref (match_operand 0 "" ""))
13604                       (pc)))]
13605   "TARGET_80387 || TARGET_SSE_MATH"
13606   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13607
13608 (define_expand "bunlt"
13609   [(set (pc)
13610         (if_then_else (match_dup 1)
13611                       (label_ref (match_operand 0 "" ""))
13612                       (pc)))]
13613   "TARGET_80387 || TARGET_SSE_MATH"
13614   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13615
13616 (define_expand "bltgt"
13617   [(set (pc)
13618         (if_then_else (match_dup 1)
13619                       (label_ref (match_operand 0 "" ""))
13620                       (pc)))]
13621   "TARGET_80387 || TARGET_SSE_MATH"
13622   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13623
13624 (define_insn "*jcc_1"
13625   [(set (pc)
13626         (if_then_else (match_operator 1 "ix86_comparison_operator"
13627                                       [(reg FLAGS_REG) (const_int 0)])
13628                       (label_ref (match_operand 0 "" ""))
13629                       (pc)))]
13630   ""
13631   "%+j%C1\t%l0"
13632   [(set_attr "type" "ibr")
13633    (set_attr "modrm" "0")
13634    (set (attr "length")
13635            (if_then_else (and (ge (minus (match_dup 0) (pc))
13636                                   (const_int -126))
13637                               (lt (minus (match_dup 0) (pc))
13638                                   (const_int 128)))
13639              (const_int 2)
13640              (const_int 6)))])
13641
13642 (define_insn "*jcc_2"
13643   [(set (pc)
13644         (if_then_else (match_operator 1 "ix86_comparison_operator"
13645                                       [(reg FLAGS_REG) (const_int 0)])
13646                       (pc)
13647                       (label_ref (match_operand 0 "" ""))))]
13648   ""
13649   "%+j%c1\t%l0"
13650   [(set_attr "type" "ibr")
13651    (set_attr "modrm" "0")
13652    (set (attr "length")
13653            (if_then_else (and (ge (minus (match_dup 0) (pc))
13654                                   (const_int -126))
13655                               (lt (minus (match_dup 0) (pc))
13656                                   (const_int 128)))
13657              (const_int 2)
13658              (const_int 6)))])
13659
13660 ;; In general it is not safe to assume too much about CCmode registers,
13661 ;; so simplify-rtx stops when it sees a second one.  Under certain
13662 ;; conditions this is safe on x86, so help combine not create
13663 ;;
13664 ;;      seta    %al
13665 ;;      testb   %al, %al
13666 ;;      je      Lfoo
13667
13668 (define_split
13669   [(set (pc)
13670         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13671                                       [(reg FLAGS_REG) (const_int 0)])
13672                           (const_int 0))
13673                       (label_ref (match_operand 1 "" ""))
13674                       (pc)))]
13675   ""
13676   [(set (pc)
13677         (if_then_else (match_dup 0)
13678                       (label_ref (match_dup 1))
13679                       (pc)))]
13680 {
13681   PUT_MODE (operands[0], VOIDmode);
13682 })
13683
13684 (define_split
13685   [(set (pc)
13686         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13687                                       [(reg FLAGS_REG) (const_int 0)])
13688                           (const_int 0))
13689                       (label_ref (match_operand 1 "" ""))
13690                       (pc)))]
13691   ""
13692   [(set (pc)
13693         (if_then_else (match_dup 0)
13694                       (label_ref (match_dup 1))
13695                       (pc)))]
13696 {
13697   rtx new_op0 = copy_rtx (operands[0]);
13698   operands[0] = new_op0;
13699   PUT_MODE (new_op0, VOIDmode);
13700   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13701                                              GET_MODE (XEXP (new_op0, 0))));
13702
13703   /* Make sure that (a) the CCmode we have for the flags is strong
13704      enough for the reversed compare or (b) we have a valid FP compare.  */
13705   if (! ix86_comparison_operator (new_op0, VOIDmode))
13706     FAIL;
13707 })
13708
13709 ;; Define combination compare-and-branch fp compare instructions to use
13710 ;; during early optimization.  Splitting the operation apart early makes
13711 ;; for bad code when we want to reverse the operation.
13712
13713 (define_insn "*fp_jcc_1_mixed"
13714   [(set (pc)
13715         (if_then_else (match_operator 0 "comparison_operator"
13716                         [(match_operand 1 "register_operand" "f,x")
13717                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13718           (label_ref (match_operand 3 "" ""))
13719           (pc)))
13720    (clobber (reg:CCFP FPSR_REG))
13721    (clobber (reg:CCFP FLAGS_REG))]
13722   "TARGET_MIX_SSE_I387
13723    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13724    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13725    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13726   "#")
13727
13728 (define_insn "*fp_jcc_1_sse"
13729   [(set (pc)
13730         (if_then_else (match_operator 0 "comparison_operator"
13731                         [(match_operand 1 "register_operand" "x")
13732                          (match_operand 2 "nonimmediate_operand" "xm")])
13733           (label_ref (match_operand 3 "" ""))
13734           (pc)))
13735    (clobber (reg:CCFP FPSR_REG))
13736    (clobber (reg:CCFP FLAGS_REG))]
13737   "TARGET_SSE_MATH
13738    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13739    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13740    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13741   "#")
13742
13743 (define_insn "*fp_jcc_1_387"
13744   [(set (pc)
13745         (if_then_else (match_operator 0 "comparison_operator"
13746                         [(match_operand 1 "register_operand" "f")
13747                          (match_operand 2 "register_operand" "f")])
13748           (label_ref (match_operand 3 "" ""))
13749           (pc)))
13750    (clobber (reg:CCFP FPSR_REG))
13751    (clobber (reg:CCFP FLAGS_REG))]
13752   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13753    && TARGET_CMOVE
13754    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13755    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13756   "#")
13757
13758 (define_insn "*fp_jcc_2_mixed"
13759   [(set (pc)
13760         (if_then_else (match_operator 0 "comparison_operator"
13761                         [(match_operand 1 "register_operand" "f,x")
13762                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13763           (pc)
13764           (label_ref (match_operand 3 "" ""))))
13765    (clobber (reg:CCFP FPSR_REG))
13766    (clobber (reg:CCFP FLAGS_REG))]
13767   "TARGET_MIX_SSE_I387
13768    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13769    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13770    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13771   "#")
13772
13773 (define_insn "*fp_jcc_2_sse"
13774   [(set (pc)
13775         (if_then_else (match_operator 0 "comparison_operator"
13776                         [(match_operand 1 "register_operand" "x")
13777                          (match_operand 2 "nonimmediate_operand" "xm")])
13778           (pc)
13779           (label_ref (match_operand 3 "" ""))))
13780    (clobber (reg:CCFP FPSR_REG))
13781    (clobber (reg:CCFP FLAGS_REG))]
13782   "TARGET_SSE_MATH
13783    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13784    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13785    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13786   "#")
13787
13788 (define_insn "*fp_jcc_2_387"
13789   [(set (pc)
13790         (if_then_else (match_operator 0 "comparison_operator"
13791                         [(match_operand 1 "register_operand" "f")
13792                          (match_operand 2 "register_operand" "f")])
13793           (pc)
13794           (label_ref (match_operand 3 "" ""))))
13795    (clobber (reg:CCFP FPSR_REG))
13796    (clobber (reg:CCFP FLAGS_REG))]
13797   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13798    && TARGET_CMOVE
13799    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13800    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13801   "#")
13802
13803 (define_insn "*fp_jcc_3_387"
13804   [(set (pc)
13805         (if_then_else (match_operator 0 "comparison_operator"
13806                         [(match_operand 1 "register_operand" "f")
13807                          (match_operand 2 "nonimmediate_operand" "fm")])
13808           (label_ref (match_operand 3 "" ""))
13809           (pc)))
13810    (clobber (reg:CCFP FPSR_REG))
13811    (clobber (reg:CCFP FLAGS_REG))
13812    (clobber (match_scratch:HI 4 "=a"))]
13813   "TARGET_80387
13814    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13815    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13816    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13817    && SELECT_CC_MODE (GET_CODE (operands[0]),
13818                       operands[1], operands[2]) == CCFPmode
13819    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13820   "#")
13821
13822 (define_insn "*fp_jcc_4_387"
13823   [(set (pc)
13824         (if_then_else (match_operator 0 "comparison_operator"
13825                         [(match_operand 1 "register_operand" "f")
13826                          (match_operand 2 "nonimmediate_operand" "fm")])
13827           (pc)
13828           (label_ref (match_operand 3 "" ""))))
13829    (clobber (reg:CCFP FPSR_REG))
13830    (clobber (reg:CCFP FLAGS_REG))
13831    (clobber (match_scratch:HI 4 "=a"))]
13832   "TARGET_80387
13833    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13834    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13835    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13836    && SELECT_CC_MODE (GET_CODE (operands[0]),
13837                       operands[1], operands[2]) == CCFPmode
13838    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13839   "#")
13840
13841 (define_insn "*fp_jcc_5_387"
13842   [(set (pc)
13843         (if_then_else (match_operator 0 "comparison_operator"
13844                         [(match_operand 1 "register_operand" "f")
13845                          (match_operand 2 "register_operand" "f")])
13846           (label_ref (match_operand 3 "" ""))
13847           (pc)))
13848    (clobber (reg:CCFP FPSR_REG))
13849    (clobber (reg:CCFP FLAGS_REG))
13850    (clobber (match_scratch:HI 4 "=a"))]
13851   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13852    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13853    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13854   "#")
13855
13856 (define_insn "*fp_jcc_6_387"
13857   [(set (pc)
13858         (if_then_else (match_operator 0 "comparison_operator"
13859                         [(match_operand 1 "register_operand" "f")
13860                          (match_operand 2 "register_operand" "f")])
13861           (pc)
13862           (label_ref (match_operand 3 "" ""))))
13863    (clobber (reg:CCFP FPSR_REG))
13864    (clobber (reg:CCFP FLAGS_REG))
13865    (clobber (match_scratch:HI 4 "=a"))]
13866   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13867    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13868    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13869   "#")
13870
13871 (define_insn "*fp_jcc_7_387"
13872   [(set (pc)
13873         (if_then_else (match_operator 0 "comparison_operator"
13874                         [(match_operand 1 "register_operand" "f")
13875                          (match_operand 2 "const0_operand" "X")])
13876           (label_ref (match_operand 3 "" ""))
13877           (pc)))
13878    (clobber (reg:CCFP FPSR_REG))
13879    (clobber (reg:CCFP FLAGS_REG))
13880    (clobber (match_scratch:HI 4 "=a"))]
13881   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13882    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13883    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13884    && SELECT_CC_MODE (GET_CODE (operands[0]),
13885                       operands[1], operands[2]) == CCFPmode
13886    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13887   "#")
13888
13889 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13890 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13891 ;; with a precedence over other operators and is always put in the first
13892 ;; place. Swap condition and operands to match ficom instruction.
13893
13894 (define_insn "*fp_jcc_8<mode>_387"
13895   [(set (pc)
13896         (if_then_else (match_operator 0 "comparison_operator"
13897                         [(match_operator 1 "float_operator"
13898                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13899                            (match_operand 3 "register_operand" "f,f")])
13900           (label_ref (match_operand 4 "" ""))
13901           (pc)))
13902    (clobber (reg:CCFP FPSR_REG))
13903    (clobber (reg:CCFP FLAGS_REG))
13904    (clobber (match_scratch:HI 5 "=a,a"))]
13905   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
13906    && TARGET_USE_<MODE>MODE_FIOP
13907    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13908    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13909    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13910    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13911   "#")
13912
13913 (define_split
13914   [(set (pc)
13915         (if_then_else (match_operator 0 "comparison_operator"
13916                         [(match_operand 1 "register_operand" "")
13917                          (match_operand 2 "nonimmediate_operand" "")])
13918           (match_operand 3 "" "")
13919           (match_operand 4 "" "")))
13920    (clobber (reg:CCFP FPSR_REG))
13921    (clobber (reg:CCFP FLAGS_REG))]
13922   "reload_completed"
13923   [(const_int 0)]
13924 {
13925   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13926                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13927   DONE;
13928 })
13929
13930 (define_split
13931   [(set (pc)
13932         (if_then_else (match_operator 0 "comparison_operator"
13933                         [(match_operand 1 "register_operand" "")
13934                          (match_operand 2 "general_operand" "")])
13935           (match_operand 3 "" "")
13936           (match_operand 4 "" "")))
13937    (clobber (reg:CCFP FPSR_REG))
13938    (clobber (reg:CCFP FLAGS_REG))
13939    (clobber (match_scratch:HI 5 "=a"))]
13940   "reload_completed"
13941   [(const_int 0)]
13942 {
13943   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13944                         operands[3], operands[4], operands[5], NULL_RTX);
13945   DONE;
13946 })
13947
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 "memory_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] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13963   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13964                         operands[3], operands[7],
13965                         operands[4], operands[5], operands[6], NULL_RTX);
13966   DONE;
13967 })
13968
13969 ;; %%% Kill this when reload knows how to do it.
13970 (define_split
13971   [(set (pc)
13972         (if_then_else (match_operator 0 "comparison_operator"
13973                         [(match_operator 1 "float_operator"
13974                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13975                            (match_operand 3 "register_operand" "")])
13976           (match_operand 4 "" "")
13977           (match_operand 5 "" "")))
13978    (clobber (reg:CCFP FPSR_REG))
13979    (clobber (reg:CCFP FLAGS_REG))
13980    (clobber (match_scratch:HI 6 "=a"))]
13981   "reload_completed"
13982   [(const_int 0)]
13983 {
13984   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13985   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13986   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13987                         operands[3], operands[7],
13988                         operands[4], operands[5], operands[6], operands[2]);
13989   DONE;
13990 })
13991 \f
13992 ;; Unconditional and other jump instructions
13993
13994 (define_insn "jump"
13995   [(set (pc)
13996         (label_ref (match_operand 0 "" "")))]
13997   ""
13998   "jmp\t%l0"
13999   [(set_attr "type" "ibr")
14000    (set (attr "length")
14001            (if_then_else (and (ge (minus (match_dup 0) (pc))
14002                                   (const_int -126))
14003                               (lt (minus (match_dup 0) (pc))
14004                                   (const_int 128)))
14005              (const_int 2)
14006              (const_int 5)))
14007    (set_attr "modrm" "0")])
14008
14009 (define_expand "indirect_jump"
14010   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14011   ""
14012   "")
14013
14014 (define_insn "*indirect_jump"
14015   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14016   "!TARGET_64BIT"
14017   "jmp\t%A0"
14018   [(set_attr "type" "ibr")
14019    (set_attr "length_immediate" "0")])
14020
14021 (define_insn "*indirect_jump_rtx64"
14022   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14023   "TARGET_64BIT"
14024   "jmp\t%A0"
14025   [(set_attr "type" "ibr")
14026    (set_attr "length_immediate" "0")])
14027
14028 (define_expand "tablejump"
14029   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14030               (use (label_ref (match_operand 1 "" "")))])]
14031   ""
14032 {
14033   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14034      relative.  Convert the relative address to an absolute address.  */
14035   if (flag_pic)
14036     {
14037       rtx op0, op1;
14038       enum rtx_code code;
14039
14040       /* We can't use @GOTOFF for text labels on VxWorks;
14041          see gotoff_operand.  */
14042       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14043         {
14044           code = PLUS;
14045           op0 = operands[0];
14046           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14047         }
14048       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14049         {
14050           code = PLUS;
14051           op0 = operands[0];
14052           op1 = pic_offset_table_rtx;
14053         }
14054       else
14055         {
14056           code = MINUS;
14057           op0 = pic_offset_table_rtx;
14058           op1 = operands[0];
14059         }
14060
14061       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14062                                          OPTAB_DIRECT);
14063     }
14064 })
14065
14066 (define_insn "*tablejump_1"
14067   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14068    (use (label_ref (match_operand 1 "" "")))]
14069   "!TARGET_64BIT"
14070   "jmp\t%A0"
14071   [(set_attr "type" "ibr")
14072    (set_attr "length_immediate" "0")])
14073
14074 (define_insn "*tablejump_1_rtx64"
14075   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14076    (use (label_ref (match_operand 1 "" "")))]
14077   "TARGET_64BIT"
14078   "jmp\t%A0"
14079   [(set_attr "type" "ibr")
14080    (set_attr "length_immediate" "0")])
14081 \f
14082 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14083
14084 (define_peephole2
14085   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14086    (set (match_operand:QI 1 "register_operand" "")
14087         (match_operator:QI 2 "ix86_comparison_operator"
14088           [(reg FLAGS_REG) (const_int 0)]))
14089    (set (match_operand 3 "q_regs_operand" "")
14090         (zero_extend (match_dup 1)))]
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
14103 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14104
14105 (define_peephole2
14106   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14107    (set (match_operand:QI 1 "register_operand" "")
14108         (match_operator:QI 2 "ix86_comparison_operator"
14109           [(reg FLAGS_REG) (const_int 0)]))
14110    (parallel [(set (match_operand 3 "q_regs_operand" "")
14111                    (zero_extend (match_dup 1)))
14112               (clobber (reg:CC FLAGS_REG))])]
14113   "(peep2_reg_dead_p (3, operands[1])
14114     || operands_match_p (operands[1], operands[3]))
14115    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14116   [(set (match_dup 4) (match_dup 0))
14117    (set (strict_low_part (match_dup 5))
14118         (match_dup 2))]
14119 {
14120   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14121   operands[5] = gen_lowpart (QImode, operands[3]);
14122   ix86_expand_clear (operands[3]);
14123 })
14124 \f
14125 ;; Call instructions.
14126
14127 ;; The predicates normally associated with named expanders are not properly
14128 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14129 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14130
14131 ;; Call subroutine returning no value.
14132
14133 (define_expand "call_pop"
14134   [(parallel [(call (match_operand:QI 0 "" "")
14135                     (match_operand:SI 1 "" ""))
14136               (set (reg:SI SP_REG)
14137                    (plus:SI (reg:SI SP_REG)
14138                             (match_operand:SI 3 "" "")))])]
14139   "!TARGET_64BIT"
14140 {
14141   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14142   DONE;
14143 })
14144
14145 (define_insn "*call_pop_0"
14146   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14147          (match_operand:SI 1 "" ""))
14148    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14149                             (match_operand:SI 2 "immediate_operand" "")))]
14150   "!TARGET_64BIT"
14151 {
14152   if (SIBLING_CALL_P (insn))
14153     return "jmp\t%P0";
14154   else
14155     return "call\t%P0";
14156 }
14157   [(set_attr "type" "call")])
14158
14159 (define_insn "*call_pop_1"
14160   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14161          (match_operand:SI 1 "" ""))
14162    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14163                             (match_operand:SI 2 "immediate_operand" "i")))]
14164   "!TARGET_64BIT"
14165 {
14166   if (constant_call_address_operand (operands[0], Pmode))
14167     {
14168       if (SIBLING_CALL_P (insn))
14169         return "jmp\t%P0";
14170       else
14171         return "call\t%P0";
14172     }
14173   if (SIBLING_CALL_P (insn))
14174     return "jmp\t%A0";
14175   else
14176     return "call\t%A0";
14177 }
14178   [(set_attr "type" "call")])
14179
14180 (define_expand "call"
14181   [(call (match_operand:QI 0 "" "")
14182          (match_operand 1 "" ""))
14183    (use (match_operand 2 "" ""))]
14184   ""
14185 {
14186   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14187   DONE;
14188 })
14189
14190 (define_expand "sibcall"
14191   [(call (match_operand:QI 0 "" "")
14192          (match_operand 1 "" ""))
14193    (use (match_operand 2 "" ""))]
14194   ""
14195 {
14196   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14197   DONE;
14198 })
14199
14200 (define_insn "*call_0"
14201   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14202          (match_operand 1 "" ""))]
14203   ""
14204 {
14205   if (SIBLING_CALL_P (insn))
14206     return "jmp\t%P0";
14207   else
14208     return "call\t%P0";
14209 }
14210   [(set_attr "type" "call")])
14211
14212 (define_insn "*call_1"
14213   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14214          (match_operand 1 "" ""))]
14215   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14216 {
14217   if (constant_call_address_operand (operands[0], Pmode))
14218     return "call\t%P0";
14219   return "call\t%A0";
14220 }
14221   [(set_attr "type" "call")])
14222
14223 (define_insn "*sibcall_1"
14224   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14225          (match_operand 1 "" ""))]
14226   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14227 {
14228   if (constant_call_address_operand (operands[0], Pmode))
14229     return "jmp\t%P0";
14230   return "jmp\t%A0";
14231 }
14232   [(set_attr "type" "call")])
14233
14234 (define_insn "*call_1_rex64"
14235   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14236          (match_operand 1 "" ""))]
14237   "!SIBLING_CALL_P (insn) && TARGET_64BIT
14238    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14239 {
14240   if (constant_call_address_operand (operands[0], Pmode))
14241     return "call\t%P0";
14242   return "call\t%A0";
14243 }
14244   [(set_attr "type" "call")])
14245
14246 (define_insn "*call_1_rex64_large"
14247   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14248          (match_operand 1 "" ""))]
14249   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14250   "call\t%A0"
14251   [(set_attr "type" "call")])
14252
14253 (define_insn "*sibcall_1_rex64"
14254   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14255          (match_operand 1 "" ""))]
14256   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14257   "jmp\t%P0"
14258   [(set_attr "type" "call")])
14259
14260 (define_insn "*sibcall_1_rex64_v"
14261   [(call (mem:QI (reg:DI R11_REG))
14262          (match_operand 0 "" ""))]
14263   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14264   "jmp\t*%%r11"
14265   [(set_attr "type" "call")])
14266
14267
14268 ;; Call subroutine, returning value in operand 0
14269
14270 (define_expand "call_value_pop"
14271   [(parallel [(set (match_operand 0 "" "")
14272                    (call (match_operand:QI 1 "" "")
14273                          (match_operand:SI 2 "" "")))
14274               (set (reg:SI SP_REG)
14275                    (plus:SI (reg:SI SP_REG)
14276                             (match_operand:SI 4 "" "")))])]
14277   "!TARGET_64BIT"
14278 {
14279   ix86_expand_call (operands[0], operands[1], operands[2],
14280                     operands[3], operands[4], 0);
14281   DONE;
14282 })
14283
14284 (define_expand "call_value"
14285   [(set (match_operand 0 "" "")
14286         (call (match_operand:QI 1 "" "")
14287               (match_operand:SI 2 "" "")))
14288    (use (match_operand:SI 3 "" ""))]
14289   ;; Operand 2 not used on the i386.
14290   ""
14291 {
14292   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14293   DONE;
14294 })
14295
14296 (define_expand "sibcall_value"
14297   [(set (match_operand 0 "" "")
14298         (call (match_operand:QI 1 "" "")
14299               (match_operand:SI 2 "" "")))
14300    (use (match_operand:SI 3 "" ""))]
14301   ;; Operand 2 not used on the i386.
14302   ""
14303 {
14304   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14305   DONE;
14306 })
14307
14308 ;; Call subroutine returning any type.
14309
14310 (define_expand "untyped_call"
14311   [(parallel [(call (match_operand 0 "" "")
14312                     (const_int 0))
14313               (match_operand 1 "" "")
14314               (match_operand 2 "" "")])]
14315   ""
14316 {
14317   int i;
14318
14319   /* In order to give reg-stack an easier job in validating two
14320      coprocessor registers as containing a possible return value,
14321      simply pretend the untyped call returns a complex long double
14322      value.  */
14323
14324   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14325                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14326                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14327                     NULL, 0);
14328
14329   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14330     {
14331       rtx set = XVECEXP (operands[2], 0, i);
14332       emit_move_insn (SET_DEST (set), SET_SRC (set));
14333     }
14334
14335   /* The optimizer does not know that the call sets the function value
14336      registers we stored in the result block.  We avoid problems by
14337      claiming that all hard registers are used and clobbered at this
14338      point.  */
14339   emit_insn (gen_blockage (const0_rtx));
14340
14341   DONE;
14342 })
14343 \f
14344 ;; Prologue and epilogue instructions
14345
14346 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14347 ;; all of memory.  This blocks insns from being moved across this point.
14348
14349 (define_insn "blockage"
14350   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14351   ""
14352   ""
14353   [(set_attr "length" "0")])
14354
14355 ;; Insn emitted into the body of a function to return from a function.
14356 ;; This is only done if the function's epilogue is known to be simple.
14357 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14358
14359 (define_expand "return"
14360   [(return)]
14361   "ix86_can_use_return_insn_p ()"
14362 {
14363   if (current_function_pops_args)
14364     {
14365       rtx popc = GEN_INT (current_function_pops_args);
14366       emit_jump_insn (gen_return_pop_internal (popc));
14367       DONE;
14368     }
14369 })
14370
14371 (define_insn "return_internal"
14372   [(return)]
14373   "reload_completed"
14374   "ret"
14375   [(set_attr "length" "1")
14376    (set_attr "length_immediate" "0")
14377    (set_attr "modrm" "0")])
14378
14379 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14380 ;; instruction Athlon and K8 have.
14381
14382 (define_insn "return_internal_long"
14383   [(return)
14384    (unspec [(const_int 0)] UNSPEC_REP)]
14385   "reload_completed"
14386   "rep {;} ret"
14387   [(set_attr "length" "1")
14388    (set_attr "length_immediate" "0")
14389    (set_attr "prefix_rep" "1")
14390    (set_attr "modrm" "0")])
14391
14392 (define_insn "return_pop_internal"
14393   [(return)
14394    (use (match_operand:SI 0 "const_int_operand" ""))]
14395   "reload_completed"
14396   "ret\t%0"
14397   [(set_attr "length" "3")
14398    (set_attr "length_immediate" "2")
14399    (set_attr "modrm" "0")])
14400
14401 (define_insn "return_indirect_internal"
14402   [(return)
14403    (use (match_operand:SI 0 "register_operand" "r"))]
14404   "reload_completed"
14405   "jmp\t%A0"
14406   [(set_attr "type" "ibr")
14407    (set_attr "length_immediate" "0")])
14408
14409 (define_insn "nop"
14410   [(const_int 0)]
14411   ""
14412   "nop"
14413   [(set_attr "length" "1")
14414    (set_attr "length_immediate" "0")
14415    (set_attr "modrm" "0")])
14416
14417 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14418 ;; branch prediction penalty for the third jump in a 16-byte
14419 ;; block on K8.
14420
14421 (define_insn "align"
14422   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14423   ""
14424 {
14425 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14426   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14427 #else
14428   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14429      The align insn is used to avoid 3 jump instructions in the row to improve
14430      branch prediction and the benefits hardly outweigh the cost of extra 8
14431      nops on the average inserted by full alignment pseudo operation.  */
14432 #endif
14433   return "";
14434 }
14435   [(set_attr "length" "16")])
14436
14437 (define_expand "prologue"
14438   [(const_int 1)]
14439   ""
14440   "ix86_expand_prologue (); DONE;")
14441
14442 (define_insn "set_got"
14443   [(set (match_operand:SI 0 "register_operand" "=r")
14444         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14445    (clobber (reg:CC FLAGS_REG))]
14446   "!TARGET_64BIT"
14447   { return output_set_got (operands[0], NULL_RTX); }
14448   [(set_attr "type" "multi")
14449    (set_attr "length" "12")])
14450
14451 (define_insn "set_got_labelled"
14452   [(set (match_operand:SI 0 "register_operand" "=r")
14453         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14454          UNSPEC_SET_GOT))
14455    (clobber (reg:CC FLAGS_REG))]
14456   "!TARGET_64BIT"
14457   { return output_set_got (operands[0], operands[1]); }
14458   [(set_attr "type" "multi")
14459    (set_attr "length" "12")])
14460
14461 (define_insn "set_got_rex64"
14462   [(set (match_operand:DI 0 "register_operand" "=r")
14463         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14464   "TARGET_64BIT"
14465   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14466   [(set_attr "type" "lea")
14467    (set_attr "length" "6")])
14468
14469 (define_insn "set_rip_rex64"
14470   [(set (match_operand:DI 0 "register_operand" "=r")
14471         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14472   "TARGET_64BIT"
14473   "lea{q}\t%l1(%%rip), %0"
14474   [(set_attr "type" "lea")
14475    (set_attr "length" "6")])
14476
14477 (define_insn "set_got_offset_rex64"
14478   [(set (match_operand:DI 0 "register_operand" "=r")
14479         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
14480   "TARGET_64BIT"
14481   "movabs{q}\t$_GLOBAL_OFFSET_TABLE_-%l1, %0"
14482   [(set_attr "type" "imov")
14483    (set_attr "length" "11")])
14484
14485 (define_expand "epilogue"
14486   [(const_int 1)]
14487   ""
14488   "ix86_expand_epilogue (1); DONE;")
14489
14490 (define_expand "sibcall_epilogue"
14491   [(const_int 1)]
14492   ""
14493   "ix86_expand_epilogue (0); DONE;")
14494
14495 (define_expand "eh_return"
14496   [(use (match_operand 0 "register_operand" ""))]
14497   ""
14498 {
14499   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14500
14501   /* Tricky bit: we write the address of the handler to which we will
14502      be returning into someone else's stack frame, one word below the
14503      stack address we wish to restore.  */
14504   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14505   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14506   tmp = gen_rtx_MEM (Pmode, tmp);
14507   emit_move_insn (tmp, ra);
14508
14509   if (Pmode == SImode)
14510     emit_jump_insn (gen_eh_return_si (sa));
14511   else
14512     emit_jump_insn (gen_eh_return_di (sa));
14513   emit_barrier ();
14514   DONE;
14515 })
14516
14517 (define_insn_and_split "eh_return_si"
14518   [(set (pc)
14519         (unspec [(match_operand:SI 0 "register_operand" "c")]
14520                  UNSPEC_EH_RETURN))]
14521   "!TARGET_64BIT"
14522   "#"
14523   "reload_completed"
14524   [(const_int 1)]
14525   "ix86_expand_epilogue (2); DONE;")
14526
14527 (define_insn_and_split "eh_return_di"
14528   [(set (pc)
14529         (unspec [(match_operand:DI 0 "register_operand" "c")]
14530                  UNSPEC_EH_RETURN))]
14531   "TARGET_64BIT"
14532   "#"
14533   "reload_completed"
14534   [(const_int 1)]
14535   "ix86_expand_epilogue (2); DONE;")
14536
14537 (define_insn "leave"
14538   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14539    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14540    (clobber (mem:BLK (scratch)))]
14541   "!TARGET_64BIT"
14542   "leave"
14543   [(set_attr "type" "leave")])
14544
14545 (define_insn "leave_rex64"
14546   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14547    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14548    (clobber (mem:BLK (scratch)))]
14549   "TARGET_64BIT"
14550   "leave"
14551   [(set_attr "type" "leave")])
14552 \f
14553 (define_expand "ffssi2"
14554   [(parallel
14555      [(set (match_operand:SI 0 "register_operand" "")
14556            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14557       (clobber (match_scratch:SI 2 ""))
14558       (clobber (reg:CC FLAGS_REG))])]
14559   ""
14560   "")
14561
14562 (define_insn_and_split "*ffs_cmove"
14563   [(set (match_operand:SI 0 "register_operand" "=r")
14564         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14565    (clobber (match_scratch:SI 2 "=&r"))
14566    (clobber (reg:CC FLAGS_REG))]
14567   "TARGET_CMOVE"
14568   "#"
14569   "&& reload_completed"
14570   [(set (match_dup 2) (const_int -1))
14571    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14572               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14573    (set (match_dup 0) (if_then_else:SI
14574                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14575                         (match_dup 2)
14576                         (match_dup 0)))
14577    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14578               (clobber (reg:CC FLAGS_REG))])]
14579   "")
14580
14581 (define_insn_and_split "*ffs_no_cmove"
14582   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14583         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14584    (clobber (match_scratch:SI 2 "=&q"))
14585    (clobber (reg:CC FLAGS_REG))]
14586   ""
14587   "#"
14588   "reload_completed"
14589   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14590               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14591    (set (strict_low_part (match_dup 3))
14592         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14593    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14594               (clobber (reg:CC FLAGS_REG))])
14595    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14596               (clobber (reg:CC FLAGS_REG))])
14597    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14598               (clobber (reg:CC FLAGS_REG))])]
14599 {
14600   operands[3] = gen_lowpart (QImode, operands[2]);
14601   ix86_expand_clear (operands[2]);
14602 })
14603
14604 (define_insn "*ffssi_1"
14605   [(set (reg:CCZ FLAGS_REG)
14606         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14607                      (const_int 0)))
14608    (set (match_operand:SI 0 "register_operand" "=r")
14609         (ctz:SI (match_dup 1)))]
14610   ""
14611   "bsf{l}\t{%1, %0|%0, %1}"
14612   [(set_attr "prefix_0f" "1")])
14613
14614 (define_expand "ffsdi2"
14615   [(parallel
14616      [(set (match_operand:DI 0 "register_operand" "")
14617            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14618       (clobber (match_scratch:DI 2 ""))
14619       (clobber (reg:CC FLAGS_REG))])]
14620   "TARGET_64BIT && TARGET_CMOVE"
14621   "")
14622
14623 (define_insn_and_split "*ffs_rex64"
14624   [(set (match_operand:DI 0 "register_operand" "=r")
14625         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14626    (clobber (match_scratch:DI 2 "=&r"))
14627    (clobber (reg:CC FLAGS_REG))]
14628   "TARGET_64BIT && TARGET_CMOVE"
14629   "#"
14630   "&& reload_completed"
14631   [(set (match_dup 2) (const_int -1))
14632    (parallel [(set (reg:CCZ FLAGS_REG)
14633                    (compare:CCZ (match_dup 1) (const_int 0)))
14634               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14635    (set (match_dup 0) (if_then_else:DI
14636                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14637                         (match_dup 2)
14638                         (match_dup 0)))
14639    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14640               (clobber (reg:CC FLAGS_REG))])]
14641   "")
14642
14643 (define_insn "*ffsdi_1"
14644   [(set (reg:CCZ FLAGS_REG)
14645         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14646                      (const_int 0)))
14647    (set (match_operand:DI 0 "register_operand" "=r")
14648         (ctz:DI (match_dup 1)))]
14649   "TARGET_64BIT"
14650   "bsf{q}\t{%1, %0|%0, %1}"
14651   [(set_attr "prefix_0f" "1")])
14652
14653 (define_insn "ctzsi2"
14654   [(set (match_operand:SI 0 "register_operand" "=r")
14655         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14656    (clobber (reg:CC FLAGS_REG))]
14657   ""
14658   "bsf{l}\t{%1, %0|%0, %1}"
14659   [(set_attr "prefix_0f" "1")])
14660
14661 (define_insn "ctzdi2"
14662   [(set (match_operand:DI 0 "register_operand" "=r")
14663         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14664    (clobber (reg:CC FLAGS_REG))]
14665   "TARGET_64BIT"
14666   "bsf{q}\t{%1, %0|%0, %1}"
14667   [(set_attr "prefix_0f" "1")])
14668
14669 (define_expand "clzsi2"
14670   [(parallel
14671      [(set (match_operand:SI 0 "register_operand" "")
14672            (minus:SI (const_int 31)
14673                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14674       (clobber (reg:CC FLAGS_REG))])
14675    (parallel
14676      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14677       (clobber (reg:CC FLAGS_REG))])]
14678   ""
14679 {
14680   if (TARGET_ABM)
14681     {
14682       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14683       DONE;
14684     }
14685 })
14686
14687 (define_insn "clzsi2_abm"
14688   [(set (match_operand:SI 0 "register_operand" "=r")
14689         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14690    (clobber (reg:CC FLAGS_REG))]
14691   "TARGET_ABM"
14692   "lzcnt{l}\t{%1, %0|%0, %1}"
14693   [(set_attr "prefix_rep" "1")
14694    (set_attr "type" "bitmanip")
14695    (set_attr "mode" "SI")])
14696
14697 (define_insn "*bsr"
14698   [(set (match_operand:SI 0 "register_operand" "=r")
14699         (minus:SI (const_int 31)
14700                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14701    (clobber (reg:CC FLAGS_REG))]
14702   ""
14703   "bsr{l}\t{%1, %0|%0, %1}"
14704   [(set_attr "prefix_0f" "1")
14705    (set_attr "mode" "SI")])
14706
14707 (define_insn "popcountsi2"
14708   [(set (match_operand:SI 0 "register_operand" "=r")
14709         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14710    (clobber (reg:CC FLAGS_REG))]
14711   "TARGET_POPCNT"
14712   "popcnt{l}\t{%1, %0|%0, %1}"
14713   [(set_attr "prefix_rep" "1")
14714    (set_attr "type" "bitmanip")
14715    (set_attr "mode" "SI")])
14716
14717 (define_insn "*popcountsi2_cmp"
14718   [(set (reg FLAGS_REG)
14719         (compare
14720           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14721           (const_int 0)))
14722    (set (match_operand:SI 0 "register_operand" "=r")
14723         (popcount:SI (match_dup 1)))]
14724   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14725   "popcnt{l}\t{%1, %0|%0, %1}"
14726   [(set_attr "prefix_rep" "1")
14727    (set_attr "type" "bitmanip")
14728    (set_attr "mode" "SI")])
14729
14730 (define_insn "*popcountsi2_cmp_zext"
14731   [(set (reg FLAGS_REG)
14732         (compare
14733           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14734           (const_int 0)))
14735    (set (match_operand:DI 0 "register_operand" "=r")
14736         (zero_extend:DI(popcount:SI (match_dup 1))))]
14737   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14738   "popcnt{l}\t{%1, %0|%0, %1}"
14739   [(set_attr "prefix_rep" "1")
14740    (set_attr "type" "bitmanip")
14741    (set_attr "mode" "SI")])
14742
14743 (define_expand "bswapsi2"
14744   [(set (match_operand:SI 0 "register_operand" "")
14745         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
14746   ""
14747 {
14748   if (!TARGET_BSWAP)
14749     {
14750       rtx x = operands[0];
14751
14752       emit_move_insn (x, operands[1]);
14753       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14754       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14755       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14756       DONE;
14757     }
14758 })
14759
14760 (define_insn "*bswapsi_1"
14761   [(set (match_operand:SI 0 "register_operand" "=r")
14762         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
14763   "TARGET_BSWAP"
14764   "bswap\t%0"
14765   [(set_attr "prefix_0f" "1")
14766    (set_attr "length" "2")])
14767
14768 (define_insn "*bswaphi_lowpart_1"
14769   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14770         (bswap:HI (match_dup 0)))
14771    (clobber (reg:CC FLAGS_REG))]
14772   "TARGET_USE_XCHGB || optimize_size"
14773   "@
14774     xchg{b}\t{%h0, %b0|%b0, %h0}
14775     rol{w}\t{$8, %0|%0, 8}"
14776   [(set_attr "length" "2,4")
14777    (set_attr "mode" "QI,HI")])
14778
14779 (define_insn "bswaphi_lowpart"
14780   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
14781         (bswap:HI (match_dup 0)))
14782    (clobber (reg:CC FLAGS_REG))]
14783   ""
14784   "rol{w}\t{$8, %0|%0, 8}"
14785   [(set_attr "length" "4")
14786    (set_attr "mode" "HI")])
14787
14788 (define_insn "bswapdi2"
14789   [(set (match_operand:DI 0 "register_operand" "=r")
14790         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
14791   "TARGET_64BIT"
14792   "bswap\t%0"
14793   [(set_attr "prefix_0f" "1")
14794    (set_attr "length" "3")])
14795
14796 (define_expand "clzdi2"
14797   [(parallel
14798      [(set (match_operand:DI 0 "register_operand" "")
14799            (minus:DI (const_int 63)
14800                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14801       (clobber (reg:CC FLAGS_REG))])
14802    (parallel
14803      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14804       (clobber (reg:CC FLAGS_REG))])]
14805   "TARGET_64BIT"
14806 {
14807   if (TARGET_ABM)
14808     {
14809       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14810       DONE;
14811     }
14812 })
14813
14814 (define_insn "clzdi2_abm"
14815   [(set (match_operand:DI 0 "register_operand" "=r")
14816         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14817    (clobber (reg:CC FLAGS_REG))]
14818   "TARGET_64BIT && TARGET_ABM"
14819   "lzcnt{q}\t{%1, %0|%0, %1}"
14820   [(set_attr "prefix_rep" "1")
14821    (set_attr "type" "bitmanip")
14822    (set_attr "mode" "DI")])
14823
14824 (define_insn "*bsr_rex64"
14825   [(set (match_operand:DI 0 "register_operand" "=r")
14826         (minus:DI (const_int 63)
14827                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14828    (clobber (reg:CC FLAGS_REG))]
14829   "TARGET_64BIT"
14830   "bsr{q}\t{%1, %0|%0, %1}"
14831   [(set_attr "prefix_0f" "1")
14832    (set_attr "mode" "DI")])
14833
14834 (define_insn "popcountdi2"
14835   [(set (match_operand:DI 0 "register_operand" "=r")
14836         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14837    (clobber (reg:CC FLAGS_REG))]
14838   "TARGET_64BIT && TARGET_POPCNT"
14839   "popcnt{q}\t{%1, %0|%0, %1}"
14840   [(set_attr "prefix_rep" "1")
14841    (set_attr "type" "bitmanip")
14842    (set_attr "mode" "DI")])
14843
14844 (define_insn "*popcountdi2_cmp"
14845   [(set (reg FLAGS_REG)
14846         (compare
14847           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
14848           (const_int 0)))
14849    (set (match_operand:DI 0 "register_operand" "=r")
14850         (popcount:DI (match_dup 1)))]
14851   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14852   "popcnt{q}\t{%1, %0|%0, %1}"
14853   [(set_attr "prefix_rep" "1")
14854    (set_attr "type" "bitmanip")
14855    (set_attr "mode" "DI")])
14856
14857 (define_expand "clzhi2"
14858   [(parallel
14859      [(set (match_operand:HI 0 "register_operand" "")
14860            (minus:HI (const_int 15)
14861                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14862       (clobber (reg:CC FLAGS_REG))])
14863    (parallel
14864      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14865       (clobber (reg:CC FLAGS_REG))])]
14866   ""
14867 {
14868   if (TARGET_ABM)
14869     {
14870       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
14871       DONE;
14872     }
14873 })
14874
14875 (define_insn "clzhi2_abm"
14876   [(set (match_operand:HI 0 "register_operand" "=r")
14877         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14878    (clobber (reg:CC FLAGS_REG))]
14879   "TARGET_ABM"
14880   "lzcnt{w}\t{%1, %0|%0, %1}"
14881   [(set_attr "prefix_rep" "1")
14882    (set_attr "type" "bitmanip")
14883    (set_attr "mode" "HI")])
14884
14885 (define_insn "*bsrhi"
14886   [(set (match_operand:HI 0 "register_operand" "=r")
14887         (minus:HI (const_int 15)
14888                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14889    (clobber (reg:CC FLAGS_REG))]
14890   ""
14891   "bsr{w}\t{%1, %0|%0, %1}"
14892   [(set_attr "prefix_0f" "1")
14893    (set_attr "mode" "HI")])
14894
14895 (define_insn "popcounthi2"
14896   [(set (match_operand:HI 0 "register_operand" "=r")
14897         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14898    (clobber (reg:CC FLAGS_REG))]
14899   "TARGET_POPCNT"
14900   "popcnt{w}\t{%1, %0|%0, %1}"
14901   [(set_attr "prefix_rep" "1")
14902    (set_attr "type" "bitmanip")
14903    (set_attr "mode" "HI")])
14904
14905 (define_insn "*popcounthi2_cmp"
14906   [(set (reg FLAGS_REG)
14907         (compare
14908           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
14909           (const_int 0)))
14910    (set (match_operand:HI 0 "register_operand" "=r")
14911         (popcount:HI (match_dup 1)))]
14912   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14913   "popcnt{w}\t{%1, %0|%0, %1}"
14914   [(set_attr "prefix_rep" "1")
14915    (set_attr "type" "bitmanip")
14916    (set_attr "mode" "HI")])
14917
14918 (define_expand "paritydi2"
14919   [(set (match_operand:DI 0 "register_operand" "")
14920         (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
14921   "! TARGET_POPCNT"
14922 {
14923   rtx scratch = gen_reg_rtx (QImode);
14924   rtx cond;
14925
14926   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14927                                 NULL_RTX, operands[1]));
14928
14929   cond = gen_rtx_fmt_ee (ORDERED, QImode,
14930                          gen_rtx_REG (CCmode, FLAGS_REG),
14931                          const0_rtx);
14932   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14933
14934   if (TARGET_64BIT)
14935     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14936   else
14937     {
14938       rtx tmp = gen_reg_rtx (SImode);
14939
14940       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14941       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14942     }
14943   DONE;
14944 })
14945
14946 (define_insn_and_split "paritydi2_cmp"
14947   [(set (reg:CC FLAGS_REG)
14948         (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
14949    (clobber (match_scratch:DI 0 "=r,X"))
14950    (clobber (match_scratch:SI 1 "=r,r"))
14951    (clobber (match_scratch:HI 2 "=Q,Q"))]
14952   "! TARGET_POPCNT"
14953   "#"
14954   "&& reload_completed"
14955   [(parallel
14956      [(set (match_dup 1)
14957            (xor:SI (match_dup 1) (match_dup 4)))
14958       (clobber (reg:CC FLAGS_REG))])
14959    (parallel
14960      [(set (reg:CC FLAGS_REG)
14961            (parity:CC (match_dup 1)))
14962       (clobber (match_dup 1))
14963       (clobber (match_dup 2))])]
14964 {
14965   operands[4] = gen_lowpart (SImode, operands[3]);
14966
14967   if (MEM_P (operands[3]))
14968     emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
14969   else if (! TARGET_64BIT)
14970     operands[1] = gen_highpart (SImode, operands[3]);
14971   else
14972     {
14973       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14974       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14975     }
14976 })
14977
14978 (define_expand "paritysi2"
14979   [(set (match_operand:SI 0 "register_operand" "")
14980         (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
14981   "! TARGET_POPCNT"
14982 {
14983   rtx scratch = gen_reg_rtx (QImode);
14984   rtx cond;
14985
14986   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14987
14988   cond = gen_rtx_fmt_ee (ORDERED, QImode,
14989                          gen_rtx_REG (CCmode, FLAGS_REG),
14990                          const0_rtx);
14991   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14992
14993   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14994   DONE;
14995 })
14996
14997 (define_insn_and_split "paritysi2_cmp"
14998   [(set (reg:CC FLAGS_REG)
14999         (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
15000    (clobber (match_scratch:SI 0 "=r,X"))
15001    (clobber (match_scratch:HI 1 "=Q,Q"))]
15002   "! TARGET_POPCNT"
15003   "#"
15004   "&& reload_completed"
15005   [(parallel
15006      [(set (match_dup 1)
15007            (xor:HI (match_dup 1) (match_dup 3)))
15008       (clobber (reg:CC FLAGS_REG))])
15009    (parallel
15010      [(set (reg:CC FLAGS_REG)
15011            (parity:CC (match_dup 1)))
15012       (clobber (match_dup 1))])]
15013 {
15014   operands[3] = gen_lowpart (HImode, operands[2]);
15015
15016   if (MEM_P (operands[2]))
15017     emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15018   else
15019     {
15020       emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15021       emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15022     }
15023 })
15024
15025 (define_insn "*parityhi2_cmp"
15026   [(set (reg:CC FLAGS_REG)
15027         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15028    (clobber (match_scratch:HI 0 "=Q"))]
15029   "! TARGET_POPCNT"
15030   "xor{b}\t{%h0, %b0|%b0, %h0}"
15031   [(set_attr "length" "2")
15032    (set_attr "mode" "HI")])
15033
15034 (define_insn "*parityqi2_cmp"
15035   [(set (reg:CC FLAGS_REG)
15036         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15037   "! TARGET_POPCNT"
15038   "test{b}\t%0, %0"
15039   [(set_attr "length" "2")
15040    (set_attr "mode" "QI")])
15041 \f
15042 ;; Thread-local storage patterns for ELF.
15043 ;;
15044 ;; Note that these code sequences must appear exactly as shown
15045 ;; in order to allow linker relaxation.
15046
15047 (define_insn "*tls_global_dynamic_32_gnu"
15048   [(set (match_operand:SI 0 "register_operand" "=a")
15049         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15050                     (match_operand:SI 2 "tls_symbolic_operand" "")
15051                     (match_operand:SI 3 "call_insn_operand" "")]
15052                     UNSPEC_TLS_GD))
15053    (clobber (match_scratch:SI 4 "=d"))
15054    (clobber (match_scratch:SI 5 "=c"))
15055    (clobber (reg:CC FLAGS_REG))]
15056   "!TARGET_64BIT && TARGET_GNU_TLS"
15057   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15058   [(set_attr "type" "multi")
15059    (set_attr "length" "12")])
15060
15061 (define_insn "*tls_global_dynamic_32_sun"
15062   [(set (match_operand:SI 0 "register_operand" "=a")
15063         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15064                     (match_operand:SI 2 "tls_symbolic_operand" "")
15065                     (match_operand:SI 3 "call_insn_operand" "")]
15066                     UNSPEC_TLS_GD))
15067    (clobber (match_scratch:SI 4 "=d"))
15068    (clobber (match_scratch:SI 5 "=c"))
15069    (clobber (reg:CC FLAGS_REG))]
15070   "!TARGET_64BIT && TARGET_SUN_TLS"
15071   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15072         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15073   [(set_attr "type" "multi")
15074    (set_attr "length" "14")])
15075
15076 (define_expand "tls_global_dynamic_32"
15077   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15078                    (unspec:SI
15079                     [(match_dup 2)
15080                      (match_operand:SI 1 "tls_symbolic_operand" "")
15081                      (match_dup 3)]
15082                     UNSPEC_TLS_GD))
15083               (clobber (match_scratch:SI 4 ""))
15084               (clobber (match_scratch:SI 5 ""))
15085               (clobber (reg:CC FLAGS_REG))])]
15086   ""
15087 {
15088   if (flag_pic)
15089     operands[2] = pic_offset_table_rtx;
15090   else
15091     {
15092       operands[2] = gen_reg_rtx (Pmode);
15093       emit_insn (gen_set_got (operands[2]));
15094     }
15095   if (TARGET_GNU2_TLS)
15096     {
15097        emit_insn (gen_tls_dynamic_gnu2_32
15098                   (operands[0], operands[1], operands[2]));
15099        DONE;
15100     }
15101   operands[3] = ix86_tls_get_addr ();
15102 })
15103
15104 (define_insn "*tls_global_dynamic_64"
15105   [(set (match_operand:DI 0 "register_operand" "=a")
15106         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15107                  (match_operand:DI 3 "" "")))
15108    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15109               UNSPEC_TLS_GD)]
15110   "TARGET_64BIT"
15111   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15112   [(set_attr "type" "multi")
15113    (set_attr "length" "16")])
15114
15115 (define_expand "tls_global_dynamic_64"
15116   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15117                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15118               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15119                          UNSPEC_TLS_GD)])]
15120   ""
15121 {
15122   if (TARGET_GNU2_TLS)
15123     {
15124        emit_insn (gen_tls_dynamic_gnu2_64
15125                   (operands[0], operands[1]));
15126        DONE;
15127     }
15128   operands[2] = ix86_tls_get_addr ();
15129 })
15130
15131 (define_insn "*tls_local_dynamic_base_32_gnu"
15132   [(set (match_operand:SI 0 "register_operand" "=a")
15133         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15134                     (match_operand:SI 2 "call_insn_operand" "")]
15135                    UNSPEC_TLS_LD_BASE))
15136    (clobber (match_scratch:SI 3 "=d"))
15137    (clobber (match_scratch:SI 4 "=c"))
15138    (clobber (reg:CC FLAGS_REG))]
15139   "!TARGET_64BIT && TARGET_GNU_TLS"
15140   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15141   [(set_attr "type" "multi")
15142    (set_attr "length" "11")])
15143
15144 (define_insn "*tls_local_dynamic_base_32_sun"
15145   [(set (match_operand:SI 0 "register_operand" "=a")
15146         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15147                     (match_operand:SI 2 "call_insn_operand" "")]
15148                    UNSPEC_TLS_LD_BASE))
15149    (clobber (match_scratch:SI 3 "=d"))
15150    (clobber (match_scratch:SI 4 "=c"))
15151    (clobber (reg:CC FLAGS_REG))]
15152   "!TARGET_64BIT && TARGET_SUN_TLS"
15153   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15154         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15155   [(set_attr "type" "multi")
15156    (set_attr "length" "13")])
15157
15158 (define_expand "tls_local_dynamic_base_32"
15159   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15160                    (unspec:SI [(match_dup 1) (match_dup 2)]
15161                               UNSPEC_TLS_LD_BASE))
15162               (clobber (match_scratch:SI 3 ""))
15163               (clobber (match_scratch:SI 4 ""))
15164               (clobber (reg:CC FLAGS_REG))])]
15165   ""
15166 {
15167   if (flag_pic)
15168     operands[1] = pic_offset_table_rtx;
15169   else
15170     {
15171       operands[1] = gen_reg_rtx (Pmode);
15172       emit_insn (gen_set_got (operands[1]));
15173     }
15174   if (TARGET_GNU2_TLS)
15175     {
15176        emit_insn (gen_tls_dynamic_gnu2_32
15177                   (operands[0], ix86_tls_module_base (), operands[1]));
15178        DONE;
15179     }
15180   operands[2] = ix86_tls_get_addr ();
15181 })
15182
15183 (define_insn "*tls_local_dynamic_base_64"
15184   [(set (match_operand:DI 0 "register_operand" "=a")
15185         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15186                  (match_operand:DI 2 "" "")))
15187    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15188   "TARGET_64BIT"
15189   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15190   [(set_attr "type" "multi")
15191    (set_attr "length" "12")])
15192
15193 (define_expand "tls_local_dynamic_base_64"
15194   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15195                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15196               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15197   ""
15198 {
15199   if (TARGET_GNU2_TLS)
15200     {
15201        emit_insn (gen_tls_dynamic_gnu2_64
15202                   (operands[0], ix86_tls_module_base ()));
15203        DONE;
15204     }
15205   operands[1] = ix86_tls_get_addr ();
15206 })
15207
15208 ;; Local dynamic of a single variable is a lose.  Show combine how
15209 ;; to convert that back to global dynamic.
15210
15211 (define_insn_and_split "*tls_local_dynamic_32_once"
15212   [(set (match_operand:SI 0 "register_operand" "=a")
15213         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15214                              (match_operand:SI 2 "call_insn_operand" "")]
15215                             UNSPEC_TLS_LD_BASE)
15216                  (const:SI (unspec:SI
15217                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15218                             UNSPEC_DTPOFF))))
15219    (clobber (match_scratch:SI 4 "=d"))
15220    (clobber (match_scratch:SI 5 "=c"))
15221    (clobber (reg:CC FLAGS_REG))]
15222   ""
15223   "#"
15224   ""
15225   [(parallel [(set (match_dup 0)
15226                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15227                               UNSPEC_TLS_GD))
15228               (clobber (match_dup 4))
15229               (clobber (match_dup 5))
15230               (clobber (reg:CC FLAGS_REG))])]
15231   "")
15232
15233 ;; Load and add the thread base pointer from %gs:0.
15234
15235 (define_insn "*load_tp_si"
15236   [(set (match_operand:SI 0 "register_operand" "=r")
15237         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15238   "!TARGET_64BIT"
15239   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15240   [(set_attr "type" "imov")
15241    (set_attr "modrm" "0")
15242    (set_attr "length" "7")
15243    (set_attr "memory" "load")
15244    (set_attr "imm_disp" "false")])
15245
15246 (define_insn "*add_tp_si"
15247   [(set (match_operand:SI 0 "register_operand" "=r")
15248         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15249                  (match_operand:SI 1 "register_operand" "0")))
15250    (clobber (reg:CC FLAGS_REG))]
15251   "!TARGET_64BIT"
15252   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15253   [(set_attr "type" "alu")
15254    (set_attr "modrm" "0")
15255    (set_attr "length" "7")
15256    (set_attr "memory" "load")
15257    (set_attr "imm_disp" "false")])
15258
15259 (define_insn "*load_tp_di"
15260   [(set (match_operand:DI 0 "register_operand" "=r")
15261         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15262   "TARGET_64BIT"
15263   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15264   [(set_attr "type" "imov")
15265    (set_attr "modrm" "0")
15266    (set_attr "length" "7")
15267    (set_attr "memory" "load")
15268    (set_attr "imm_disp" "false")])
15269
15270 (define_insn "*add_tp_di"
15271   [(set (match_operand:DI 0 "register_operand" "=r")
15272         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15273                  (match_operand:DI 1 "register_operand" "0")))
15274    (clobber (reg:CC FLAGS_REG))]
15275   "TARGET_64BIT"
15276   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15277   [(set_attr "type" "alu")
15278    (set_attr "modrm" "0")
15279    (set_attr "length" "7")
15280    (set_attr "memory" "load")
15281    (set_attr "imm_disp" "false")])
15282
15283 ;; GNU2 TLS patterns can be split.
15284
15285 (define_expand "tls_dynamic_gnu2_32"
15286   [(set (match_dup 3)
15287         (plus:SI (match_operand:SI 2 "register_operand" "")
15288                  (const:SI
15289                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15290                              UNSPEC_TLSDESC))))
15291    (parallel
15292     [(set (match_operand:SI 0 "register_operand" "")
15293           (unspec:SI [(match_dup 1) (match_dup 3)
15294                       (match_dup 2) (reg:SI SP_REG)]
15295                       UNSPEC_TLSDESC))
15296      (clobber (reg:CC FLAGS_REG))])]
15297   "!TARGET_64BIT && TARGET_GNU2_TLS"
15298 {
15299   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15300   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15301 })
15302
15303 (define_insn "*tls_dynamic_lea_32"
15304   [(set (match_operand:SI 0 "register_operand" "=r")
15305         (plus:SI (match_operand:SI 1 "register_operand" "b")
15306                  (const:SI
15307                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15308                               UNSPEC_TLSDESC))))]
15309   "!TARGET_64BIT && TARGET_GNU2_TLS"
15310   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15311   [(set_attr "type" "lea")
15312    (set_attr "mode" "SI")
15313    (set_attr "length" "6")
15314    (set_attr "length_address" "4")])
15315
15316 (define_insn "*tls_dynamic_call_32"
15317   [(set (match_operand:SI 0 "register_operand" "=a")
15318         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15319                     (match_operand:SI 2 "register_operand" "0")
15320                     ;; we have to make sure %ebx still points to the GOT
15321                     (match_operand:SI 3 "register_operand" "b")
15322                     (reg:SI SP_REG)]
15323                    UNSPEC_TLSDESC))
15324    (clobber (reg:CC FLAGS_REG))]
15325   "!TARGET_64BIT && TARGET_GNU2_TLS"
15326   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15327   [(set_attr "type" "call")
15328    (set_attr "length" "2")
15329    (set_attr "length_address" "0")])
15330
15331 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15332   [(set (match_operand:SI 0 "register_operand" "=&a")
15333         (plus:SI
15334          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15335                      (match_operand:SI 4 "" "")
15336                      (match_operand:SI 2 "register_operand" "b")
15337                      (reg:SI SP_REG)]
15338                     UNSPEC_TLSDESC)
15339          (const:SI (unspec:SI
15340                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15341                     UNSPEC_DTPOFF))))
15342    (clobber (reg:CC FLAGS_REG))]
15343   "!TARGET_64BIT && TARGET_GNU2_TLS"
15344   "#"
15345   ""
15346   [(set (match_dup 0) (match_dup 5))]
15347 {
15348   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15349   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15350 })
15351
15352 (define_expand "tls_dynamic_gnu2_64"
15353   [(set (match_dup 2)
15354         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15355                    UNSPEC_TLSDESC))
15356    (parallel
15357     [(set (match_operand:DI 0 "register_operand" "")
15358           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15359                      UNSPEC_TLSDESC))
15360      (clobber (reg:CC FLAGS_REG))])]
15361   "TARGET_64BIT && TARGET_GNU2_TLS"
15362 {
15363   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15364   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15365 })
15366
15367 (define_insn "*tls_dynamic_lea_64"
15368   [(set (match_operand:DI 0 "register_operand" "=r")
15369         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15370                    UNSPEC_TLSDESC))]
15371   "TARGET_64BIT && TARGET_GNU2_TLS"
15372   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15373   [(set_attr "type" "lea")
15374    (set_attr "mode" "DI")
15375    (set_attr "length" "7")
15376    (set_attr "length_address" "4")])
15377
15378 (define_insn "*tls_dynamic_call_64"
15379   [(set (match_operand:DI 0 "register_operand" "=a")
15380         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15381                     (match_operand:DI 2 "register_operand" "0")
15382                     (reg:DI SP_REG)]
15383                    UNSPEC_TLSDESC))
15384    (clobber (reg:CC FLAGS_REG))]
15385   "TARGET_64BIT && TARGET_GNU2_TLS"
15386   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15387   [(set_attr "type" "call")
15388    (set_attr "length" "2")
15389    (set_attr "length_address" "0")])
15390
15391 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15392   [(set (match_operand:DI 0 "register_operand" "=&a")
15393         (plus:DI
15394          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15395                      (match_operand:DI 3 "" "")
15396                      (reg:DI SP_REG)]
15397                     UNSPEC_TLSDESC)
15398          (const:DI (unspec:DI
15399                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15400                     UNSPEC_DTPOFF))))
15401    (clobber (reg:CC FLAGS_REG))]
15402   "TARGET_64BIT && TARGET_GNU2_TLS"
15403   "#"
15404   ""
15405   [(set (match_dup 0) (match_dup 4))]
15406 {
15407   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15408   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15409 })
15410
15411 ;;
15412 \f
15413 ;; These patterns match the binary 387 instructions for addM3, subM3,
15414 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15415 ;; SFmode.  The first is the normal insn, the second the same insn but
15416 ;; with one operand a conversion, and the third the same insn but with
15417 ;; the other operand a conversion.  The conversion may be SFmode or
15418 ;; SImode if the target mode DFmode, but only SImode if the target mode
15419 ;; is SFmode.
15420
15421 ;; Gcc is slightly more smart about handling normal two address instructions
15422 ;; so use special patterns for add and mull.
15423
15424 (define_insn "*fop_sf_comm_mixed"
15425   [(set (match_operand:SF 0 "register_operand" "=f,x")
15426         (match_operator:SF 3 "binary_fp_operator"
15427                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15428                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15429   "TARGET_MIX_SSE_I387
15430    && COMMUTATIVE_ARITH_P (operands[3])
15431    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15432   "* return output_387_binary_op (insn, operands);"
15433   [(set (attr "type")
15434         (if_then_else (eq_attr "alternative" "1")
15435            (if_then_else (match_operand:SF 3 "mult_operator" "")
15436               (const_string "ssemul")
15437               (const_string "sseadd"))
15438            (if_then_else (match_operand:SF 3 "mult_operator" "")
15439               (const_string "fmul")
15440               (const_string "fop"))))
15441    (set_attr "mode" "SF")])
15442
15443 (define_insn "*fop_sf_comm_sse"
15444   [(set (match_operand:SF 0 "register_operand" "=x")
15445         (match_operator:SF 3 "binary_fp_operator"
15446                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15447                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15448   "TARGET_SSE_MATH
15449    && COMMUTATIVE_ARITH_P (operands[3])
15450    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15451   "* return output_387_binary_op (insn, operands);"
15452   [(set (attr "type")
15453         (if_then_else (match_operand:SF 3 "mult_operator" "")
15454            (const_string "ssemul")
15455            (const_string "sseadd")))
15456    (set_attr "mode" "SF")])
15457
15458 (define_insn "*fop_sf_comm_i387"
15459   [(set (match_operand:SF 0 "register_operand" "=f")
15460         (match_operator:SF 3 "binary_fp_operator"
15461                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15462                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15463   "TARGET_80387
15464    && COMMUTATIVE_ARITH_P (operands[3])
15465    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15466   "* return output_387_binary_op (insn, operands);"
15467   [(set (attr "type")
15468         (if_then_else (match_operand:SF 3 "mult_operator" "")
15469            (const_string "fmul")
15470            (const_string "fop")))
15471    (set_attr "mode" "SF")])
15472
15473 (define_insn "*fop_sf_1_mixed"
15474   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15475         (match_operator:SF 3 "binary_fp_operator"
15476                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15477                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15478   "TARGET_MIX_SSE_I387
15479    && !COMMUTATIVE_ARITH_P (operands[3])
15480    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15481   "* return output_387_binary_op (insn, operands);"
15482   [(set (attr "type")
15483         (cond [(and (eq_attr "alternative" "2")
15484                     (match_operand:SF 3 "mult_operator" ""))
15485                  (const_string "ssemul")
15486                (and (eq_attr "alternative" "2")
15487                     (match_operand:SF 3 "div_operator" ""))
15488                  (const_string "ssediv")
15489                (eq_attr "alternative" "2")
15490                  (const_string "sseadd")
15491                (match_operand:SF 3 "mult_operator" "")
15492                  (const_string "fmul")
15493                (match_operand:SF 3 "div_operator" "")
15494                  (const_string "fdiv")
15495               ]
15496               (const_string "fop")))
15497    (set_attr "mode" "SF")])
15498
15499 (define_insn "*fop_sf_1_sse"
15500   [(set (match_operand:SF 0 "register_operand" "=x")
15501         (match_operator:SF 3 "binary_fp_operator"
15502                         [(match_operand:SF 1 "register_operand" "0")
15503                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15504   "TARGET_SSE_MATH
15505    && !COMMUTATIVE_ARITH_P (operands[3])"
15506   "* return output_387_binary_op (insn, operands);"
15507   [(set (attr "type")
15508         (cond [(match_operand:SF 3 "mult_operator" "")
15509                  (const_string "ssemul")
15510                (match_operand:SF 3 "div_operator" "")
15511                  (const_string "ssediv")
15512               ]
15513               (const_string "sseadd")))
15514    (set_attr "mode" "SF")])
15515
15516 ;; This pattern is not fully shadowed by the pattern above.
15517 (define_insn "*fop_sf_1_i387"
15518   [(set (match_operand:SF 0 "register_operand" "=f,f")
15519         (match_operator:SF 3 "binary_fp_operator"
15520                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15521                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15522   "TARGET_80387 && !TARGET_SSE_MATH
15523    && !COMMUTATIVE_ARITH_P (operands[3])
15524    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15525   "* return output_387_binary_op (insn, operands);"
15526   [(set (attr "type")
15527         (cond [(match_operand:SF 3 "mult_operator" "")
15528                  (const_string "fmul")
15529                (match_operand:SF 3 "div_operator" "")
15530                  (const_string "fdiv")
15531               ]
15532               (const_string "fop")))
15533    (set_attr "mode" "SF")])
15534
15535 ;; ??? Add SSE splitters for these!
15536 (define_insn "*fop_sf_2<mode>_i387"
15537   [(set (match_operand:SF 0 "register_operand" "=f,f")
15538         (match_operator:SF 3 "binary_fp_operator"
15539           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15540            (match_operand:SF 2 "register_operand" "0,0")]))]
15541   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15542   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15543   [(set (attr "type")
15544         (cond [(match_operand:SF 3 "mult_operator" "")
15545                  (const_string "fmul")
15546                (match_operand:SF 3 "div_operator" "")
15547                  (const_string "fdiv")
15548               ]
15549               (const_string "fop")))
15550    (set_attr "fp_int_src" "true")
15551    (set_attr "mode" "<MODE>")])
15552
15553 (define_insn "*fop_sf_3<mode>_i387"
15554   [(set (match_operand:SF 0 "register_operand" "=f,f")
15555         (match_operator:SF 3 "binary_fp_operator"
15556           [(match_operand:SF 1 "register_operand" "0,0")
15557            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15558   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15559   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15560   [(set (attr "type")
15561         (cond [(match_operand:SF 3 "mult_operator" "")
15562                  (const_string "fmul")
15563                (match_operand:SF 3 "div_operator" "")
15564                  (const_string "fdiv")
15565               ]
15566               (const_string "fop")))
15567    (set_attr "fp_int_src" "true")
15568    (set_attr "mode" "<MODE>")])
15569
15570 (define_insn "*fop_df_comm_mixed"
15571   [(set (match_operand:DF 0 "register_operand" "=f,x")
15572         (match_operator:DF 3 "binary_fp_operator"
15573           [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15574            (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15575   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15576    && COMMUTATIVE_ARITH_P (operands[3])
15577    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15578   "* return output_387_binary_op (insn, operands);"
15579   [(set (attr "type")
15580         (if_then_else (eq_attr "alternative" "1")
15581            (if_then_else (match_operand:DF 3 "mult_operator" "")
15582               (const_string "ssemul")
15583               (const_string "sseadd"))
15584            (if_then_else (match_operand:DF 3 "mult_operator" "")
15585               (const_string "fmul")
15586               (const_string "fop"))))
15587    (set_attr "mode" "DF")])
15588
15589 (define_insn "*fop_df_comm_sse"
15590   [(set (match_operand:DF 0 "register_operand" "=x")
15591         (match_operator:DF 3 "binary_fp_operator"
15592           [(match_operand:DF 1 "nonimmediate_operand" "%0")
15593            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15594   "TARGET_SSE2 && TARGET_SSE_MATH
15595    && COMMUTATIVE_ARITH_P (operands[3])
15596    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15597   "* return output_387_binary_op (insn, operands);"
15598   [(set (attr "type")
15599         (if_then_else (match_operand:DF 3 "mult_operator" "")
15600            (const_string "ssemul")
15601            (const_string "sseadd")))
15602    (set_attr "mode" "DF")])
15603
15604 (define_insn "*fop_df_comm_i387"
15605   [(set (match_operand:DF 0 "register_operand" "=f")
15606         (match_operator:DF 3 "binary_fp_operator"
15607                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15608                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15609   "TARGET_80387
15610    && COMMUTATIVE_ARITH_P (operands[3])
15611    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15612   "* return output_387_binary_op (insn, operands);"
15613   [(set (attr "type")
15614         (if_then_else (match_operand:DF 3 "mult_operator" "")
15615            (const_string "fmul")
15616            (const_string "fop")))
15617    (set_attr "mode" "DF")])
15618
15619 (define_insn "*fop_df_1_mixed"
15620   [(set (match_operand:DF 0 "register_operand" "=f,f,x")
15621         (match_operator:DF 3 "binary_fp_operator"
15622           [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15623            (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
15624   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15625    && !COMMUTATIVE_ARITH_P (operands[3])
15626    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15627   "* return output_387_binary_op (insn, operands);"
15628   [(set (attr "type")
15629         (cond [(and (eq_attr "alternative" "2")
15630                     (match_operand:DF 3 "mult_operator" ""))
15631                  (const_string "ssemul")
15632                (and (eq_attr "alternative" "2")
15633                     (match_operand:DF 3 "div_operator" ""))
15634                  (const_string "ssediv")
15635                (eq_attr "alternative" "2")
15636                  (const_string "sseadd")
15637                (match_operand:DF 3 "mult_operator" "")
15638                  (const_string "fmul")
15639                (match_operand:DF 3 "div_operator" "")
15640                  (const_string "fdiv")
15641               ]
15642               (const_string "fop")))
15643    (set_attr "mode" "DF")])
15644
15645 (define_insn "*fop_df_1_sse"
15646   [(set (match_operand:DF 0 "register_operand" "=x")
15647         (match_operator:DF 3 "binary_fp_operator"
15648           [(match_operand:DF 1 "register_operand" "0")
15649            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15650   "TARGET_SSE2 && TARGET_SSE_MATH
15651    && !COMMUTATIVE_ARITH_P (operands[3])"
15652   "* return output_387_binary_op (insn, operands);"
15653   [(set_attr "mode" "DF")
15654    (set (attr "type")
15655         (cond [(match_operand:DF 3 "mult_operator" "")
15656                  (const_string "ssemul")
15657                (match_operand:DF 3 "div_operator" "")
15658                  (const_string "ssediv")
15659               ]
15660               (const_string "sseadd")))])
15661
15662 ;; This pattern is not fully shadowed by the pattern above.
15663 (define_insn "*fop_df_1_i387"
15664   [(set (match_operand:DF 0 "register_operand" "=f,f")
15665         (match_operator:DF 3 "binary_fp_operator"
15666                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15667                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15668   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15669    && !COMMUTATIVE_ARITH_P (operands[3])
15670    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15671   "* return output_387_binary_op (insn, operands);"
15672   [(set (attr "type")
15673         (cond [(match_operand:DF 3 "mult_operator" "")
15674                  (const_string "fmul")
15675                (match_operand:DF 3 "div_operator" "")
15676                  (const_string "fdiv")
15677               ]
15678               (const_string "fop")))
15679    (set_attr "mode" "DF")])
15680
15681 ;; ??? Add SSE splitters for these!
15682 (define_insn "*fop_df_2<mode>_i387"
15683   [(set (match_operand:DF 0 "register_operand" "=f,f")
15684         (match_operator:DF 3 "binary_fp_operator"
15685            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15686             (match_operand:DF 2 "register_operand" "0,0")]))]
15687   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15688    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15689   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15690   [(set (attr "type")
15691         (cond [(match_operand:DF 3 "mult_operator" "")
15692                  (const_string "fmul")
15693                (match_operand:DF 3 "div_operator" "")
15694                  (const_string "fdiv")
15695               ]
15696               (const_string "fop")))
15697    (set_attr "fp_int_src" "true")
15698    (set_attr "mode" "<MODE>")])
15699
15700 (define_insn "*fop_df_3<mode>_i387"
15701   [(set (match_operand:DF 0 "register_operand" "=f,f")
15702         (match_operator:DF 3 "binary_fp_operator"
15703            [(match_operand:DF 1 "register_operand" "0,0")
15704             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15705   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15706    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15707   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15708   [(set (attr "type")
15709         (cond [(match_operand:DF 3 "mult_operator" "")
15710                  (const_string "fmul")
15711                (match_operand:DF 3 "div_operator" "")
15712                  (const_string "fdiv")
15713               ]
15714               (const_string "fop")))
15715    (set_attr "fp_int_src" "true")
15716    (set_attr "mode" "<MODE>")])
15717
15718 (define_insn "*fop_df_4_i387"
15719   [(set (match_operand:DF 0 "register_operand" "=f,f")
15720         (match_operator:DF 3 "binary_fp_operator"
15721            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15722             (match_operand:DF 2 "register_operand" "0,f")]))]
15723   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15724    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15725   "* return output_387_binary_op (insn, operands);"
15726   [(set (attr "type")
15727         (cond [(match_operand:DF 3 "mult_operator" "")
15728                  (const_string "fmul")
15729                (match_operand:DF 3 "div_operator" "")
15730                  (const_string "fdiv")
15731               ]
15732               (const_string "fop")))
15733    (set_attr "mode" "SF")])
15734
15735 (define_insn "*fop_df_5_i387"
15736   [(set (match_operand:DF 0 "register_operand" "=f,f")
15737         (match_operator:DF 3 "binary_fp_operator"
15738           [(match_operand:DF 1 "register_operand" "0,f")
15739            (float_extend:DF
15740             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15741   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15742   "* return output_387_binary_op (insn, operands);"
15743   [(set (attr "type")
15744         (cond [(match_operand:DF 3 "mult_operator" "")
15745                  (const_string "fmul")
15746                (match_operand:DF 3 "div_operator" "")
15747                  (const_string "fdiv")
15748               ]
15749               (const_string "fop")))
15750    (set_attr "mode" "SF")])
15751
15752 (define_insn "*fop_df_6_i387"
15753   [(set (match_operand:DF 0 "register_operand" "=f,f")
15754         (match_operator:DF 3 "binary_fp_operator"
15755           [(float_extend:DF
15756             (match_operand:SF 1 "register_operand" "0,f"))
15757            (float_extend:DF
15758             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15759   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15760   "* return output_387_binary_op (insn, operands);"
15761   [(set (attr "type")
15762         (cond [(match_operand:DF 3 "mult_operator" "")
15763                  (const_string "fmul")
15764                (match_operand:DF 3 "div_operator" "")
15765                  (const_string "fdiv")
15766               ]
15767               (const_string "fop")))
15768    (set_attr "mode" "SF")])
15769
15770 (define_insn "*fop_xf_comm_i387"
15771   [(set (match_operand:XF 0 "register_operand" "=f")
15772         (match_operator:XF 3 "binary_fp_operator"
15773                         [(match_operand:XF 1 "register_operand" "%0")
15774                          (match_operand:XF 2 "register_operand" "f")]))]
15775   "TARGET_80387
15776    && COMMUTATIVE_ARITH_P (operands[3])"
15777   "* return output_387_binary_op (insn, operands);"
15778   [(set (attr "type")
15779         (if_then_else (match_operand:XF 3 "mult_operator" "")
15780            (const_string "fmul")
15781            (const_string "fop")))
15782    (set_attr "mode" "XF")])
15783
15784 (define_insn "*fop_xf_1_i387"
15785   [(set (match_operand:XF 0 "register_operand" "=f,f")
15786         (match_operator:XF 3 "binary_fp_operator"
15787                         [(match_operand:XF 1 "register_operand" "0,f")
15788                          (match_operand:XF 2 "register_operand" "f,0")]))]
15789   "TARGET_80387
15790    && !COMMUTATIVE_ARITH_P (operands[3])"
15791   "* return output_387_binary_op (insn, operands);"
15792   [(set (attr "type")
15793         (cond [(match_operand:XF 3 "mult_operator" "")
15794                  (const_string "fmul")
15795                (match_operand:XF 3 "div_operator" "")
15796                  (const_string "fdiv")
15797               ]
15798               (const_string "fop")))
15799    (set_attr "mode" "XF")])
15800
15801 (define_insn "*fop_xf_2<mode>_i387"
15802   [(set (match_operand:XF 0 "register_operand" "=f,f")
15803         (match_operator:XF 3 "binary_fp_operator"
15804            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15805             (match_operand:XF 2 "register_operand" "0,0")]))]
15806   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15807   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15808   [(set (attr "type")
15809         (cond [(match_operand:XF 3 "mult_operator" "")
15810                  (const_string "fmul")
15811                (match_operand:XF 3 "div_operator" "")
15812                  (const_string "fdiv")
15813               ]
15814               (const_string "fop")))
15815    (set_attr "fp_int_src" "true")
15816    (set_attr "mode" "<MODE>")])
15817
15818 (define_insn "*fop_xf_3<mode>_i387"
15819   [(set (match_operand:XF 0 "register_operand" "=f,f")
15820         (match_operator:XF 3 "binary_fp_operator"
15821           [(match_operand:XF 1 "register_operand" "0,0")
15822            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15823   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15824   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15825   [(set (attr "type")
15826         (cond [(match_operand:XF 3 "mult_operator" "")
15827                  (const_string "fmul")
15828                (match_operand:XF 3 "div_operator" "")
15829                  (const_string "fdiv")
15830               ]
15831               (const_string "fop")))
15832    (set_attr "fp_int_src" "true")
15833    (set_attr "mode" "<MODE>")])
15834
15835 (define_insn "*fop_xf_4_i387"
15836   [(set (match_operand:XF 0 "register_operand" "=f,f")
15837         (match_operator:XF 3 "binary_fp_operator"
15838            [(float_extend:XF
15839               (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
15840             (match_operand:XF 2 "register_operand" "0,f")]))]
15841   "TARGET_80387"
15842   "* return output_387_binary_op (insn, operands);"
15843   [(set (attr "type")
15844         (cond [(match_operand:XF 3 "mult_operator" "")
15845                  (const_string "fmul")
15846                (match_operand:XF 3 "div_operator" "")
15847                  (const_string "fdiv")
15848               ]
15849               (const_string "fop")))
15850    (set_attr "mode" "SF")])
15851
15852 (define_insn "*fop_xf_5_i387"
15853   [(set (match_operand:XF 0 "register_operand" "=f,f")
15854         (match_operator:XF 3 "binary_fp_operator"
15855           [(match_operand:XF 1 "register_operand" "0,f")
15856            (float_extend:XF
15857              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15858   "TARGET_80387"
15859   "* return output_387_binary_op (insn, operands);"
15860   [(set (attr "type")
15861         (cond [(match_operand:XF 3 "mult_operator" "")
15862                  (const_string "fmul")
15863                (match_operand:XF 3 "div_operator" "")
15864                  (const_string "fdiv")
15865               ]
15866               (const_string "fop")))
15867    (set_attr "mode" "SF")])
15868
15869 (define_insn "*fop_xf_6_i387"
15870   [(set (match_operand:XF 0 "register_operand" "=f,f")
15871         (match_operator:XF 3 "binary_fp_operator"
15872           [(float_extend:XF
15873              (match_operand:X87MODEF12 1 "register_operand" "0,f"))
15874            (float_extend:XF
15875              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15876   "TARGET_80387"
15877   "* return output_387_binary_op (insn, operands);"
15878   [(set (attr "type")
15879         (cond [(match_operand:XF 3 "mult_operator" "")
15880                  (const_string "fmul")
15881                (match_operand:XF 3 "div_operator" "")
15882                  (const_string "fdiv")
15883               ]
15884               (const_string "fop")))
15885    (set_attr "mode" "SF")])
15886
15887 (define_split
15888   [(set (match_operand 0 "register_operand" "")
15889         (match_operator 3 "binary_fp_operator"
15890            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15891             (match_operand 2 "register_operand" "")]))]
15892   "reload_completed
15893    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
15894   [(const_int 0)]
15895 {
15896   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15897   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15898   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15899                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15900                                           GET_MODE (operands[3]),
15901                                           operands[4],
15902                                           operands[2])));
15903   ix86_free_from_memory (GET_MODE (operands[1]));
15904   DONE;
15905 })
15906
15907 (define_split
15908   [(set (match_operand 0 "register_operand" "")
15909         (match_operator 3 "binary_fp_operator"
15910            [(match_operand 1 "register_operand" "")
15911             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15912   "reload_completed
15913    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
15914   [(const_int 0)]
15915 {
15916   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15917   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15918   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15919                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15920                                           GET_MODE (operands[3]),
15921                                           operands[1],
15922                                           operands[4])));
15923   ix86_free_from_memory (GET_MODE (operands[2]));
15924   DONE;
15925 })
15926 \f
15927 ;; FPU special functions.
15928
15929 ;; This pattern implements a no-op XFmode truncation for
15930 ;; all fancy i386 XFmode math functions.
15931
15932 (define_insn "truncxf<mode>2_i387_noop_unspec"
15933   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15934         (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
15935         UNSPEC_TRUNC_NOOP))]
15936   "TARGET_USE_FANCY_MATH_387"
15937   "* return output_387_reg_move (insn, operands);"
15938   [(set_attr "type" "fmov")
15939    (set_attr "mode" "<MODE>")])
15940
15941 (define_insn "sqrtxf2"
15942   [(set (match_operand:XF 0 "register_operand" "=f")
15943         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15944   "TARGET_USE_FANCY_MATH_387"
15945   "fsqrt"
15946   [(set_attr "type" "fpspc")
15947    (set_attr "mode" "XF")
15948    (set_attr "athlon_decode" "direct")
15949    (set_attr "amdfam10_decode" "direct")])
15950
15951 (define_insn "sqrt_extend<mode>xf2_i387"
15952   [(set (match_operand:XF 0 "register_operand" "=f")
15953         (sqrt:XF
15954           (float_extend:XF
15955             (match_operand:X87MODEF12 1 "register_operand" "0"))))]
15956   "TARGET_USE_FANCY_MATH_387"
15957   "fsqrt"
15958   [(set_attr "type" "fpspc")
15959    (set_attr "mode" "XF")
15960    (set_attr "athlon_decode" "direct")   
15961    (set_attr "amdfam10_decode" "direct")])
15962
15963 (define_insn "*sqrt<mode>2_sse"
15964   [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
15965         (sqrt:SSEMODEF
15966           (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
15967   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15968   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
15969   [(set_attr "type" "sse")
15970    (set_attr "mode" "<MODE>")
15971    (set_attr "athlon_decode" "*")
15972    (set_attr "amdfam10_decode" "*")])
15973
15974 (define_expand "sqrt<mode>2"
15975   [(set (match_operand:X87MODEF12 0 "register_operand" "")
15976         (sqrt:X87MODEF12
15977           (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
15978   "TARGET_USE_FANCY_MATH_387
15979    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15980 {
15981   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15982     {
15983       rtx op0 = gen_reg_rtx (XFmode);
15984       rtx op1 = force_reg (<MODE>mode, operands[1]);
15985
15986       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15987       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15988       DONE;
15989    }
15990 })
15991
15992 (define_insn "fpremxf4_i387"
15993   [(set (match_operand:XF 0 "register_operand" "=f")
15994         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15995                     (match_operand:XF 3 "register_operand" "1")]
15996                    UNSPEC_FPREM_F))
15997    (set (match_operand:XF 1 "register_operand" "=u")
15998         (unspec:XF [(match_dup 2) (match_dup 3)]
15999                    UNSPEC_FPREM_U))
16000    (set (reg:CCFP FPSR_REG)
16001         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16002                      UNSPEC_C2_FLAG))]
16003   "TARGET_USE_FANCY_MATH_387"
16004   "fprem"
16005   [(set_attr "type" "fpspc")
16006    (set_attr "mode" "XF")])
16007
16008 (define_expand "fmodxf3"
16009   [(use (match_operand:XF 0 "register_operand" ""))
16010    (use (match_operand:XF 1 "register_operand" ""))
16011    (use (match_operand:XF 2 "register_operand" ""))]
16012   "TARGET_USE_FANCY_MATH_387"
16013 {
16014   rtx label = gen_label_rtx ();
16015
16016   emit_label (label);
16017
16018   emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
16019                                 operands[1], operands[2]));
16020   ix86_emit_fp_unordered_jump (label);
16021   LABEL_NUSES (label) = 1;
16022
16023   emit_move_insn (operands[0], operands[1]);
16024   DONE;
16025 })
16026
16027 (define_expand "fmod<mode>3"
16028   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16029    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16030    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16031   "TARGET_USE_FANCY_MATH_387"
16032 {
16033   rtx label = gen_label_rtx ();
16034
16035   rtx op1 = gen_reg_rtx (XFmode);
16036   rtx op2 = gen_reg_rtx (XFmode);
16037
16038   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16039   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16040
16041   emit_label (label);
16042   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16043   ix86_emit_fp_unordered_jump (label);
16044   LABEL_NUSES (label) = 1;
16045
16046   /* Truncate the result properly for strict SSE math.  */
16047   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16048       && !TARGET_MIX_SSE_I387)
16049     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16050   else
16051     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16052
16053   DONE;
16054 })
16055
16056 (define_insn "fprem1xf4_i387"
16057   [(set (match_operand:XF 0 "register_operand" "=f")
16058         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16059                     (match_operand:XF 3 "register_operand" "1")]
16060                    UNSPEC_FPREM1_F))
16061    (set (match_operand:XF 1 "register_operand" "=u")
16062         (unspec:XF [(match_dup 2) (match_dup 3)]
16063                    UNSPEC_FPREM1_U))
16064    (set (reg:CCFP FPSR_REG)
16065         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16066                      UNSPEC_C2_FLAG))]
16067   "TARGET_USE_FANCY_MATH_387"
16068   "fprem1"
16069   [(set_attr "type" "fpspc")
16070    (set_attr "mode" "XF")])
16071
16072 (define_expand "remainderxf3"
16073   [(use (match_operand:XF 0 "register_operand" ""))
16074    (use (match_operand:XF 1 "register_operand" ""))
16075    (use (match_operand:XF 2 "register_operand" ""))]
16076   "TARGET_USE_FANCY_MATH_387"
16077 {
16078   rtx label = gen_label_rtx ();
16079
16080   emit_label (label);
16081
16082   emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
16083                                  operands[1], operands[2]));
16084   ix86_emit_fp_unordered_jump (label);
16085   LABEL_NUSES (label) = 1;
16086
16087   emit_move_insn (operands[0], operands[1]);
16088   DONE;
16089 })
16090
16091 (define_expand "remainder<mode>3"
16092   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16093    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16094    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16095   "TARGET_USE_FANCY_MATH_387"
16096 {
16097   rtx label = gen_label_rtx ();
16098
16099   rtx op1 = gen_reg_rtx (XFmode);
16100   rtx op2 = gen_reg_rtx (XFmode);
16101
16102   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16103   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16104
16105   emit_label (label);
16106
16107   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16108   ix86_emit_fp_unordered_jump (label);
16109   LABEL_NUSES (label) = 1;
16110
16111   /* Truncate the result properly for strict SSE math.  */
16112   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16113       && !TARGET_MIX_SSE_I387)
16114     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16115   else
16116     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16117
16118   DONE;
16119 })
16120
16121 (define_insn "*sinxf2_i387"
16122   [(set (match_operand:XF 0 "register_operand" "=f")
16123         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16124   "TARGET_USE_FANCY_MATH_387
16125    && flag_unsafe_math_optimizations"
16126   "fsin"
16127   [(set_attr "type" "fpspc")
16128    (set_attr "mode" "XF")])
16129
16130 (define_insn "*sin_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_SIN))]
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   "fsin"
16140   [(set_attr "type" "fpspc")
16141    (set_attr "mode" "XF")])
16142
16143 (define_insn "*cosxf2_i387"
16144   [(set (match_operand:XF 0 "register_operand" "=f")
16145         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16146   "TARGET_USE_FANCY_MATH_387
16147    && flag_unsafe_math_optimizations"
16148   "fcos"
16149   [(set_attr "type" "fpspc")
16150    (set_attr "mode" "XF")])
16151
16152 (define_insn "*cos_extend<mode>xf2_i387"
16153   [(set (match_operand:XF 0 "register_operand" "=f")
16154         (unspec:XF [(float_extend:XF
16155                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
16156                    UNSPEC_COS))]
16157   "TARGET_USE_FANCY_MATH_387
16158    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16159        || TARGET_MIX_SSE_I387)
16160    && flag_unsafe_math_optimizations"
16161   "fcos"
16162   [(set_attr "type" "fpspc")
16163    (set_attr "mode" "XF")])
16164
16165 ;; When sincos pattern is defined, sin and cos builtin functions will be
16166 ;; expanded to sincos pattern with one of its outputs left unused.
16167 ;; CSE pass will figure out if two sincos patterns can be combined,
16168 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16169 ;; depending on the unused output.
16170
16171 (define_insn "sincosxf3"
16172   [(set (match_operand:XF 0 "register_operand" "=f")
16173         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16174                    UNSPEC_SINCOS_COS))
16175    (set (match_operand:XF 1 "register_operand" "=u")
16176         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16177   "TARGET_USE_FANCY_MATH_387
16178    && flag_unsafe_math_optimizations"
16179   "fsincos"
16180   [(set_attr "type" "fpspc")
16181    (set_attr "mode" "XF")])
16182
16183 (define_split
16184   [(set (match_operand:XF 0 "register_operand" "")
16185         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16186                    UNSPEC_SINCOS_COS))
16187    (set (match_operand:XF 1 "register_operand" "")
16188         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16189   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16190    && !reload_completed && !reload_in_progress"
16191   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16192   "")
16193
16194 (define_split
16195   [(set (match_operand:XF 0 "register_operand" "")
16196         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16197                    UNSPEC_SINCOS_COS))
16198    (set (match_operand:XF 1 "register_operand" "")
16199         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16200   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16201    && !reload_completed && !reload_in_progress"
16202   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16203   "")
16204
16205 (define_insn "sincos_extend<mode>xf3_i387"
16206   [(set (match_operand:XF 0 "register_operand" "=f")
16207         (unspec:XF [(float_extend:XF
16208                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16209                    UNSPEC_SINCOS_COS))
16210    (set (match_operand:XF 1 "register_operand" "=u")
16211         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16212   "TARGET_USE_FANCY_MATH_387
16213    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16214        || TARGET_MIX_SSE_I387)
16215    && flag_unsafe_math_optimizations"
16216   "fsincos"
16217   [(set_attr "type" "fpspc")
16218    (set_attr "mode" "XF")])
16219
16220 (define_split
16221   [(set (match_operand:XF 0 "register_operand" "")
16222         (unspec:XF [(float_extend:XF
16223                       (match_operand:X87MODEF12 2 "register_operand" ""))]
16224                    UNSPEC_SINCOS_COS))
16225    (set (match_operand:XF 1 "register_operand" "")
16226         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16227   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16228    && !reload_completed && !reload_in_progress"
16229   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16230   "")
16231
16232 (define_split
16233   [(set (match_operand:XF 0 "register_operand" "")
16234         (unspec:XF [(float_extend:XF
16235                       (match_operand:X87MODEF12 2 "register_operand" ""))]
16236                    UNSPEC_SINCOS_COS))
16237    (set (match_operand:XF 1 "register_operand" "")
16238         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16239   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16240    && !reload_completed && !reload_in_progress"
16241   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16242   "")
16243
16244 (define_expand "sincos<mode>3"
16245   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16246    (use (match_operand:X87MODEF12 1 "register_operand" ""))
16247    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16248   "TARGET_USE_FANCY_MATH_387
16249    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16250        || TARGET_MIX_SSE_I387)
16251    && flag_unsafe_math_optimizations"
16252 {
16253   rtx op0 = gen_reg_rtx (XFmode);
16254   rtx op1 = gen_reg_rtx (XFmode);
16255
16256   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16257   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16258   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16259   DONE;
16260 })
16261
16262 (define_insn "fptanxf4_i387"
16263   [(set (match_operand:XF 0 "register_operand" "=f")
16264         (match_operand:XF 3 "const_double_operand" "F"))
16265    (set (match_operand:XF 1 "register_operand" "=u")
16266         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16267                    UNSPEC_TAN))]
16268   "TARGET_USE_FANCY_MATH_387
16269    && flag_unsafe_math_optimizations
16270    && standard_80387_constant_p (operands[3]) == 2"
16271   "fptan"
16272   [(set_attr "type" "fpspc")
16273    (set_attr "mode" "XF")])
16274
16275 (define_insn "fptan_extend<mode>xf4_i387"
16276   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16277         (match_operand:X87MODEF12 3 "const_double_operand" "F"))
16278    (set (match_operand:XF 1 "register_operand" "=u")
16279         (unspec:XF [(float_extend:XF
16280                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16281                    UNSPEC_TAN))]
16282   "TARGET_USE_FANCY_MATH_387
16283    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16284        || TARGET_MIX_SSE_I387)
16285    && flag_unsafe_math_optimizations
16286    && standard_80387_constant_p (operands[3]) == 2"
16287   "fptan"
16288   [(set_attr "type" "fpspc")
16289    (set_attr "mode" "XF")])
16290
16291 (define_expand "tanxf2"
16292   [(use (match_operand:XF 0 "register_operand" ""))
16293    (use (match_operand:XF 1 "register_operand" ""))]
16294   "TARGET_USE_FANCY_MATH_387
16295    && flag_unsafe_math_optimizations"
16296 {
16297   rtx one = gen_reg_rtx (XFmode);
16298   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16299
16300   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16301   DONE;
16302 })
16303
16304 (define_expand "tan<mode>2"
16305   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16306    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16307   "TARGET_USE_FANCY_MATH_387
16308    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16309        || TARGET_MIX_SSE_I387)
16310    && flag_unsafe_math_optimizations"
16311 {
16312   rtx op0 = gen_reg_rtx (XFmode);
16313
16314   rtx one = gen_reg_rtx (<MODE>mode);
16315   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16316
16317   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16318                                              operands[1], op2));
16319   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16320   DONE;
16321 })
16322
16323 (define_insn "*fpatanxf3_i387"
16324   [(set (match_operand:XF 0 "register_operand" "=f")
16325         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16326                     (match_operand:XF 2 "register_operand" "u")]
16327                    UNSPEC_FPATAN))
16328    (clobber (match_scratch:XF 3 "=2"))]
16329   "TARGET_USE_FANCY_MATH_387
16330    && flag_unsafe_math_optimizations"
16331   "fpatan"
16332   [(set_attr "type" "fpspc")
16333    (set_attr "mode" "XF")])
16334
16335 (define_insn "fpatan_extend<mode>xf3_i387"
16336   [(set (match_operand:XF 0 "register_operand" "=f")
16337         (unspec:XF [(float_extend:XF
16338                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16339                     (float_extend:XF
16340                       (match_operand:X87MODEF12 2 "register_operand" "u"))]
16341                    UNSPEC_FPATAN))
16342    (clobber (match_scratch:XF 3 "=2"))]
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   "fpatan"
16348   [(set_attr "type" "fpspc")
16349    (set_attr "mode" "XF")])
16350
16351 (define_expand "atan2xf3"
16352   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16353                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16354                                (match_operand:XF 1 "register_operand" "")]
16355                               UNSPEC_FPATAN))
16356               (clobber (match_scratch:XF 3 ""))])]
16357   "TARGET_USE_FANCY_MATH_387
16358    && flag_unsafe_math_optimizations"
16359   "")
16360
16361 (define_expand "atan2<mode>3"
16362   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16363    (use (match_operand:X87MODEF12 1 "register_operand" ""))
16364    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16365   "TARGET_USE_FANCY_MATH_387
16366    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16367        || TARGET_MIX_SSE_I387)
16368    && flag_unsafe_math_optimizations"
16369 {
16370   rtx op0 = gen_reg_rtx (XFmode);
16371
16372   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16373   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16374   DONE;
16375 })
16376
16377 (define_expand "atanxf2"
16378   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16379                    (unspec:XF [(match_dup 2)
16380                                (match_operand:XF 1 "register_operand" "")]
16381                               UNSPEC_FPATAN))
16382               (clobber (match_scratch:XF 3 ""))])]
16383   "TARGET_USE_FANCY_MATH_387
16384    && flag_unsafe_math_optimizations"
16385 {
16386   operands[2] = gen_reg_rtx (XFmode);
16387   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16388 })
16389
16390 (define_expand "atan<mode>2"
16391   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16392    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16393   "TARGET_USE_FANCY_MATH_387
16394    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16395        || TARGET_MIX_SSE_I387)
16396    && flag_unsafe_math_optimizations"
16397 {
16398   rtx op0 = gen_reg_rtx (XFmode);
16399
16400   rtx op2 = gen_reg_rtx (<MODE>mode);
16401   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16402
16403   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16404   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16405   DONE;
16406 })
16407
16408 (define_expand "asinxf2"
16409   [(set (match_dup 2)
16410         (mult:XF (match_operand:XF 1 "register_operand" "")
16411                  (match_dup 1)))
16412    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16413    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16414    (parallel [(set (match_operand:XF 0 "register_operand" "")
16415                    (unspec:XF [(match_dup 5) (match_dup 1)]
16416                               UNSPEC_FPATAN))
16417               (clobber (match_scratch:XF 6 ""))])]
16418   "TARGET_USE_FANCY_MATH_387
16419    && flag_unsafe_math_optimizations && !optimize_size"
16420 {
16421   int i;
16422
16423   for (i = 2; i < 6; i++)
16424     operands[i] = gen_reg_rtx (XFmode);
16425
16426   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16427 })
16428
16429 (define_expand "asin<mode>2"
16430   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16431    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16432  "TARGET_USE_FANCY_MATH_387
16433    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16434        || TARGET_MIX_SSE_I387)
16435    && flag_unsafe_math_optimizations && !optimize_size"
16436 {
16437   rtx op0 = gen_reg_rtx (XFmode);
16438   rtx op1 = gen_reg_rtx (XFmode);
16439
16440   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16441   emit_insn (gen_asinxf2 (op0, op1));
16442   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16443   DONE;
16444 })
16445
16446 (define_expand "acosxf2"
16447   [(set (match_dup 2)
16448         (mult:XF (match_operand:XF 1 "register_operand" "")
16449                  (match_dup 1)))
16450    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16451    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16452    (parallel [(set (match_operand:XF 0 "register_operand" "")
16453                    (unspec:XF [(match_dup 1) (match_dup 5)]
16454                               UNSPEC_FPATAN))
16455               (clobber (match_scratch:XF 6 ""))])]
16456   "TARGET_USE_FANCY_MATH_387
16457    && flag_unsafe_math_optimizations && !optimize_size"
16458 {
16459   int i;
16460
16461   for (i = 2; i < 6; i++)
16462     operands[i] = gen_reg_rtx (XFmode);
16463
16464   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16465 })
16466
16467 (define_expand "acos<mode>2"
16468   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16469    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16470  "TARGET_USE_FANCY_MATH_387
16471    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16472        || TARGET_MIX_SSE_I387)
16473    && flag_unsafe_math_optimizations && !optimize_size"
16474 {
16475   rtx op0 = gen_reg_rtx (XFmode);
16476   rtx op1 = gen_reg_rtx (XFmode);
16477
16478   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16479   emit_insn (gen_acosxf2 (op0, op1));
16480   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16481   DONE;
16482 })
16483
16484 (define_insn "fyl2xxf3_i387"
16485   [(set (match_operand:XF 0 "register_operand" "=f")
16486         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16487                     (match_operand:XF 2 "register_operand" "u")]
16488                    UNSPEC_FYL2X))
16489    (clobber (match_scratch:XF 3 "=2"))]
16490   "TARGET_USE_FANCY_MATH_387
16491    && flag_unsafe_math_optimizations"
16492   "fyl2x"
16493   [(set_attr "type" "fpspc")
16494    (set_attr "mode" "XF")])
16495
16496 (define_insn "fyl2x_extend<mode>xf3_i387"
16497   [(set (match_operand:XF 0 "register_operand" "=f")
16498         (unspec:XF [(float_extend:XF
16499                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16500                     (match_operand:XF 2 "register_operand" "u")]
16501                    UNSPEC_FYL2X))
16502    (clobber (match_scratch:XF 3 "=2"))]
16503   "TARGET_USE_FANCY_MATH_387
16504    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16505        || TARGET_MIX_SSE_I387)
16506    && flag_unsafe_math_optimizations"
16507   "fyl2x"
16508   [(set_attr "type" "fpspc")
16509    (set_attr "mode" "XF")])
16510
16511 (define_expand "logxf2"
16512   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16513                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16514                                (match_dup 2)] UNSPEC_FYL2X))
16515               (clobber (match_scratch:XF 3 ""))])]
16516   "TARGET_USE_FANCY_MATH_387
16517    && flag_unsafe_math_optimizations"
16518 {
16519   operands[2] = gen_reg_rtx (XFmode);
16520   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16521 })
16522
16523 (define_expand "log<mode>2"
16524   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16525    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16526   "TARGET_USE_FANCY_MATH_387
16527    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16528        || TARGET_MIX_SSE_I387)
16529    && flag_unsafe_math_optimizations"
16530 {
16531   rtx op0 = gen_reg_rtx (XFmode);
16532
16533   rtx op2 = gen_reg_rtx (XFmode);
16534   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16535
16536   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16537   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16538   DONE;
16539 })
16540
16541 (define_expand "log10xf2"
16542   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16543                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16544                                (match_dup 2)] UNSPEC_FYL2X))
16545               (clobber (match_scratch:XF 3 ""))])]
16546   "TARGET_USE_FANCY_MATH_387
16547    && flag_unsafe_math_optimizations"
16548 {
16549   operands[2] = gen_reg_rtx (XFmode);
16550   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16551 })
16552
16553 (define_expand "log10<mode>2"
16554   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16555    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16556   "TARGET_USE_FANCY_MATH_387
16557    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16558        || TARGET_MIX_SSE_I387)
16559    && flag_unsafe_math_optimizations"
16560 {
16561   rtx op0 = gen_reg_rtx (XFmode);
16562
16563   rtx op2 = gen_reg_rtx (XFmode);
16564   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16565
16566   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16567   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16568   DONE;
16569 })
16570
16571 (define_expand "log2xf2"
16572   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16573                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16574                                (match_dup 2)] UNSPEC_FYL2X))
16575               (clobber (match_scratch:XF 3 ""))])]
16576   "TARGET_USE_FANCY_MATH_387
16577    && flag_unsafe_math_optimizations"
16578 {
16579   operands[2] = gen_reg_rtx (XFmode);
16580   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16581 })
16582
16583 (define_expand "log2<mode>2"
16584   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16585    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16586   "TARGET_USE_FANCY_MATH_387
16587    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16588        || TARGET_MIX_SSE_I387)
16589    && flag_unsafe_math_optimizations"
16590 {
16591   rtx op0 = gen_reg_rtx (XFmode);
16592
16593   rtx op2 = gen_reg_rtx (XFmode);
16594   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16595
16596   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16597   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16598   DONE;
16599 })
16600
16601 (define_insn "fyl2xp1xf3_i387"
16602   [(set (match_operand:XF 0 "register_operand" "=f")
16603         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16604                     (match_operand:XF 2 "register_operand" "u")]
16605                    UNSPEC_FYL2XP1))
16606    (clobber (match_scratch:XF 3 "=2"))]
16607   "TARGET_USE_FANCY_MATH_387
16608    && flag_unsafe_math_optimizations"
16609   "fyl2xp1"
16610   [(set_attr "type" "fpspc")
16611    (set_attr "mode" "XF")])
16612
16613 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16614   [(set (match_operand:XF 0 "register_operand" "=f")
16615         (unspec:XF [(float_extend:XF
16616                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16617                     (match_operand:XF 2 "register_operand" "u")]
16618                    UNSPEC_FYL2XP1))
16619    (clobber (match_scratch:XF 3 "=2"))]
16620   "TARGET_USE_FANCY_MATH_387
16621    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16622        || TARGET_MIX_SSE_I387)
16623    && flag_unsafe_math_optimizations"
16624   "fyl2xp1"
16625   [(set_attr "type" "fpspc")
16626    (set_attr "mode" "XF")])
16627
16628 (define_expand "log1pxf2"
16629   [(use (match_operand:XF 0 "register_operand" ""))
16630    (use (match_operand:XF 1 "register_operand" ""))]
16631   "TARGET_USE_FANCY_MATH_387
16632    && flag_unsafe_math_optimizations && !optimize_size"
16633 {
16634   ix86_emit_i387_log1p (operands[0], operands[1]);
16635   DONE;
16636 })
16637
16638 (define_expand "log1p<mode>2"
16639   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16640    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16641   "TARGET_USE_FANCY_MATH_387
16642    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16643        || TARGET_MIX_SSE_I387)
16644    && flag_unsafe_math_optimizations && !optimize_size"
16645 {
16646   rtx op0 = gen_reg_rtx (XFmode);
16647
16648   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16649
16650   ix86_emit_i387_log1p (op0, operands[1]);
16651   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16652   DONE;
16653 })
16654
16655 (define_insn "fxtractxf3_i387"
16656   [(set (match_operand:XF 0 "register_operand" "=f")
16657         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16658                    UNSPEC_XTRACT_FRACT))
16659    (set (match_operand:XF 1 "register_operand" "=u")
16660         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16661   "TARGET_USE_FANCY_MATH_387
16662    && flag_unsafe_math_optimizations"
16663   "fxtract"
16664   [(set_attr "type" "fpspc")
16665    (set_attr "mode" "XF")])
16666
16667 (define_insn "fxtract_extend<mode>xf3_i387"
16668   [(set (match_operand:XF 0 "register_operand" "=f")
16669         (unspec:XF [(float_extend:XF
16670                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16671                    UNSPEC_XTRACT_FRACT))
16672    (set (match_operand:XF 1 "register_operand" "=u")
16673         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16674   "TARGET_USE_FANCY_MATH_387
16675    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16676        || TARGET_MIX_SSE_I387)
16677    && flag_unsafe_math_optimizations"
16678   "fxtract"
16679   [(set_attr "type" "fpspc")
16680    (set_attr "mode" "XF")])
16681
16682 (define_expand "logbxf2"
16683   [(parallel [(set (match_dup 2)
16684                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16685                               UNSPEC_XTRACT_FRACT))
16686               (set (match_operand:XF 0 "register_operand" "")
16687                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16688   "TARGET_USE_FANCY_MATH_387
16689    && flag_unsafe_math_optimizations"
16690 {
16691   operands[2] = gen_reg_rtx (XFmode);
16692 })
16693
16694 (define_expand "logb<mode>2"
16695   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16696    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16697   "TARGET_USE_FANCY_MATH_387
16698    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16699        || TARGET_MIX_SSE_I387)
16700    && flag_unsafe_math_optimizations"
16701 {
16702   rtx op0 = gen_reg_rtx (XFmode);
16703   rtx op1 = gen_reg_rtx (XFmode);
16704
16705   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16706   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16707   DONE;
16708 })
16709
16710 (define_expand "ilogbxf2"
16711   [(use (match_operand:SI 0 "register_operand" ""))
16712    (use (match_operand:XF 1 "register_operand" ""))]
16713   "TARGET_USE_FANCY_MATH_387
16714    && flag_unsafe_math_optimizations && !optimize_size"
16715 {
16716   rtx op0 = gen_reg_rtx (XFmode);
16717   rtx op1 = gen_reg_rtx (XFmode);
16718
16719   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16720   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16721   DONE;
16722 })
16723
16724 (define_expand "ilogb<mode>2"
16725   [(use (match_operand:SI 0 "register_operand" ""))
16726    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16727   "TARGET_USE_FANCY_MATH_387
16728    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16729        || TARGET_MIX_SSE_I387)
16730    && flag_unsafe_math_optimizations && !optimize_size"
16731 {
16732   rtx op0 = gen_reg_rtx (XFmode);
16733   rtx op1 = gen_reg_rtx (XFmode);
16734
16735   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16736   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16737   DONE;
16738 })
16739
16740 (define_insn "*f2xm1xf2_i387"
16741   [(set (match_operand:XF 0 "register_operand" "=f")
16742         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16743                    UNSPEC_F2XM1))]
16744   "TARGET_USE_FANCY_MATH_387
16745    && flag_unsafe_math_optimizations"
16746   "f2xm1"
16747   [(set_attr "type" "fpspc")
16748    (set_attr "mode" "XF")])
16749
16750 (define_insn "*fscalexf4_i387"
16751   [(set (match_operand:XF 0 "register_operand" "=f")
16752         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16753                     (match_operand:XF 3 "register_operand" "1")]
16754                    UNSPEC_FSCALE_FRACT))
16755    (set (match_operand:XF 1 "register_operand" "=u")
16756         (unspec:XF [(match_dup 2) (match_dup 3)]
16757                    UNSPEC_FSCALE_EXP))]
16758   "TARGET_USE_FANCY_MATH_387
16759    && flag_unsafe_math_optimizations"
16760   "fscale"
16761   [(set_attr "type" "fpspc")
16762    (set_attr "mode" "XF")])
16763
16764 (define_expand "expNcorexf3"
16765   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16766                                (match_operand:XF 2 "register_operand" "")))
16767    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16768    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16769    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16770    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16771    (parallel [(set (match_operand:XF 0 "register_operand" "")
16772                    (unspec:XF [(match_dup 8) (match_dup 4)]
16773                               UNSPEC_FSCALE_FRACT))
16774               (set (match_dup 9)
16775                    (unspec:XF [(match_dup 8) (match_dup 4)]
16776                               UNSPEC_FSCALE_EXP))])]
16777   "TARGET_USE_FANCY_MATH_387
16778    && flag_unsafe_math_optimizations && !optimize_size"
16779 {
16780   int i;
16781
16782   for (i = 3; i < 10; i++)
16783     operands[i] = gen_reg_rtx (XFmode);
16784
16785   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16786 })
16787
16788 (define_expand "expxf2"
16789   [(use (match_operand:XF 0 "register_operand" ""))
16790    (use (match_operand:XF 1 "register_operand" ""))]
16791   "TARGET_USE_FANCY_MATH_387
16792    && flag_unsafe_math_optimizations && !optimize_size"
16793 {
16794   rtx op2 = gen_reg_rtx (XFmode);
16795   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16796
16797   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16798   DONE;
16799 })
16800
16801 (define_expand "exp<mode>2"
16802   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16803    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16804  "TARGET_USE_FANCY_MATH_387
16805    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16806        || TARGET_MIX_SSE_I387)
16807    && flag_unsafe_math_optimizations && !optimize_size"
16808 {
16809   rtx op0 = gen_reg_rtx (XFmode);
16810   rtx op1 = gen_reg_rtx (XFmode);
16811
16812   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16813   emit_insn (gen_expxf2 (op0, op1));
16814   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16815   DONE;
16816 })
16817
16818 (define_expand "exp10xf2"
16819   [(use (match_operand:XF 0 "register_operand" ""))
16820    (use (match_operand:XF 1 "register_operand" ""))]
16821   "TARGET_USE_FANCY_MATH_387
16822    && flag_unsafe_math_optimizations && !optimize_size"
16823 {
16824   rtx op2 = gen_reg_rtx (XFmode);
16825   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16826
16827   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16828   DONE;
16829 })
16830
16831 (define_expand "exp10<mode>2"
16832   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16833    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16834  "TARGET_USE_FANCY_MATH_387
16835    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16836        || TARGET_MIX_SSE_I387)
16837    && flag_unsafe_math_optimizations && !optimize_size"
16838 {
16839   rtx op0 = gen_reg_rtx (XFmode);
16840   rtx op1 = gen_reg_rtx (XFmode);
16841
16842   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16843   emit_insn (gen_exp10xf2 (op0, op1));
16844   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16845   DONE;
16846 })
16847
16848 (define_expand "exp2xf2"
16849   [(use (match_operand:XF 0 "register_operand" ""))
16850    (use (match_operand:XF 1 "register_operand" ""))]
16851   "TARGET_USE_FANCY_MATH_387
16852    && flag_unsafe_math_optimizations && !optimize_size"
16853 {
16854   rtx op2 = gen_reg_rtx (XFmode);
16855   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
16856
16857   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16858   DONE;
16859 })
16860
16861 (define_expand "exp2<mode>2"
16862   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16863    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16864  "TARGET_USE_FANCY_MATH_387
16865    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16866        || TARGET_MIX_SSE_I387)
16867    && flag_unsafe_math_optimizations && !optimize_size"
16868 {
16869   rtx op0 = gen_reg_rtx (XFmode);
16870   rtx op1 = gen_reg_rtx (XFmode);
16871
16872   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16873   emit_insn (gen_exp2xf2 (op0, op1));
16874   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16875   DONE;
16876 })
16877
16878 (define_expand "expm1xf2"
16879   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16880                                (match_dup 2)))
16881    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16882    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16883    (set (match_dup 9) (float_extend:XF (match_dup 13)))
16884    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16885    (parallel [(set (match_dup 7)
16886                    (unspec:XF [(match_dup 6) (match_dup 4)]
16887                               UNSPEC_FSCALE_FRACT))
16888               (set (match_dup 8)
16889                    (unspec:XF [(match_dup 6) (match_dup 4)]
16890                               UNSPEC_FSCALE_EXP))])
16891    (parallel [(set (match_dup 10)
16892                    (unspec:XF [(match_dup 9) (match_dup 8)]
16893                               UNSPEC_FSCALE_FRACT))
16894               (set (match_dup 11)
16895                    (unspec:XF [(match_dup 9) (match_dup 8)]
16896                               UNSPEC_FSCALE_EXP))])
16897    (set (match_dup 12) (minus:XF (match_dup 10)
16898                                  (float_extend:XF (match_dup 13))))
16899    (set (match_operand:XF 0 "register_operand" "")
16900         (plus:XF (match_dup 12) (match_dup 7)))]
16901   "TARGET_USE_FANCY_MATH_387
16902    && flag_unsafe_math_optimizations && !optimize_size"
16903 {
16904   int i;
16905
16906   for (i = 2; i < 13; i++)
16907     operands[i] = gen_reg_rtx (XFmode);
16908
16909   operands[13]
16910     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
16911
16912   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16913 })
16914
16915 (define_expand "expm1<mode>2"
16916   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16917    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16918  "TARGET_USE_FANCY_MATH_387
16919    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16920        || TARGET_MIX_SSE_I387)
16921    && flag_unsafe_math_optimizations && !optimize_size"
16922 {
16923   rtx op0 = gen_reg_rtx (XFmode);
16924   rtx op1 = gen_reg_rtx (XFmode);
16925
16926   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16927   emit_insn (gen_expm1xf2 (op0, op1));
16928   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16929   DONE;
16930 })
16931
16932 (define_expand "ldexpxf3"
16933   [(set (match_dup 3)
16934         (float:XF (match_operand:SI 2 "register_operand" "")))
16935    (parallel [(set (match_operand:XF 0 " register_operand" "")
16936                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16937                                (match_dup 3)]
16938                               UNSPEC_FSCALE_FRACT))
16939               (set (match_dup 4)
16940                    (unspec:XF [(match_dup 1) (match_dup 3)]
16941                               UNSPEC_FSCALE_EXP))])]
16942   "TARGET_USE_FANCY_MATH_387
16943    && flag_unsafe_math_optimizations && !optimize_size"
16944 {
16945   operands[3] = gen_reg_rtx (XFmode);
16946   operands[4] = gen_reg_rtx (XFmode);
16947 })
16948
16949 (define_expand "ldexp<mode>3"
16950   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16951    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16952    (use (match_operand:SI 2 "register_operand" ""))]
16953  "TARGET_USE_FANCY_MATH_387
16954    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16955        || TARGET_MIX_SSE_I387)
16956    && flag_unsafe_math_optimizations && !optimize_size"
16957 {
16958   rtx op0 = gen_reg_rtx (XFmode);
16959   rtx op1 = gen_reg_rtx (XFmode);
16960
16961   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16962   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16963   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16964   DONE;
16965 })
16966
16967 (define_expand "scalbxf3"
16968   [(parallel [(set (match_operand:XF 0 " register_operand" "")
16969                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16970                                (match_operand:XF 2 "register_operand" "")]
16971                               UNSPEC_FSCALE_FRACT))
16972               (set (match_dup 3)
16973                    (unspec:XF [(match_dup 1) (match_dup 2)]
16974                               UNSPEC_FSCALE_EXP))])]
16975   "TARGET_USE_FANCY_MATH_387
16976    && flag_unsafe_math_optimizations && !optimize_size"
16977 {
16978   operands[3] = gen_reg_rtx (XFmode);
16979 })
16980
16981 (define_expand "scalb<mode>3"
16982   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16983    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16984    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16985  "TARGET_USE_FANCY_MATH_387
16986    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16987        || TARGET_MIX_SSE_I387)
16988    && flag_unsafe_math_optimizations && !optimize_size"
16989 {
16990   rtx op0 = gen_reg_rtx (XFmode);
16991   rtx op1 = gen_reg_rtx (XFmode);
16992   rtx op2 = gen_reg_rtx (XFmode);
16993
16994   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16995   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16996   emit_insn (gen_scalbxf3 (op0, op1, op2));
16997   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16998   DONE;
16999 })
17000 \f
17001
17002 (define_insn "rintxf2"
17003   [(set (match_operand:XF 0 "register_operand" "=f")
17004         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17005                    UNSPEC_FRNDINT))]
17006   "TARGET_USE_FANCY_MATH_387
17007    && flag_unsafe_math_optimizations"
17008   "frndint"
17009   [(set_attr "type" "fpspc")
17010    (set_attr "mode" "XF")])
17011
17012 (define_expand "rint<mode>2"
17013   [(use (match_operand:SSEMODEF 0 "register_operand" ""))
17014    (use (match_operand:SSEMODEF 1 "register_operand" ""))]
17015   "(TARGET_USE_FANCY_MATH_387
17016     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17017         || TARGET_MIX_SSE_I387)
17018     && flag_unsafe_math_optimizations)
17019    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17020        && !flag_trapping_math
17021        && !optimize_size)"
17022 {
17023   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17024       && !flag_trapping_math
17025       && !optimize_size)
17026     ix86_expand_rint (operand0, operand1);
17027   else
17028     {
17029       rtx op0 = gen_reg_rtx (XFmode);
17030       rtx op1 = gen_reg_rtx (XFmode);
17031
17032       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17033       emit_insn (gen_rintxf2 (op0, op1));
17034
17035       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17036     }
17037   DONE;
17038 })
17039
17040 (define_expand "round<mode>2"
17041   [(match_operand:SSEMODEF 0 "register_operand" "")
17042    (match_operand:SSEMODEF 1 "nonimmediate_operand" "")]
17043   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17044    && !flag_trapping_math && !flag_rounding_math
17045    && !optimize_size"
17046 {
17047   if ((<MODE>mode != DFmode) || TARGET_64BIT)
17048     ix86_expand_round (operand0, operand1);
17049   else
17050     ix86_expand_rounddf_32 (operand0, operand1);
17051   DONE;
17052 })
17053
17054 (define_insn_and_split "*fistdi2_1"
17055   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17056         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17057                    UNSPEC_FIST))]
17058   "TARGET_USE_FANCY_MATH_387
17059    && !(reload_completed || reload_in_progress)"
17060   "#"
17061   "&& 1"
17062   [(const_int 0)]
17063 {
17064   if (memory_operand (operands[0], VOIDmode))
17065     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17066   else
17067     {
17068       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17069       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17070                                          operands[2]));
17071     }
17072   DONE;
17073 }
17074   [(set_attr "type" "fpspc")
17075    (set_attr "mode" "DI")])
17076
17077 (define_insn "fistdi2"
17078   [(set (match_operand:DI 0 "memory_operand" "=m")
17079         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17080                    UNSPEC_FIST))
17081    (clobber (match_scratch:XF 2 "=&1f"))]
17082   "TARGET_USE_FANCY_MATH_387"
17083   "* return output_fix_trunc (insn, operands, 0);"
17084   [(set_attr "type" "fpspc")
17085    (set_attr "mode" "DI")])
17086
17087 (define_insn "fistdi2_with_temp"
17088   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17089         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17090                    UNSPEC_FIST))
17091    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17092    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17093   "TARGET_USE_FANCY_MATH_387"
17094   "#"
17095   [(set_attr "type" "fpspc")
17096    (set_attr "mode" "DI")])
17097
17098 (define_split
17099   [(set (match_operand:DI 0 "register_operand" "")
17100         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17101                    UNSPEC_FIST))
17102    (clobber (match_operand:DI 2 "memory_operand" ""))
17103    (clobber (match_scratch 3 ""))]
17104   "reload_completed"
17105   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17106               (clobber (match_dup 3))])
17107    (set (match_dup 0) (match_dup 2))]
17108   "")
17109
17110 (define_split
17111   [(set (match_operand:DI 0 "memory_operand" "")
17112         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17113                    UNSPEC_FIST))
17114    (clobber (match_operand:DI 2 "memory_operand" ""))
17115    (clobber (match_scratch 3 ""))]
17116   "reload_completed"
17117   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17118               (clobber (match_dup 3))])]
17119   "")
17120
17121 (define_insn_and_split "*fist<mode>2_1"
17122   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17123         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17124                            UNSPEC_FIST))]
17125   "TARGET_USE_FANCY_MATH_387
17126    && !(reload_completed || reload_in_progress)"
17127   "#"
17128   "&& 1"
17129   [(const_int 0)]
17130 {
17131   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17132   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17133                                         operands[2]));
17134   DONE;
17135 }
17136   [(set_attr "type" "fpspc")
17137    (set_attr "mode" "<MODE>")])
17138
17139 (define_insn "fist<mode>2"
17140   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17141         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17142                            UNSPEC_FIST))]
17143   "TARGET_USE_FANCY_MATH_387"
17144   "* return output_fix_trunc (insn, operands, 0);"
17145   [(set_attr "type" "fpspc")
17146    (set_attr "mode" "<MODE>")])
17147
17148 (define_insn "fist<mode>2_with_temp"
17149   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17150         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17151                            UNSPEC_FIST))
17152    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17153   "TARGET_USE_FANCY_MATH_387"
17154   "#"
17155   [(set_attr "type" "fpspc")
17156    (set_attr "mode" "<MODE>")])
17157
17158 (define_split
17159   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17160         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17161                            UNSPEC_FIST))
17162    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17163   "reload_completed"
17164   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17165    (set (match_dup 0) (match_dup 2))]
17166   "")
17167
17168 (define_split
17169   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17170         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17171                            UNSPEC_FIST))
17172    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17173   "reload_completed"
17174   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17175   "")
17176
17177 (define_expand "lrintxf<mode>2"
17178   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17179      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17180                       UNSPEC_FIST))]
17181   "TARGET_USE_FANCY_MATH_387"
17182   "")
17183
17184 (define_expand "lrint<SSEMODEF:mode><SSEMODEI24:mode>2"
17185   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17186      (unspec:SSEMODEI24 [(match_operand:SSEMODEF 1 "register_operand" "")]
17187                         UNSPEC_FIX_NOTRUNC))]
17188   "SSE_FLOAT_MODE_P (<SSEMODEF:MODE>mode) && TARGET_SSE_MATH
17189    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17190   "")
17191
17192 (define_expand "lround<SSEMODEF:mode><SSEMODEI24:mode>2"
17193   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17194    (match_operand:SSEMODEF 1 "register_operand" "")]
17195   "SSE_FLOAT_MODE_P (<SSEMODEF:MODE>mode) && TARGET_SSE_MATH
17196    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17197    && !flag_trapping_math && !flag_rounding_math
17198    && !optimize_size"
17199 {
17200   ix86_expand_lround (operand0, operand1);
17201   DONE;
17202 })
17203
17204 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17205 (define_insn_and_split "frndintxf2_floor"
17206   [(set (match_operand:XF 0 "register_operand" "=f")
17207         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17208          UNSPEC_FRNDINT_FLOOR))
17209    (clobber (reg:CC FLAGS_REG))]
17210   "TARGET_USE_FANCY_MATH_387
17211    && flag_unsafe_math_optimizations
17212    && !(reload_completed || reload_in_progress)"
17213   "#"
17214   "&& 1"
17215   [(const_int 0)]
17216 {
17217   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17218
17219   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17220   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17221
17222   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17223                                         operands[2], operands[3]));
17224   DONE;
17225 }
17226   [(set_attr "type" "frndint")
17227    (set_attr "i387_cw" "floor")
17228    (set_attr "mode" "XF")])
17229
17230 (define_insn "frndintxf2_floor_i387"
17231   [(set (match_operand:XF 0 "register_operand" "=f")
17232         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17233          UNSPEC_FRNDINT_FLOOR))
17234    (use (match_operand:HI 2 "memory_operand" "m"))
17235    (use (match_operand:HI 3 "memory_operand" "m"))]
17236   "TARGET_USE_FANCY_MATH_387
17237    && flag_unsafe_math_optimizations"
17238   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17239   [(set_attr "type" "frndint")
17240    (set_attr "i387_cw" "floor")
17241    (set_attr "mode" "XF")])
17242
17243 (define_expand "floorxf2"
17244   [(use (match_operand:XF 0 "register_operand" ""))
17245    (use (match_operand:XF 1 "register_operand" ""))]
17246   "TARGET_USE_FANCY_MATH_387
17247    && flag_unsafe_math_optimizations && !optimize_size"
17248 {
17249   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17250   DONE;
17251 })
17252
17253 (define_expand "floordf2"
17254   [(use (match_operand:DF 0 "register_operand" ""))
17255    (use (match_operand:DF 1 "register_operand" ""))]
17256   "((TARGET_USE_FANCY_MATH_387
17257      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17258      && flag_unsafe_math_optimizations)
17259     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17260         && !flag_trapping_math))
17261    && !optimize_size"
17262 {
17263   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17264       && !flag_trapping_math)
17265     {
17266       if (TARGET_64BIT)
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_extenddfxf2 (op1, operands[1]));
17277       emit_insn (gen_frndintxf2_floor (op0, op1));
17278
17279       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17280     }
17281   DONE;
17282 })
17283
17284 (define_expand "floorsf2"
17285   [(use (match_operand:SF 0 "register_operand" ""))
17286    (use (match_operand:SF 1 "register_operand" ""))]
17287   "((TARGET_USE_FANCY_MATH_387
17288      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17289      && flag_unsafe_math_optimizations)
17290     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17291         && !flag_trapping_math))
17292    && !optimize_size"
17293 {
17294   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17295       && !flag_trapping_math)
17296     ix86_expand_floorceil (operand0, operand1, true);
17297   else
17298     {
17299       rtx op0 = gen_reg_rtx (XFmode);
17300       rtx op1 = gen_reg_rtx (XFmode);
17301
17302       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17303       emit_insn (gen_frndintxf2_floor (op0, op1));
17304
17305       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17306     }
17307   DONE;
17308 })
17309
17310 (define_insn_and_split "*fist<mode>2_floor_1"
17311   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17312         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17313          UNSPEC_FIST_FLOOR))
17314    (clobber (reg:CC FLAGS_REG))]
17315   "TARGET_USE_FANCY_MATH_387
17316    && flag_unsafe_math_optimizations
17317    && !(reload_completed || reload_in_progress)"
17318   "#"
17319   "&& 1"
17320   [(const_int 0)]
17321 {
17322   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17323
17324   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17325   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17326   if (memory_operand (operands[0], VOIDmode))
17327     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17328                                       operands[2], operands[3]));
17329   else
17330     {
17331       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17332       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17333                                                   operands[2], operands[3],
17334                                                   operands[4]));
17335     }
17336   DONE;
17337 }
17338   [(set_attr "type" "fistp")
17339    (set_attr "i387_cw" "floor")
17340    (set_attr "mode" "<MODE>")])
17341
17342 (define_insn "fistdi2_floor"
17343   [(set (match_operand:DI 0 "memory_operand" "=m")
17344         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17345          UNSPEC_FIST_FLOOR))
17346    (use (match_operand:HI 2 "memory_operand" "m"))
17347    (use (match_operand:HI 3 "memory_operand" "m"))
17348    (clobber (match_scratch:XF 4 "=&1f"))]
17349   "TARGET_USE_FANCY_MATH_387
17350    && flag_unsafe_math_optimizations"
17351   "* return output_fix_trunc (insn, operands, 0);"
17352   [(set_attr "type" "fistp")
17353    (set_attr "i387_cw" "floor")
17354    (set_attr "mode" "DI")])
17355
17356 (define_insn "fistdi2_floor_with_temp"
17357   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17358         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17359          UNSPEC_FIST_FLOOR))
17360    (use (match_operand:HI 2 "memory_operand" "m,m"))
17361    (use (match_operand:HI 3 "memory_operand" "m,m"))
17362    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17363    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17364   "TARGET_USE_FANCY_MATH_387
17365    && flag_unsafe_math_optimizations"
17366   "#"
17367   [(set_attr "type" "fistp")
17368    (set_attr "i387_cw" "floor")
17369    (set_attr "mode" "DI")])
17370
17371 (define_split
17372   [(set (match_operand:DI 0 "register_operand" "")
17373         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17374          UNSPEC_FIST_FLOOR))
17375    (use (match_operand:HI 2 "memory_operand" ""))
17376    (use (match_operand:HI 3 "memory_operand" ""))
17377    (clobber (match_operand:DI 4 "memory_operand" ""))
17378    (clobber (match_scratch 5 ""))]
17379   "reload_completed"
17380   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17381               (use (match_dup 2))
17382               (use (match_dup 3))
17383               (clobber (match_dup 5))])
17384    (set (match_dup 0) (match_dup 4))]
17385   "")
17386
17387 (define_split
17388   [(set (match_operand:DI 0 "memory_operand" "")
17389         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17390          UNSPEC_FIST_FLOOR))
17391    (use (match_operand:HI 2 "memory_operand" ""))
17392    (use (match_operand:HI 3 "memory_operand" ""))
17393    (clobber (match_operand:DI 4 "memory_operand" ""))
17394    (clobber (match_scratch 5 ""))]
17395   "reload_completed"
17396   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17397               (use (match_dup 2))
17398               (use (match_dup 3))
17399               (clobber (match_dup 5))])]
17400   "")
17401
17402 (define_insn "fist<mode>2_floor"
17403   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17404         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17405          UNSPEC_FIST_FLOOR))
17406    (use (match_operand:HI 2 "memory_operand" "m"))
17407    (use (match_operand:HI 3 "memory_operand" "m"))]
17408   "TARGET_USE_FANCY_MATH_387
17409    && flag_unsafe_math_optimizations"
17410   "* return output_fix_trunc (insn, operands, 0);"
17411   [(set_attr "type" "fistp")
17412    (set_attr "i387_cw" "floor")
17413    (set_attr "mode" "<MODE>")])
17414
17415 (define_insn "fist<mode>2_floor_with_temp"
17416   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17417         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17418          UNSPEC_FIST_FLOOR))
17419    (use (match_operand:HI 2 "memory_operand" "m,m"))
17420    (use (match_operand:HI 3 "memory_operand" "m,m"))
17421    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17422   "TARGET_USE_FANCY_MATH_387
17423    && flag_unsafe_math_optimizations"
17424   "#"
17425   [(set_attr "type" "fistp")
17426    (set_attr "i387_cw" "floor")
17427    (set_attr "mode" "<MODE>")])
17428
17429 (define_split
17430   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17431         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17432          UNSPEC_FIST_FLOOR))
17433    (use (match_operand:HI 2 "memory_operand" ""))
17434    (use (match_operand:HI 3 "memory_operand" ""))
17435    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17436   "reload_completed"
17437   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17438                                   UNSPEC_FIST_FLOOR))
17439               (use (match_dup 2))
17440               (use (match_dup 3))])
17441    (set (match_dup 0) (match_dup 4))]
17442   "")
17443
17444 (define_split
17445   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17446         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17447          UNSPEC_FIST_FLOOR))
17448    (use (match_operand:HI 2 "memory_operand" ""))
17449    (use (match_operand:HI 3 "memory_operand" ""))
17450    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17451   "reload_completed"
17452   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17453                                   UNSPEC_FIST_FLOOR))
17454               (use (match_dup 2))
17455               (use (match_dup 3))])]
17456   "")
17457
17458 (define_expand "lfloorxf<mode>2"
17459   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17460                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17461                     UNSPEC_FIST_FLOOR))
17462               (clobber (reg:CC FLAGS_REG))])]
17463   "TARGET_USE_FANCY_MATH_387
17464    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17465    && flag_unsafe_math_optimizations"
17466   "")
17467
17468 (define_expand "lfloor<mode>di2"
17469   [(match_operand:DI 0 "nonimmediate_operand" "")
17470    (match_operand:SSEMODEF 1 "register_operand" "")]
17471   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17472    && !flag_trapping_math
17473    && !optimize_size"
17474 {
17475   ix86_expand_lfloorceil (operand0, operand1, true);
17476   DONE;
17477 })
17478
17479 (define_expand "lfloor<mode>si2"
17480   [(match_operand:SI 0 "nonimmediate_operand" "")
17481    (match_operand:SSEMODEF 1 "register_operand" "")]
17482   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17483    && !flag_trapping_math
17484    && (!optimize_size || !TARGET_64BIT)"
17485 {
17486   ix86_expand_lfloorceil (operand0, operand1, true);
17487   DONE;
17488 })
17489
17490 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17491 (define_insn_and_split "frndintxf2_ceil"
17492   [(set (match_operand:XF 0 "register_operand" "=f")
17493         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17494          UNSPEC_FRNDINT_CEIL))
17495    (clobber (reg:CC FLAGS_REG))]
17496   "TARGET_USE_FANCY_MATH_387
17497    && flag_unsafe_math_optimizations
17498    && !(reload_completed || reload_in_progress)"
17499   "#"
17500   "&& 1"
17501   [(const_int 0)]
17502 {
17503   ix86_optimize_mode_switching[I387_CEIL] = 1;
17504
17505   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17506   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17507
17508   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17509                                        operands[2], operands[3]));
17510   DONE;
17511 }
17512   [(set_attr "type" "frndint")
17513    (set_attr "i387_cw" "ceil")
17514    (set_attr "mode" "XF")])
17515
17516 (define_insn "frndintxf2_ceil_i387"
17517   [(set (match_operand:XF 0 "register_operand" "=f")
17518         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17519          UNSPEC_FRNDINT_CEIL))
17520    (use (match_operand:HI 2 "memory_operand" "m"))
17521    (use (match_operand:HI 3 "memory_operand" "m"))]
17522   "TARGET_USE_FANCY_MATH_387
17523    && flag_unsafe_math_optimizations"
17524   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17525   [(set_attr "type" "frndint")
17526    (set_attr "i387_cw" "ceil")
17527    (set_attr "mode" "XF")])
17528
17529 (define_expand "ceilxf2"
17530   [(use (match_operand:XF 0 "register_operand" ""))
17531    (use (match_operand:XF 1 "register_operand" ""))]
17532   "TARGET_USE_FANCY_MATH_387
17533    && flag_unsafe_math_optimizations && !optimize_size"
17534 {
17535   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17536   DONE;
17537 })
17538
17539 (define_expand "ceildf2"
17540   [(use (match_operand:DF 0 "register_operand" ""))
17541    (use (match_operand:DF 1 "register_operand" ""))]
17542   "((TARGET_USE_FANCY_MATH_387
17543      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17544      && flag_unsafe_math_optimizations)
17545     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17546         && !flag_trapping_math))
17547    && !optimize_size"
17548 {
17549   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17550       && !flag_trapping_math)
17551     {
17552       if (TARGET_64BIT)
17553         ix86_expand_floorceil (operand0, operand1, false);
17554       else
17555         ix86_expand_floorceildf_32 (operand0, operand1, false);
17556     }
17557   else
17558     {
17559       rtx op0 = gen_reg_rtx (XFmode);
17560       rtx op1 = gen_reg_rtx (XFmode);
17561
17562       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17563       emit_insn (gen_frndintxf2_ceil (op0, op1));
17564
17565       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17566     }
17567   DONE;
17568 })
17569
17570 (define_expand "ceilsf2"
17571   [(use (match_operand:SF 0 "register_operand" ""))
17572    (use (match_operand:SF 1 "register_operand" ""))]
17573   "((TARGET_USE_FANCY_MATH_387
17574      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17575      && flag_unsafe_math_optimizations)
17576     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17577         && !flag_trapping_math))
17578    && !optimize_size"
17579 {
17580   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17581       && !flag_trapping_math)
17582     ix86_expand_floorceil (operand0, operand1, false);
17583   else
17584     {
17585       rtx op0 = gen_reg_rtx (XFmode);
17586       rtx op1 = gen_reg_rtx (XFmode);
17587
17588       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17589       emit_insn (gen_frndintxf2_ceil (op0, op1));
17590
17591       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17592     }
17593   DONE;
17594 })
17595
17596 (define_insn_and_split "*fist<mode>2_ceil_1"
17597   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17598         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17599          UNSPEC_FIST_CEIL))
17600    (clobber (reg:CC FLAGS_REG))]
17601   "TARGET_USE_FANCY_MATH_387
17602    && flag_unsafe_math_optimizations
17603    && !(reload_completed || reload_in_progress)"
17604   "#"
17605   "&& 1"
17606   [(const_int 0)]
17607 {
17608   ix86_optimize_mode_switching[I387_CEIL] = 1;
17609
17610   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17611   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17612   if (memory_operand (operands[0], VOIDmode))
17613     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17614                                      operands[2], operands[3]));
17615   else
17616     {
17617       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17618       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17619                                                  operands[2], operands[3],
17620                                                  operands[4]));
17621     }
17622   DONE;
17623 }
17624   [(set_attr "type" "fistp")
17625    (set_attr "i387_cw" "ceil")
17626    (set_attr "mode" "<MODE>")])
17627
17628 (define_insn "fistdi2_ceil"
17629   [(set (match_operand:DI 0 "memory_operand" "=m")
17630         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17631          UNSPEC_FIST_CEIL))
17632    (use (match_operand:HI 2 "memory_operand" "m"))
17633    (use (match_operand:HI 3 "memory_operand" "m"))
17634    (clobber (match_scratch:XF 4 "=&1f"))]
17635   "TARGET_USE_FANCY_MATH_387
17636    && flag_unsafe_math_optimizations"
17637   "* return output_fix_trunc (insn, operands, 0);"
17638   [(set_attr "type" "fistp")
17639    (set_attr "i387_cw" "ceil")
17640    (set_attr "mode" "DI")])
17641
17642 (define_insn "fistdi2_ceil_with_temp"
17643   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17644         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17645          UNSPEC_FIST_CEIL))
17646    (use (match_operand:HI 2 "memory_operand" "m,m"))
17647    (use (match_operand:HI 3 "memory_operand" "m,m"))
17648    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17649    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17650   "TARGET_USE_FANCY_MATH_387
17651    && flag_unsafe_math_optimizations"
17652   "#"
17653   [(set_attr "type" "fistp")
17654    (set_attr "i387_cw" "ceil")
17655    (set_attr "mode" "DI")])
17656
17657 (define_split
17658   [(set (match_operand:DI 0 "register_operand" "")
17659         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17660          UNSPEC_FIST_CEIL))
17661    (use (match_operand:HI 2 "memory_operand" ""))
17662    (use (match_operand:HI 3 "memory_operand" ""))
17663    (clobber (match_operand:DI 4 "memory_operand" ""))
17664    (clobber (match_scratch 5 ""))]
17665   "reload_completed"
17666   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17667               (use (match_dup 2))
17668               (use (match_dup 3))
17669               (clobber (match_dup 5))])
17670    (set (match_dup 0) (match_dup 4))]
17671   "")
17672
17673 (define_split
17674   [(set (match_operand:DI 0 "memory_operand" "")
17675         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17676          UNSPEC_FIST_CEIL))
17677    (use (match_operand:HI 2 "memory_operand" ""))
17678    (use (match_operand:HI 3 "memory_operand" ""))
17679    (clobber (match_operand:DI 4 "memory_operand" ""))
17680    (clobber (match_scratch 5 ""))]
17681   "reload_completed"
17682   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17683               (use (match_dup 2))
17684               (use (match_dup 3))
17685               (clobber (match_dup 5))])]
17686   "")
17687
17688 (define_insn "fist<mode>2_ceil"
17689   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17690         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17691          UNSPEC_FIST_CEIL))
17692    (use (match_operand:HI 2 "memory_operand" "m"))
17693    (use (match_operand:HI 3 "memory_operand" "m"))]
17694   "TARGET_USE_FANCY_MATH_387
17695    && flag_unsafe_math_optimizations"
17696   "* return output_fix_trunc (insn, operands, 0);"
17697   [(set_attr "type" "fistp")
17698    (set_attr "i387_cw" "ceil")
17699    (set_attr "mode" "<MODE>")])
17700
17701 (define_insn "fist<mode>2_ceil_with_temp"
17702   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17703         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17704          UNSPEC_FIST_CEIL))
17705    (use (match_operand:HI 2 "memory_operand" "m,m"))
17706    (use (match_operand:HI 3 "memory_operand" "m,m"))
17707    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17708   "TARGET_USE_FANCY_MATH_387
17709    && flag_unsafe_math_optimizations"
17710   "#"
17711   [(set_attr "type" "fistp")
17712    (set_attr "i387_cw" "ceil")
17713    (set_attr "mode" "<MODE>")])
17714
17715 (define_split
17716   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17717         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17718          UNSPEC_FIST_CEIL))
17719    (use (match_operand:HI 2 "memory_operand" ""))
17720    (use (match_operand:HI 3 "memory_operand" ""))
17721    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17722   "reload_completed"
17723   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17724                                   UNSPEC_FIST_CEIL))
17725               (use (match_dup 2))
17726               (use (match_dup 3))])
17727    (set (match_dup 0) (match_dup 4))]
17728   "")
17729
17730 (define_split
17731   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17732         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17733          UNSPEC_FIST_CEIL))
17734    (use (match_operand:HI 2 "memory_operand" ""))
17735    (use (match_operand:HI 3 "memory_operand" ""))
17736    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17737   "reload_completed"
17738   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17739                                   UNSPEC_FIST_CEIL))
17740               (use (match_dup 2))
17741               (use (match_dup 3))])]
17742   "")
17743
17744 (define_expand "lceilxf<mode>2"
17745   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17746                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17747                     UNSPEC_FIST_CEIL))
17748               (clobber (reg:CC FLAGS_REG))])]
17749   "TARGET_USE_FANCY_MATH_387
17750    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17751    && flag_unsafe_math_optimizations"
17752   "")
17753
17754 (define_expand "lceil<mode>di2"
17755   [(match_operand:DI 0 "nonimmediate_operand" "")
17756    (match_operand:SSEMODEF 1 "register_operand" "")]
17757   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17758    && !flag_trapping_math"
17759 {
17760   ix86_expand_lfloorceil (operand0, operand1, false);
17761   DONE;
17762 })
17763
17764 (define_expand "lceil<mode>si2"
17765   [(match_operand:SI 0 "nonimmediate_operand" "")
17766    (match_operand:SSEMODEF 1 "register_operand" "")]
17767   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17768    && !flag_trapping_math"
17769 {
17770   ix86_expand_lfloorceil (operand0, operand1, false);
17771   DONE;
17772 })
17773
17774 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17775 (define_insn_and_split "frndintxf2_trunc"
17776   [(set (match_operand:XF 0 "register_operand" "=f")
17777         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17778          UNSPEC_FRNDINT_TRUNC))
17779    (clobber (reg:CC FLAGS_REG))]
17780   "TARGET_USE_FANCY_MATH_387
17781    && flag_unsafe_math_optimizations
17782    && !(reload_completed || reload_in_progress)"
17783   "#"
17784   "&& 1"
17785   [(const_int 0)]
17786 {
17787   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17788
17789   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17790   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17791
17792   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17793                                         operands[2], operands[3]));
17794   DONE;
17795 }
17796   [(set_attr "type" "frndint")
17797    (set_attr "i387_cw" "trunc")
17798    (set_attr "mode" "XF")])
17799
17800 (define_insn "frndintxf2_trunc_i387"
17801   [(set (match_operand:XF 0 "register_operand" "=f")
17802         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17803          UNSPEC_FRNDINT_TRUNC))
17804    (use (match_operand:HI 2 "memory_operand" "m"))
17805    (use (match_operand:HI 3 "memory_operand" "m"))]
17806   "TARGET_USE_FANCY_MATH_387
17807    && flag_unsafe_math_optimizations"
17808   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17809   [(set_attr "type" "frndint")
17810    (set_attr "i387_cw" "trunc")
17811    (set_attr "mode" "XF")])
17812
17813 (define_expand "btruncxf2"
17814   [(use (match_operand:XF 0 "register_operand" ""))
17815    (use (match_operand:XF 1 "register_operand" ""))]
17816   "TARGET_USE_FANCY_MATH_387
17817    && flag_unsafe_math_optimizations && !optimize_size"
17818 {
17819   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17820   DONE;
17821 })
17822
17823 (define_expand "btruncdf2"
17824   [(use (match_operand:DF 0 "register_operand" ""))
17825    (use (match_operand:DF 1 "register_operand" ""))]
17826   "((TARGET_USE_FANCY_MATH_387
17827      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17828      && flag_unsafe_math_optimizations)
17829     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17830         && !flag_trapping_math))
17831    && !optimize_size"
17832 {
17833   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17834       && !flag_trapping_math)
17835     {
17836       if (TARGET_64BIT)
17837         ix86_expand_trunc (operand0, operand1);
17838       else
17839         ix86_expand_truncdf_32 (operand0, operand1);
17840     }
17841   else
17842     {
17843       rtx op0 = gen_reg_rtx (XFmode);
17844       rtx op1 = gen_reg_rtx (XFmode);
17845
17846       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17847       emit_insn (gen_frndintxf2_trunc (op0, op1));
17848
17849       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17850     }
17851   DONE;
17852 })
17853
17854 (define_expand "btruncsf2"
17855   [(use (match_operand:SF 0 "register_operand" ""))
17856    (use (match_operand:SF 1 "register_operand" ""))]
17857   "((TARGET_USE_FANCY_MATH_387
17858      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17859      && flag_unsafe_math_optimizations)
17860     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17861         && !flag_trapping_math))
17862    && !optimize_size"
17863 {
17864   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17865       && !flag_trapping_math)
17866     ix86_expand_trunc (operand0, operand1);
17867   else
17868     {
17869       rtx op0 = gen_reg_rtx (XFmode);
17870       rtx op1 = gen_reg_rtx (XFmode);
17871
17872       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17873       emit_insn (gen_frndintxf2_trunc (op0, op1));
17874
17875       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17876     }
17877   DONE;
17878 })
17879
17880 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17881 (define_insn_and_split "frndintxf2_mask_pm"
17882   [(set (match_operand:XF 0 "register_operand" "=f")
17883         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17884          UNSPEC_FRNDINT_MASK_PM))
17885    (clobber (reg:CC FLAGS_REG))]
17886   "TARGET_USE_FANCY_MATH_387
17887    && flag_unsafe_math_optimizations
17888    && !(reload_completed || reload_in_progress)"
17889   "#"
17890   "&& 1"
17891   [(const_int 0)]
17892 {
17893   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17894
17895   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17896   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17897
17898   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17899                                           operands[2], operands[3]));
17900   DONE;
17901 }
17902   [(set_attr "type" "frndint")
17903    (set_attr "i387_cw" "mask_pm")
17904    (set_attr "mode" "XF")])
17905
17906 (define_insn "frndintxf2_mask_pm_i387"
17907   [(set (match_operand:XF 0 "register_operand" "=f")
17908         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17909          UNSPEC_FRNDINT_MASK_PM))
17910    (use (match_operand:HI 2 "memory_operand" "m"))
17911    (use (match_operand:HI 3 "memory_operand" "m"))]
17912   "TARGET_USE_FANCY_MATH_387
17913    && flag_unsafe_math_optimizations"
17914   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17915   [(set_attr "type" "frndint")
17916    (set_attr "i387_cw" "mask_pm")
17917    (set_attr "mode" "XF")])
17918
17919 (define_expand "nearbyintxf2"
17920   [(use (match_operand:XF 0 "register_operand" ""))
17921    (use (match_operand:XF 1 "register_operand" ""))]
17922   "TARGET_USE_FANCY_MATH_387
17923    && flag_unsafe_math_optimizations"
17924 {
17925   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17926
17927   DONE;
17928 })
17929
17930 (define_expand "nearbyintdf2"
17931   [(use (match_operand:DF 0 "register_operand" ""))
17932    (use (match_operand:DF 1 "register_operand" ""))]
17933   "TARGET_USE_FANCY_MATH_387
17934    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17935    && flag_unsafe_math_optimizations"
17936 {
17937   rtx op0 = gen_reg_rtx (XFmode);
17938   rtx op1 = gen_reg_rtx (XFmode);
17939
17940   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17941   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17942
17943   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17944   DONE;
17945 })
17946
17947 (define_expand "nearbyintsf2"
17948   [(use (match_operand:SF 0 "register_operand" ""))
17949    (use (match_operand:SF 1 "register_operand" ""))]
17950   "TARGET_USE_FANCY_MATH_387
17951    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17952    && flag_unsafe_math_optimizations"
17953 {
17954   rtx op0 = gen_reg_rtx (XFmode);
17955   rtx op1 = gen_reg_rtx (XFmode);
17956
17957   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17958   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17959
17960   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17961   DONE;
17962 })
17963
17964 (define_insn "fxam<mode>2_i387"
17965   [(set (match_operand:HI 0 "register_operand" "=a")
17966         (unspec:HI
17967           [(match_operand:X87MODEF 1 "register_operand" "f")]
17968           UNSPEC_FXAM))]
17969   "TARGET_USE_FANCY_MATH_387"
17970   "fxam\n\tfnstsw\t%0"
17971   [(set_attr "type" "multi")
17972    (set_attr "unit" "i387")
17973    (set_attr "mode" "<MODE>")])
17974
17975 (define_expand "isinf<mode>2"
17976   [(use (match_operand:SI 0 "register_operand" ""))
17977    (use (match_operand:X87MODEF 1 "register_operand" ""))]
17978   "TARGET_USE_FANCY_MATH_387
17979    && TARGET_C99_FUNCTIONS
17980    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17981        || TARGET_MIX_SSE_I387)"
17982 {
17983   rtx mask = GEN_INT (0x45);
17984   rtx val = GEN_INT (0x05);
17985
17986   rtx cond;
17987
17988   rtx scratch = gen_reg_rtx (HImode);
17989   rtx res = gen_reg_rtx (QImode);
17990
17991   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
17992   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
17993   emit_insn (gen_cmpqi_ext_3 (scratch, val));
17994   cond = gen_rtx_fmt_ee (EQ, QImode,
17995                          gen_rtx_REG (CCmode, FLAGS_REG),
17996                          const0_rtx);
17997   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
17998   emit_insn (gen_zero_extendqisi2 (operands[0], res));
17999   DONE;
18000 })
18001
18002 \f
18003 ;; Block operation instructions
18004
18005 (define_expand "movmemsi"
18006   [(use (match_operand:BLK 0 "memory_operand" ""))
18007    (use (match_operand:BLK 1 "memory_operand" ""))
18008    (use (match_operand:SI 2 "nonmemory_operand" ""))
18009    (use (match_operand:SI 3 "const_int_operand" ""))
18010    (use (match_operand:SI 4 "const_int_operand" ""))
18011    (use (match_operand:SI 5 "const_int_operand" ""))]
18012   ""
18013 {
18014  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18015                          operands[4], operands[5]))
18016    DONE;
18017  else
18018    FAIL;
18019 })
18020
18021 (define_expand "movmemdi"
18022   [(use (match_operand:BLK 0 "memory_operand" ""))
18023    (use (match_operand:BLK 1 "memory_operand" ""))
18024    (use (match_operand:DI 2 "nonmemory_operand" ""))
18025    (use (match_operand:DI 3 "const_int_operand" ""))
18026    (use (match_operand:SI 4 "const_int_operand" ""))
18027    (use (match_operand:SI 5 "const_int_operand" ""))]
18028   "TARGET_64BIT"
18029 {
18030  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18031                          operands[4], operands[5]))
18032    DONE;
18033  else
18034    FAIL;
18035 })
18036
18037 ;; Most CPUs don't like single string operations
18038 ;; Handle this case here to simplify previous expander.
18039
18040 (define_expand "strmov"
18041   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18042    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18043    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18044               (clobber (reg:CC FLAGS_REG))])
18045    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18046               (clobber (reg:CC FLAGS_REG))])]
18047   ""
18048 {
18049   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18050
18051   /* If .md ever supports :P for Pmode, these can be directly
18052      in the pattern above.  */
18053   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18054   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18055
18056   if (TARGET_SINGLE_STRINGOP || optimize_size)
18057     {
18058       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18059                                       operands[2], operands[3],
18060                                       operands[5], operands[6]));
18061       DONE;
18062     }
18063
18064   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18065 })
18066
18067 (define_expand "strmov_singleop"
18068   [(parallel [(set (match_operand 1 "memory_operand" "")
18069                    (match_operand 3 "memory_operand" ""))
18070               (set (match_operand 0 "register_operand" "")
18071                    (match_operand 4 "" ""))
18072               (set (match_operand 2 "register_operand" "")
18073                    (match_operand 5 "" ""))])]
18074   "TARGET_SINGLE_STRINGOP || optimize_size"
18075   "")
18076
18077 (define_insn "*strmovdi_rex_1"
18078   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18079         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18080    (set (match_operand:DI 0 "register_operand" "=D")
18081         (plus:DI (match_dup 2)
18082                  (const_int 8)))
18083    (set (match_operand:DI 1 "register_operand" "=S")
18084         (plus:DI (match_dup 3)
18085                  (const_int 8)))]
18086   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18087   "movsq"
18088   [(set_attr "type" "str")
18089    (set_attr "mode" "DI")
18090    (set_attr "memory" "both")])
18091
18092 (define_insn "*strmovsi_1"
18093   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18094         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18095    (set (match_operand:SI 0 "register_operand" "=D")
18096         (plus:SI (match_dup 2)
18097                  (const_int 4)))
18098    (set (match_operand:SI 1 "register_operand" "=S")
18099         (plus:SI (match_dup 3)
18100                  (const_int 4)))]
18101   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18102   "{movsl|movsd}"
18103   [(set_attr "type" "str")
18104    (set_attr "mode" "SI")
18105    (set_attr "memory" "both")])
18106
18107 (define_insn "*strmovsi_rex_1"
18108   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18109         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18110    (set (match_operand:DI 0 "register_operand" "=D")
18111         (plus:DI (match_dup 2)
18112                  (const_int 4)))
18113    (set (match_operand:DI 1 "register_operand" "=S")
18114         (plus:DI (match_dup 3)
18115                  (const_int 4)))]
18116   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18117   "{movsl|movsd}"
18118   [(set_attr "type" "str")
18119    (set_attr "mode" "SI")
18120    (set_attr "memory" "both")])
18121
18122 (define_insn "*strmovhi_1"
18123   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18124         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18125    (set (match_operand:SI 0 "register_operand" "=D")
18126         (plus:SI (match_dup 2)
18127                  (const_int 2)))
18128    (set (match_operand:SI 1 "register_operand" "=S")
18129         (plus:SI (match_dup 3)
18130                  (const_int 2)))]
18131   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18132   "movsw"
18133   [(set_attr "type" "str")
18134    (set_attr "memory" "both")
18135    (set_attr "mode" "HI")])
18136
18137 (define_insn "*strmovhi_rex_1"
18138   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18139         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18140    (set (match_operand:DI 0 "register_operand" "=D")
18141         (plus:DI (match_dup 2)
18142                  (const_int 2)))
18143    (set (match_operand:DI 1 "register_operand" "=S")
18144         (plus:DI (match_dup 3)
18145                  (const_int 2)))]
18146   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18147   "movsw"
18148   [(set_attr "type" "str")
18149    (set_attr "memory" "both")
18150    (set_attr "mode" "HI")])
18151
18152 (define_insn "*strmovqi_1"
18153   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18154         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18155    (set (match_operand:SI 0 "register_operand" "=D")
18156         (plus:SI (match_dup 2)
18157                  (const_int 1)))
18158    (set (match_operand:SI 1 "register_operand" "=S")
18159         (plus:SI (match_dup 3)
18160                  (const_int 1)))]
18161   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18162   "movsb"
18163   [(set_attr "type" "str")
18164    (set_attr "memory" "both")
18165    (set_attr "mode" "QI")])
18166
18167 (define_insn "*strmovqi_rex_1"
18168   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18169         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18170    (set (match_operand:DI 0 "register_operand" "=D")
18171         (plus:DI (match_dup 2)
18172                  (const_int 1)))
18173    (set (match_operand:DI 1 "register_operand" "=S")
18174         (plus:DI (match_dup 3)
18175                  (const_int 1)))]
18176   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18177   "movsb"
18178   [(set_attr "type" "str")
18179    (set_attr "memory" "both")
18180    (set_attr "mode" "QI")])
18181
18182 (define_expand "rep_mov"
18183   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18184               (set (match_operand 0 "register_operand" "")
18185                    (match_operand 5 "" ""))
18186               (set (match_operand 2 "register_operand" "")
18187                    (match_operand 6 "" ""))
18188               (set (match_operand 1 "memory_operand" "")
18189                    (match_operand 3 "memory_operand" ""))
18190               (use (match_dup 4))])]
18191   ""
18192   "")
18193
18194 (define_insn "*rep_movdi_rex64"
18195   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18196    (set (match_operand:DI 0 "register_operand" "=D")
18197         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18198                             (const_int 3))
18199                  (match_operand:DI 3 "register_operand" "0")))
18200    (set (match_operand:DI 1 "register_operand" "=S")
18201         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18202                  (match_operand:DI 4 "register_operand" "1")))
18203    (set (mem:BLK (match_dup 3))
18204         (mem:BLK (match_dup 4)))
18205    (use (match_dup 5))]
18206   "TARGET_64BIT"
18207   "{rep\;movsq|rep movsq}"
18208   [(set_attr "type" "str")
18209    (set_attr "prefix_rep" "1")
18210    (set_attr "memory" "both")
18211    (set_attr "mode" "DI")])
18212
18213 (define_insn "*rep_movsi"
18214   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18215    (set (match_operand:SI 0 "register_operand" "=D")
18216         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18217                             (const_int 2))
18218                  (match_operand:SI 3 "register_operand" "0")))
18219    (set (match_operand:SI 1 "register_operand" "=S")
18220         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18221                  (match_operand:SI 4 "register_operand" "1")))
18222    (set (mem:BLK (match_dup 3))
18223         (mem:BLK (match_dup 4)))
18224    (use (match_dup 5))]
18225   "!TARGET_64BIT"
18226   "{rep\;movsl|rep movsd}"
18227   [(set_attr "type" "str")
18228    (set_attr "prefix_rep" "1")
18229    (set_attr "memory" "both")
18230    (set_attr "mode" "SI")])
18231
18232 (define_insn "*rep_movsi_rex64"
18233   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18234    (set (match_operand:DI 0 "register_operand" "=D")
18235         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18236                             (const_int 2))
18237                  (match_operand:DI 3 "register_operand" "0")))
18238    (set (match_operand:DI 1 "register_operand" "=S")
18239         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18240                  (match_operand:DI 4 "register_operand" "1")))
18241    (set (mem:BLK (match_dup 3))
18242         (mem:BLK (match_dup 4)))
18243    (use (match_dup 5))]
18244   "TARGET_64BIT"
18245   "{rep\;movsl|rep movsd}"
18246   [(set_attr "type" "str")
18247    (set_attr "prefix_rep" "1")
18248    (set_attr "memory" "both")
18249    (set_attr "mode" "SI")])
18250
18251 (define_insn "*rep_movqi"
18252   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18253    (set (match_operand:SI 0 "register_operand" "=D")
18254         (plus:SI (match_operand:SI 3 "register_operand" "0")
18255                  (match_operand:SI 5 "register_operand" "2")))
18256    (set (match_operand:SI 1 "register_operand" "=S")
18257         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18258    (set (mem:BLK (match_dup 3))
18259         (mem:BLK (match_dup 4)))
18260    (use (match_dup 5))]
18261   "!TARGET_64BIT"
18262   "{rep\;movsb|rep movsb}"
18263   [(set_attr "type" "str")
18264    (set_attr "prefix_rep" "1")
18265    (set_attr "memory" "both")
18266    (set_attr "mode" "SI")])
18267
18268 (define_insn "*rep_movqi_rex64"
18269   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18270    (set (match_operand:DI 0 "register_operand" "=D")
18271         (plus:DI (match_operand:DI 3 "register_operand" "0")
18272                  (match_operand:DI 5 "register_operand" "2")))
18273    (set (match_operand:DI 1 "register_operand" "=S")
18274         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18275    (set (mem:BLK (match_dup 3))
18276         (mem:BLK (match_dup 4)))
18277    (use (match_dup 5))]
18278   "TARGET_64BIT"
18279   "{rep\;movsb|rep movsb}"
18280   [(set_attr "type" "str")
18281    (set_attr "prefix_rep" "1")
18282    (set_attr "memory" "both")
18283    (set_attr "mode" "SI")])
18284
18285 (define_expand "setmemsi"
18286    [(use (match_operand:BLK 0 "memory_operand" ""))
18287     (use (match_operand:SI 1 "nonmemory_operand" ""))
18288     (use (match_operand 2 "const_int_operand" ""))
18289     (use (match_operand 3 "const_int_operand" ""))
18290     (use (match_operand:SI 4 "const_int_operand" ""))
18291     (use (match_operand:SI 5 "const_int_operand" ""))]
18292   ""
18293 {
18294  if (ix86_expand_setmem (operands[0], operands[1],
18295                          operands[2], operands[3],
18296                          operands[4], operands[5]))
18297    DONE;
18298  else
18299    FAIL;
18300 })
18301
18302 (define_expand "setmemdi"
18303    [(use (match_operand:BLK 0 "memory_operand" ""))
18304     (use (match_operand:DI 1 "nonmemory_operand" ""))
18305     (use (match_operand 2 "const_int_operand" ""))
18306     (use (match_operand 3 "const_int_operand" ""))
18307     (use (match_operand 4 "const_int_operand" ""))
18308     (use (match_operand 5 "const_int_operand" ""))]
18309   "TARGET_64BIT"
18310 {
18311  if (ix86_expand_setmem (operands[0], operands[1],
18312                          operands[2], operands[3],
18313                          operands[4], operands[5]))
18314    DONE;
18315  else
18316    FAIL;
18317 })
18318
18319 ;; Most CPUs don't like single string operations
18320 ;; Handle this case here to simplify previous expander.
18321
18322 (define_expand "strset"
18323   [(set (match_operand 1 "memory_operand" "")
18324         (match_operand 2 "register_operand" ""))
18325    (parallel [(set (match_operand 0 "register_operand" "")
18326                    (match_dup 3))
18327               (clobber (reg:CC FLAGS_REG))])]
18328   ""
18329 {
18330   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18331     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18332
18333   /* If .md ever supports :P for Pmode, this can be directly
18334      in the pattern above.  */
18335   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18336                               GEN_INT (GET_MODE_SIZE (GET_MODE
18337                                                       (operands[2]))));
18338   if (TARGET_SINGLE_STRINGOP || optimize_size)
18339     {
18340       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18341                                       operands[3]));
18342       DONE;
18343     }
18344 })
18345
18346 (define_expand "strset_singleop"
18347   [(parallel [(set (match_operand 1 "memory_operand" "")
18348                    (match_operand 2 "register_operand" ""))
18349               (set (match_operand 0 "register_operand" "")
18350                    (match_operand 3 "" ""))])]
18351   "TARGET_SINGLE_STRINGOP || optimize_size"
18352   "")
18353
18354 (define_insn "*strsetdi_rex_1"
18355   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18356         (match_operand:DI 2 "register_operand" "a"))
18357    (set (match_operand:DI 0 "register_operand" "=D")
18358         (plus:DI (match_dup 1)
18359                  (const_int 8)))]
18360   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18361   "stosq"
18362   [(set_attr "type" "str")
18363    (set_attr "memory" "store")
18364    (set_attr "mode" "DI")])
18365
18366 (define_insn "*strsetsi_1"
18367   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18368         (match_operand:SI 2 "register_operand" "a"))
18369    (set (match_operand:SI 0 "register_operand" "=D")
18370         (plus:SI (match_dup 1)
18371                  (const_int 4)))]
18372   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18373   "{stosl|stosd}"
18374   [(set_attr "type" "str")
18375    (set_attr "memory" "store")
18376    (set_attr "mode" "SI")])
18377
18378 (define_insn "*strsetsi_rex_1"
18379   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18380         (match_operand:SI 2 "register_operand" "a"))
18381    (set (match_operand:DI 0 "register_operand" "=D")
18382         (plus:DI (match_dup 1)
18383                  (const_int 4)))]
18384   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18385   "{stosl|stosd}"
18386   [(set_attr "type" "str")
18387    (set_attr "memory" "store")
18388    (set_attr "mode" "SI")])
18389
18390 (define_insn "*strsethi_1"
18391   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18392         (match_operand:HI 2 "register_operand" "a"))
18393    (set (match_operand:SI 0 "register_operand" "=D")
18394         (plus:SI (match_dup 1)
18395                  (const_int 2)))]
18396   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18397   "stosw"
18398   [(set_attr "type" "str")
18399    (set_attr "memory" "store")
18400    (set_attr "mode" "HI")])
18401
18402 (define_insn "*strsethi_rex_1"
18403   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18404         (match_operand:HI 2 "register_operand" "a"))
18405    (set (match_operand:DI 0 "register_operand" "=D")
18406         (plus:DI (match_dup 1)
18407                  (const_int 2)))]
18408   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18409   "stosw"
18410   [(set_attr "type" "str")
18411    (set_attr "memory" "store")
18412    (set_attr "mode" "HI")])
18413
18414 (define_insn "*strsetqi_1"
18415   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18416         (match_operand:QI 2 "register_operand" "a"))
18417    (set (match_operand:SI 0 "register_operand" "=D")
18418         (plus:SI (match_dup 1)
18419                  (const_int 1)))]
18420   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18421   "stosb"
18422   [(set_attr "type" "str")
18423    (set_attr "memory" "store")
18424    (set_attr "mode" "QI")])
18425
18426 (define_insn "*strsetqi_rex_1"
18427   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18428         (match_operand:QI 2 "register_operand" "a"))
18429    (set (match_operand:DI 0 "register_operand" "=D")
18430         (plus:DI (match_dup 1)
18431                  (const_int 1)))]
18432   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18433   "stosb"
18434   [(set_attr "type" "str")
18435    (set_attr "memory" "store")
18436    (set_attr "mode" "QI")])
18437
18438 (define_expand "rep_stos"
18439   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18440               (set (match_operand 0 "register_operand" "")
18441                    (match_operand 4 "" ""))
18442               (set (match_operand 2 "memory_operand" "") (const_int 0))
18443               (use (match_operand 3 "register_operand" ""))
18444               (use (match_dup 1))])]
18445   ""
18446   "")
18447
18448 (define_insn "*rep_stosdi_rex64"
18449   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18450    (set (match_operand:DI 0 "register_operand" "=D")
18451         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18452                             (const_int 3))
18453                  (match_operand:DI 3 "register_operand" "0")))
18454    (set (mem:BLK (match_dup 3))
18455         (const_int 0))
18456    (use (match_operand:DI 2 "register_operand" "a"))
18457    (use (match_dup 4))]
18458   "TARGET_64BIT"
18459   "{rep\;stosq|rep stosq}"
18460   [(set_attr "type" "str")
18461    (set_attr "prefix_rep" "1")
18462    (set_attr "memory" "store")
18463    (set_attr "mode" "DI")])
18464
18465 (define_insn "*rep_stossi"
18466   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18467    (set (match_operand:SI 0 "register_operand" "=D")
18468         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18469                             (const_int 2))
18470                  (match_operand:SI 3 "register_operand" "0")))
18471    (set (mem:BLK (match_dup 3))
18472         (const_int 0))
18473    (use (match_operand:SI 2 "register_operand" "a"))
18474    (use (match_dup 4))]
18475   "!TARGET_64BIT"
18476   "{rep\;stosl|rep stosd}"
18477   [(set_attr "type" "str")
18478    (set_attr "prefix_rep" "1")
18479    (set_attr "memory" "store")
18480    (set_attr "mode" "SI")])
18481
18482 (define_insn "*rep_stossi_rex64"
18483   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18484    (set (match_operand:DI 0 "register_operand" "=D")
18485         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18486                             (const_int 2))
18487                  (match_operand:DI 3 "register_operand" "0")))
18488    (set (mem:BLK (match_dup 3))
18489         (const_int 0))
18490    (use (match_operand:SI 2 "register_operand" "a"))
18491    (use (match_dup 4))]
18492   "TARGET_64BIT"
18493   "{rep\;stosl|rep stosd}"
18494   [(set_attr "type" "str")
18495    (set_attr "prefix_rep" "1")
18496    (set_attr "memory" "store")
18497    (set_attr "mode" "SI")])
18498
18499 (define_insn "*rep_stosqi"
18500   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18501    (set (match_operand:SI 0 "register_operand" "=D")
18502         (plus:SI (match_operand:SI 3 "register_operand" "0")
18503                  (match_operand:SI 4 "register_operand" "1")))
18504    (set (mem:BLK (match_dup 3))
18505         (const_int 0))
18506    (use (match_operand:QI 2 "register_operand" "a"))
18507    (use (match_dup 4))]
18508   "!TARGET_64BIT"
18509   "{rep\;stosb|rep stosb}"
18510   [(set_attr "type" "str")
18511    (set_attr "prefix_rep" "1")
18512    (set_attr "memory" "store")
18513    (set_attr "mode" "QI")])
18514
18515 (define_insn "*rep_stosqi_rex64"
18516   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18517    (set (match_operand:DI 0 "register_operand" "=D")
18518         (plus:DI (match_operand:DI 3 "register_operand" "0")
18519                  (match_operand:DI 4 "register_operand" "1")))
18520    (set (mem:BLK (match_dup 3))
18521         (const_int 0))
18522    (use (match_operand:QI 2 "register_operand" "a"))
18523    (use (match_dup 4))]
18524   "TARGET_64BIT"
18525   "{rep\;stosb|rep stosb}"
18526   [(set_attr "type" "str")
18527    (set_attr "prefix_rep" "1")
18528    (set_attr "memory" "store")
18529    (set_attr "mode" "QI")])
18530
18531 (define_expand "cmpstrnsi"
18532   [(set (match_operand:SI 0 "register_operand" "")
18533         (compare:SI (match_operand:BLK 1 "general_operand" "")
18534                     (match_operand:BLK 2 "general_operand" "")))
18535    (use (match_operand 3 "general_operand" ""))
18536    (use (match_operand 4 "immediate_operand" ""))]
18537   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18538 {
18539   rtx addr1, addr2, out, outlow, count, countreg, align;
18540
18541   /* Can't use this if the user has appropriated esi or edi.  */
18542   if (global_regs[4] || global_regs[5])
18543     FAIL;
18544
18545   out = operands[0];
18546   if (!REG_P (out))
18547     out = gen_reg_rtx (SImode);
18548
18549   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18550   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18551   if (addr1 != XEXP (operands[1], 0))
18552     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18553   if (addr2 != XEXP (operands[2], 0))
18554     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18555
18556   count = operands[3];
18557   countreg = ix86_zero_extend_to_Pmode (count);
18558
18559   /* %%% Iff we are testing strict equality, we can use known alignment
18560      to good advantage.  This may be possible with combine, particularly
18561      once cc0 is dead.  */
18562   align = operands[4];
18563
18564   if (CONST_INT_P (count))
18565     {
18566       if (INTVAL (count) == 0)
18567         {
18568           emit_move_insn (operands[0], const0_rtx);
18569           DONE;
18570         }
18571       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18572                                      operands[1], operands[2]));
18573     }
18574   else
18575     {
18576       if (TARGET_64BIT)
18577         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18578       else
18579         emit_insn (gen_cmpsi_1 (countreg, countreg));
18580       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18581                                   operands[1], operands[2]));
18582     }
18583
18584   outlow = gen_lowpart (QImode, out);
18585   emit_insn (gen_cmpintqi (outlow));
18586   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18587
18588   if (operands[0] != out)
18589     emit_move_insn (operands[0], out);
18590
18591   DONE;
18592 })
18593
18594 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18595
18596 (define_expand "cmpintqi"
18597   [(set (match_dup 1)
18598         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18599    (set (match_dup 2)
18600         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18601    (parallel [(set (match_operand:QI 0 "register_operand" "")
18602                    (minus:QI (match_dup 1)
18603                              (match_dup 2)))
18604               (clobber (reg:CC FLAGS_REG))])]
18605   ""
18606   "operands[1] = gen_reg_rtx (QImode);
18607    operands[2] = gen_reg_rtx (QImode);")
18608
18609 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18610 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18611
18612 (define_expand "cmpstrnqi_nz_1"
18613   [(parallel [(set (reg:CC FLAGS_REG)
18614                    (compare:CC (match_operand 4 "memory_operand" "")
18615                                (match_operand 5 "memory_operand" "")))
18616               (use (match_operand 2 "register_operand" ""))
18617               (use (match_operand:SI 3 "immediate_operand" ""))
18618               (clobber (match_operand 0 "register_operand" ""))
18619               (clobber (match_operand 1 "register_operand" ""))
18620               (clobber (match_dup 2))])]
18621   ""
18622   "")
18623
18624 (define_insn "*cmpstrnqi_nz_1"
18625   [(set (reg:CC FLAGS_REG)
18626         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18627                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18628    (use (match_operand:SI 6 "register_operand" "2"))
18629    (use (match_operand:SI 3 "immediate_operand" "i"))
18630    (clobber (match_operand:SI 0 "register_operand" "=S"))
18631    (clobber (match_operand:SI 1 "register_operand" "=D"))
18632    (clobber (match_operand:SI 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_insn "*cmpstrnqi_nz_rex_1"
18640   [(set (reg:CC FLAGS_REG)
18641         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18642                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18643    (use (match_operand:DI 6 "register_operand" "2"))
18644    (use (match_operand:SI 3 "immediate_operand" "i"))
18645    (clobber (match_operand:DI 0 "register_operand" "=S"))
18646    (clobber (match_operand:DI 1 "register_operand" "=D"))
18647    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18648   "TARGET_64BIT"
18649   "repz{\;| }cmpsb"
18650   [(set_attr "type" "str")
18651    (set_attr "mode" "QI")
18652    (set_attr "prefix_rep" "1")])
18653
18654 ;; The same, but the count is not known to not be zero.
18655
18656 (define_expand "cmpstrnqi_1"
18657   [(parallel [(set (reg:CC FLAGS_REG)
18658                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18659                                      (const_int 0))
18660                   (compare:CC (match_operand 4 "memory_operand" "")
18661                               (match_operand 5 "memory_operand" ""))
18662                   (const_int 0)))
18663               (use (match_operand:SI 3 "immediate_operand" ""))
18664               (use (reg:CC FLAGS_REG))
18665               (clobber (match_operand 0 "register_operand" ""))
18666               (clobber (match_operand 1 "register_operand" ""))
18667               (clobber (match_dup 2))])]
18668   ""
18669   "")
18670
18671 (define_insn "*cmpstrnqi_1"
18672   [(set (reg:CC FLAGS_REG)
18673         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18674                              (const_int 0))
18675           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18676                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18677           (const_int 0)))
18678    (use (match_operand:SI 3 "immediate_operand" "i"))
18679    (use (reg:CC FLAGS_REG))
18680    (clobber (match_operand:SI 0 "register_operand" "=S"))
18681    (clobber (match_operand:SI 1 "register_operand" "=D"))
18682    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18683   "!TARGET_64BIT"
18684   "repz{\;| }cmpsb"
18685   [(set_attr "type" "str")
18686    (set_attr "mode" "QI")
18687    (set_attr "prefix_rep" "1")])
18688
18689 (define_insn "*cmpstrnqi_rex_1"
18690   [(set (reg:CC FLAGS_REG)
18691         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18692                              (const_int 0))
18693           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18694                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18695           (const_int 0)))
18696    (use (match_operand:SI 3 "immediate_operand" "i"))
18697    (use (reg:CC FLAGS_REG))
18698    (clobber (match_operand:DI 0 "register_operand" "=S"))
18699    (clobber (match_operand:DI 1 "register_operand" "=D"))
18700    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18701   "TARGET_64BIT"
18702   "repz{\;| }cmpsb"
18703   [(set_attr "type" "str")
18704    (set_attr "mode" "QI")
18705    (set_attr "prefix_rep" "1")])
18706
18707 (define_expand "strlensi"
18708   [(set (match_operand:SI 0 "register_operand" "")
18709         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18710                     (match_operand:QI 2 "immediate_operand" "")
18711                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18712   ""
18713 {
18714  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18715    DONE;
18716  else
18717    FAIL;
18718 })
18719
18720 (define_expand "strlendi"
18721   [(set (match_operand:DI 0 "register_operand" "")
18722         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18723                     (match_operand:QI 2 "immediate_operand" "")
18724                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18725   ""
18726 {
18727  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18728    DONE;
18729  else
18730    FAIL;
18731 })
18732
18733 (define_expand "strlenqi_1"
18734   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18735               (clobber (match_operand 1 "register_operand" ""))
18736               (clobber (reg:CC FLAGS_REG))])]
18737   ""
18738   "")
18739
18740 (define_insn "*strlenqi_1"
18741   [(set (match_operand:SI 0 "register_operand" "=&c")
18742         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18743                     (match_operand:QI 2 "register_operand" "a")
18744                     (match_operand:SI 3 "immediate_operand" "i")
18745                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18746    (clobber (match_operand:SI 1 "register_operand" "=D"))
18747    (clobber (reg:CC FLAGS_REG))]
18748   "!TARGET_64BIT"
18749   "repnz{\;| }scasb"
18750   [(set_attr "type" "str")
18751    (set_attr "mode" "QI")
18752    (set_attr "prefix_rep" "1")])
18753
18754 (define_insn "*strlenqi_rex_1"
18755   [(set (match_operand:DI 0 "register_operand" "=&c")
18756         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18757                     (match_operand:QI 2 "register_operand" "a")
18758                     (match_operand:DI 3 "immediate_operand" "i")
18759                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18760    (clobber (match_operand:DI 1 "register_operand" "=D"))
18761    (clobber (reg:CC FLAGS_REG))]
18762   "TARGET_64BIT"
18763   "repnz{\;| }scasb"
18764   [(set_attr "type" "str")
18765    (set_attr "mode" "QI")
18766    (set_attr "prefix_rep" "1")])
18767
18768 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18769 ;; handled in combine, but it is not currently up to the task.
18770 ;; When used for their truth value, the cmpstrn* expanders generate
18771 ;; code like this:
18772 ;;
18773 ;;   repz cmpsb
18774 ;;   seta       %al
18775 ;;   setb       %dl
18776 ;;   cmpb       %al, %dl
18777 ;;   jcc        label
18778 ;;
18779 ;; The intermediate three instructions are unnecessary.
18780
18781 ;; This one handles cmpstrn*_nz_1...
18782 (define_peephole2
18783   [(parallel[
18784      (set (reg:CC FLAGS_REG)
18785           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18786                       (mem:BLK (match_operand 5 "register_operand" ""))))
18787      (use (match_operand 6 "register_operand" ""))
18788      (use (match_operand:SI 3 "immediate_operand" ""))
18789      (clobber (match_operand 0 "register_operand" ""))
18790      (clobber (match_operand 1 "register_operand" ""))
18791      (clobber (match_operand 2 "register_operand" ""))])
18792    (set (match_operand:QI 7 "register_operand" "")
18793         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18794    (set (match_operand:QI 8 "register_operand" "")
18795         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18796    (set (reg FLAGS_REG)
18797         (compare (match_dup 7) (match_dup 8)))
18798   ]
18799   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18800   [(parallel[
18801      (set (reg:CC FLAGS_REG)
18802           (compare:CC (mem:BLK (match_dup 4))
18803                       (mem:BLK (match_dup 5))))
18804      (use (match_dup 6))
18805      (use (match_dup 3))
18806      (clobber (match_dup 0))
18807      (clobber (match_dup 1))
18808      (clobber (match_dup 2))])]
18809   "")
18810
18811 ;; ...and this one handles cmpstrn*_1.
18812 (define_peephole2
18813   [(parallel[
18814      (set (reg:CC FLAGS_REG)
18815           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18816                                (const_int 0))
18817             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18818                         (mem:BLK (match_operand 5 "register_operand" "")))
18819             (const_int 0)))
18820      (use (match_operand:SI 3 "immediate_operand" ""))
18821      (use (reg:CC FLAGS_REG))
18822      (clobber (match_operand 0 "register_operand" ""))
18823      (clobber (match_operand 1 "register_operand" ""))
18824      (clobber (match_operand 2 "register_operand" ""))])
18825    (set (match_operand:QI 7 "register_operand" "")
18826         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18827    (set (match_operand:QI 8 "register_operand" "")
18828         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18829    (set (reg FLAGS_REG)
18830         (compare (match_dup 7) (match_dup 8)))
18831   ]
18832   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18833   [(parallel[
18834      (set (reg:CC FLAGS_REG)
18835           (if_then_else:CC (ne (match_dup 6)
18836                                (const_int 0))
18837             (compare:CC (mem:BLK (match_dup 4))
18838                         (mem:BLK (match_dup 5)))
18839             (const_int 0)))
18840      (use (match_dup 3))
18841      (use (reg:CC FLAGS_REG))
18842      (clobber (match_dup 0))
18843      (clobber (match_dup 1))
18844      (clobber (match_dup 2))])]
18845   "")
18846
18847
18848 \f
18849 ;; Conditional move instructions.
18850
18851 (define_expand "movdicc"
18852   [(set (match_operand:DI 0 "register_operand" "")
18853         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18854                          (match_operand:DI 2 "general_operand" "")
18855                          (match_operand:DI 3 "general_operand" "")))]
18856   "TARGET_64BIT"
18857   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18858
18859 (define_insn "x86_movdicc_0_m1_rex64"
18860   [(set (match_operand:DI 0 "register_operand" "=r")
18861         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18862           (const_int -1)
18863           (const_int 0)))
18864    (clobber (reg:CC FLAGS_REG))]
18865   "TARGET_64BIT"
18866   "sbb{q}\t%0, %0"
18867   ; Since we don't have the proper number of operands for an alu insn,
18868   ; fill in all the blanks.
18869   [(set_attr "type" "alu")
18870    (set_attr "pent_pair" "pu")
18871    (set_attr "memory" "none")
18872    (set_attr "imm_disp" "false")
18873    (set_attr "mode" "DI")
18874    (set_attr "length_immediate" "0")])
18875
18876 (define_insn "*movdicc_c_rex64"
18877   [(set (match_operand:DI 0 "register_operand" "=r,r")
18878         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18879                                 [(reg FLAGS_REG) (const_int 0)])
18880                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18881                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18882   "TARGET_64BIT && TARGET_CMOVE
18883    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18884   "@
18885    cmov%O2%C1\t{%2, %0|%0, %2}
18886    cmov%O2%c1\t{%3, %0|%0, %3}"
18887   [(set_attr "type" "icmov")
18888    (set_attr "mode" "DI")])
18889
18890 (define_expand "movsicc"
18891   [(set (match_operand:SI 0 "register_operand" "")
18892         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18893                          (match_operand:SI 2 "general_operand" "")
18894                          (match_operand:SI 3 "general_operand" "")))]
18895   ""
18896   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18897
18898 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18899 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18900 ;; So just document what we're doing explicitly.
18901
18902 (define_insn "x86_movsicc_0_m1"
18903   [(set (match_operand:SI 0 "register_operand" "=r")
18904         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18905           (const_int -1)
18906           (const_int 0)))
18907    (clobber (reg:CC FLAGS_REG))]
18908   ""
18909   "sbb{l}\t%0, %0"
18910   ; Since we don't have the proper number of operands for an alu insn,
18911   ; fill in all the blanks.
18912   [(set_attr "type" "alu")
18913    (set_attr "pent_pair" "pu")
18914    (set_attr "memory" "none")
18915    (set_attr "imm_disp" "false")
18916    (set_attr "mode" "SI")
18917    (set_attr "length_immediate" "0")])
18918
18919 (define_insn "*movsicc_noc"
18920   [(set (match_operand:SI 0 "register_operand" "=r,r")
18921         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18922                                 [(reg FLAGS_REG) (const_int 0)])
18923                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18924                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18925   "TARGET_CMOVE
18926    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18927   "@
18928    cmov%O2%C1\t{%2, %0|%0, %2}
18929    cmov%O2%c1\t{%3, %0|%0, %3}"
18930   [(set_attr "type" "icmov")
18931    (set_attr "mode" "SI")])
18932
18933 (define_expand "movhicc"
18934   [(set (match_operand:HI 0 "register_operand" "")
18935         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18936                          (match_operand:HI 2 "general_operand" "")
18937                          (match_operand:HI 3 "general_operand" "")))]
18938   "TARGET_HIMODE_MATH"
18939   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18940
18941 (define_insn "*movhicc_noc"
18942   [(set (match_operand:HI 0 "register_operand" "=r,r")
18943         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18944                                 [(reg FLAGS_REG) (const_int 0)])
18945                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18946                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18947   "TARGET_CMOVE
18948    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18949   "@
18950    cmov%O2%C1\t{%2, %0|%0, %2}
18951    cmov%O2%c1\t{%3, %0|%0, %3}"
18952   [(set_attr "type" "icmov")
18953    (set_attr "mode" "HI")])
18954
18955 (define_expand "movqicc"
18956   [(set (match_operand:QI 0 "register_operand" "")
18957         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18958                          (match_operand:QI 2 "general_operand" "")
18959                          (match_operand:QI 3 "general_operand" "")))]
18960   "TARGET_QIMODE_MATH"
18961   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18962
18963 (define_insn_and_split "*movqicc_noc"
18964   [(set (match_operand:QI 0 "register_operand" "=r,r")
18965         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18966                                 [(match_operand 4 "flags_reg_operand" "")
18967                                  (const_int 0)])
18968                       (match_operand:QI 2 "register_operand" "r,0")
18969                       (match_operand:QI 3 "register_operand" "0,r")))]
18970   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18971   "#"
18972   "&& reload_completed"
18973   [(set (match_dup 0)
18974         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18975                       (match_dup 2)
18976                       (match_dup 3)))]
18977   "operands[0] = gen_lowpart (SImode, operands[0]);
18978    operands[2] = gen_lowpart (SImode, operands[2]);
18979    operands[3] = gen_lowpart (SImode, operands[3]);"
18980   [(set_attr "type" "icmov")
18981    (set_attr "mode" "SI")])
18982
18983 (define_expand "movsfcc"
18984   [(set (match_operand:SF 0 "register_operand" "")
18985         (if_then_else:SF (match_operand 1 "comparison_operator" "")
18986                          (match_operand:SF 2 "register_operand" "")
18987                          (match_operand:SF 3 "register_operand" "")))]
18988   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18989   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18990
18991 (define_insn "*movsfcc_1_387"
18992   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18993         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18994                                 [(reg FLAGS_REG) (const_int 0)])
18995                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18996                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18997   "TARGET_80387 && TARGET_CMOVE
18998    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18999   "@
19000    fcmov%F1\t{%2, %0|%0, %2}
19001    fcmov%f1\t{%3, %0|%0, %3}
19002    cmov%O2%C1\t{%2, %0|%0, %2}
19003    cmov%O2%c1\t{%3, %0|%0, %3}"
19004   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19005    (set_attr "mode" "SF,SF,SI,SI")])
19006
19007 (define_expand "movdfcc"
19008   [(set (match_operand:DF 0 "register_operand" "")
19009         (if_then_else:DF (match_operand 1 "comparison_operator" "")
19010                          (match_operand:DF 2 "register_operand" "")
19011                          (match_operand:DF 3 "register_operand" "")))]
19012   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19013   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19014
19015 (define_insn "*movdfcc_1"
19016   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19017         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19018                                 [(reg FLAGS_REG) (const_int 0)])
19019                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19020                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19021   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19022    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19023   "@
19024    fcmov%F1\t{%2, %0|%0, %2}
19025    fcmov%f1\t{%3, %0|%0, %3}
19026    #
19027    #"
19028   [(set_attr "type" "fcmov,fcmov,multi,multi")
19029    (set_attr "mode" "DF")])
19030
19031 (define_insn "*movdfcc_1_rex64"
19032   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19033         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19034                                 [(reg FLAGS_REG) (const_int 0)])
19035                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19036                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19037   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19038    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19039   "@
19040    fcmov%F1\t{%2, %0|%0, %2}
19041    fcmov%f1\t{%3, %0|%0, %3}
19042    cmov%O2%C1\t{%2, %0|%0, %2}
19043    cmov%O2%c1\t{%3, %0|%0, %3}"
19044   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19045    (set_attr "mode" "DF")])
19046
19047 (define_split
19048   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19049         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19050                                 [(match_operand 4 "flags_reg_operand" "")
19051                                  (const_int 0)])
19052                       (match_operand:DF 2 "nonimmediate_operand" "")
19053                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19054   "!TARGET_64BIT && reload_completed"
19055   [(set (match_dup 2)
19056         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19057                       (match_dup 5)
19058                       (match_dup 7)))
19059    (set (match_dup 3)
19060         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19061                       (match_dup 6)
19062                       (match_dup 8)))]
19063   "split_di (operands+2, 1, operands+5, operands+6);
19064    split_di (operands+3, 1, operands+7, operands+8);
19065    split_di (operands, 1, operands+2, operands+3);")
19066
19067 (define_expand "movxfcc"
19068   [(set (match_operand:XF 0 "register_operand" "")
19069         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19070                          (match_operand:XF 2 "register_operand" "")
19071                          (match_operand:XF 3 "register_operand" "")))]
19072   "TARGET_80387 && TARGET_CMOVE"
19073   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19074
19075 (define_insn "*movxfcc_1"
19076   [(set (match_operand:XF 0 "register_operand" "=f,f")
19077         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19078                                 [(reg FLAGS_REG) (const_int 0)])
19079                       (match_operand:XF 2 "register_operand" "f,0")
19080                       (match_operand:XF 3 "register_operand" "0,f")))]
19081   "TARGET_80387 && TARGET_CMOVE"
19082   "@
19083    fcmov%F1\t{%2, %0|%0, %2}
19084    fcmov%f1\t{%3, %0|%0, %3}"
19085   [(set_attr "type" "fcmov")
19086    (set_attr "mode" "XF")])
19087
19088 ;; These versions of the min/max patterns are intentionally ignorant of
19089 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19090 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19091 ;; are undefined in this condition, we're certain this is correct.
19092
19093 (define_insn "sminsf3"
19094   [(set (match_operand:SF 0 "register_operand" "=x")
19095         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19096                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19097   "TARGET_SSE_MATH"
19098   "minss\t{%2, %0|%0, %2}"
19099   [(set_attr "type" "sseadd")
19100    (set_attr "mode" "SF")])
19101
19102 (define_insn "smaxsf3"
19103   [(set (match_operand:SF 0 "register_operand" "=x")
19104         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19105                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19106   "TARGET_SSE_MATH"
19107   "maxss\t{%2, %0|%0, %2}"
19108   [(set_attr "type" "sseadd")
19109    (set_attr "mode" "SF")])
19110
19111 (define_insn "smindf3"
19112   [(set (match_operand:DF 0 "register_operand" "=x")
19113         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19114                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19115   "TARGET_SSE2 && TARGET_SSE_MATH"
19116   "minsd\t{%2, %0|%0, %2}"
19117   [(set_attr "type" "sseadd")
19118    (set_attr "mode" "DF")])
19119
19120 (define_insn "smaxdf3"
19121   [(set (match_operand:DF 0 "register_operand" "=x")
19122         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19123                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19124   "TARGET_SSE2 && TARGET_SSE_MATH"
19125   "maxsd\t{%2, %0|%0, %2}"
19126   [(set_attr "type" "sseadd")
19127    (set_attr "mode" "DF")])
19128
19129 ;; These versions of the min/max patterns implement exactly the operations
19130 ;;   min = (op1 < op2 ? op1 : op2)
19131 ;;   max = (!(op1 < op2) ? op1 : op2)
19132 ;; Their operands are not commutative, and thus they may be used in the
19133 ;; presence of -0.0 and NaN.
19134
19135 (define_insn "*ieee_sminsf3"
19136   [(set (match_operand:SF 0 "register_operand" "=x")
19137         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19138                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19139                    UNSPEC_IEEE_MIN))]
19140   "TARGET_SSE_MATH"
19141   "minss\t{%2, %0|%0, %2}"
19142   [(set_attr "type" "sseadd")
19143    (set_attr "mode" "SF")])
19144
19145 (define_insn "*ieee_smaxsf3"
19146   [(set (match_operand:SF 0 "register_operand" "=x")
19147         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19148                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19149                    UNSPEC_IEEE_MAX))]
19150   "TARGET_SSE_MATH"
19151   "maxss\t{%2, %0|%0, %2}"
19152   [(set_attr "type" "sseadd")
19153    (set_attr "mode" "SF")])
19154
19155 (define_insn "*ieee_smindf3"
19156   [(set (match_operand:DF 0 "register_operand" "=x")
19157         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19158                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19159                    UNSPEC_IEEE_MIN))]
19160   "TARGET_SSE2 && TARGET_SSE_MATH"
19161   "minsd\t{%2, %0|%0, %2}"
19162   [(set_attr "type" "sseadd")
19163    (set_attr "mode" "DF")])
19164
19165 (define_insn "*ieee_smaxdf3"
19166   [(set (match_operand:DF 0 "register_operand" "=x")
19167         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19168                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19169                    UNSPEC_IEEE_MAX))]
19170   "TARGET_SSE2 && TARGET_SSE_MATH"
19171   "maxsd\t{%2, %0|%0, %2}"
19172   [(set_attr "type" "sseadd")
19173    (set_attr "mode" "DF")])
19174
19175 ;; Make two stack loads independent:
19176 ;;   fld aa              fld aa
19177 ;;   fld %st(0)     ->   fld bb
19178 ;;   fmul bb             fmul %st(1), %st
19179 ;;
19180 ;; Actually we only match the last two instructions for simplicity.
19181 (define_peephole2
19182   [(set (match_operand 0 "fp_register_operand" "")
19183         (match_operand 1 "fp_register_operand" ""))
19184    (set (match_dup 0)
19185         (match_operator 2 "binary_fp_operator"
19186            [(match_dup 0)
19187             (match_operand 3 "memory_operand" "")]))]
19188   "REGNO (operands[0]) != REGNO (operands[1])"
19189   [(set (match_dup 0) (match_dup 3))
19190    (set (match_dup 0) (match_dup 4))]
19191
19192   ;; The % modifier is not operational anymore in peephole2's, so we have to
19193   ;; swap the operands manually in the case of addition and multiplication.
19194   "if (COMMUTATIVE_ARITH_P (operands[2]))
19195      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19196                                  operands[0], operands[1]);
19197    else
19198      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19199                                  operands[1], operands[0]);")
19200
19201 ;; Conditional addition patterns
19202 (define_expand "addqicc"
19203   [(match_operand:QI 0 "register_operand" "")
19204    (match_operand 1 "comparison_operator" "")
19205    (match_operand:QI 2 "register_operand" "")
19206    (match_operand:QI 3 "const_int_operand" "")]
19207   ""
19208   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19209
19210 (define_expand "addhicc"
19211   [(match_operand:HI 0 "register_operand" "")
19212    (match_operand 1 "comparison_operator" "")
19213    (match_operand:HI 2 "register_operand" "")
19214    (match_operand:HI 3 "const_int_operand" "")]
19215   ""
19216   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19217
19218 (define_expand "addsicc"
19219   [(match_operand:SI 0 "register_operand" "")
19220    (match_operand 1 "comparison_operator" "")
19221    (match_operand:SI 2 "register_operand" "")
19222    (match_operand:SI 3 "const_int_operand" "")]
19223   ""
19224   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19225
19226 (define_expand "adddicc"
19227   [(match_operand:DI 0 "register_operand" "")
19228    (match_operand 1 "comparison_operator" "")
19229    (match_operand:DI 2 "register_operand" "")
19230    (match_operand:DI 3 "const_int_operand" "")]
19231   "TARGET_64BIT"
19232   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19233
19234 \f
19235 ;; Misc patterns (?)
19236
19237 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19238 ;; Otherwise there will be nothing to keep
19239 ;;
19240 ;; [(set (reg ebp) (reg esp))]
19241 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19242 ;;  (clobber (eflags)]
19243 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19244 ;;
19245 ;; in proper program order.
19246 (define_insn "pro_epilogue_adjust_stack_1"
19247   [(set (match_operand:SI 0 "register_operand" "=r,r")
19248         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19249                  (match_operand:SI 2 "immediate_operand" "i,i")))
19250    (clobber (reg:CC FLAGS_REG))
19251    (clobber (mem:BLK (scratch)))]
19252   "!TARGET_64BIT"
19253 {
19254   switch (get_attr_type (insn))
19255     {
19256     case TYPE_IMOV:
19257       return "mov{l}\t{%1, %0|%0, %1}";
19258
19259     case TYPE_ALU:
19260       if (CONST_INT_P (operands[2])
19261           && (INTVAL (operands[2]) == 128
19262               || (INTVAL (operands[2]) < 0
19263                   && INTVAL (operands[2]) != -128)))
19264         {
19265           operands[2] = GEN_INT (-INTVAL (operands[2]));
19266           return "sub{l}\t{%2, %0|%0, %2}";
19267         }
19268       return "add{l}\t{%2, %0|%0, %2}";
19269
19270     case TYPE_LEA:
19271       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19272       return "lea{l}\t{%a2, %0|%0, %a2}";
19273
19274     default:
19275       gcc_unreachable ();
19276     }
19277 }
19278   [(set (attr "type")
19279         (cond [(eq_attr "alternative" "0")
19280                  (const_string "alu")
19281                (match_operand:SI 2 "const0_operand" "")
19282                  (const_string "imov")
19283               ]
19284               (const_string "lea")))
19285    (set_attr "mode" "SI")])
19286
19287 (define_insn "pro_epilogue_adjust_stack_rex64"
19288   [(set (match_operand:DI 0 "register_operand" "=r,r")
19289         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19290                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19291    (clobber (reg:CC FLAGS_REG))
19292    (clobber (mem:BLK (scratch)))]
19293   "TARGET_64BIT"
19294 {
19295   switch (get_attr_type (insn))
19296     {
19297     case TYPE_IMOV:
19298       return "mov{q}\t{%1, %0|%0, %1}";
19299
19300     case TYPE_ALU:
19301       if (CONST_INT_P (operands[2])
19302           /* Avoid overflows.  */
19303           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19304           && (INTVAL (operands[2]) == 128
19305               || (INTVAL (operands[2]) < 0
19306                   && INTVAL (operands[2]) != -128)))
19307         {
19308           operands[2] = GEN_INT (-INTVAL (operands[2]));
19309           return "sub{q}\t{%2, %0|%0, %2}";
19310         }
19311       return "add{q}\t{%2, %0|%0, %2}";
19312
19313     case TYPE_LEA:
19314       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19315       return "lea{q}\t{%a2, %0|%0, %a2}";
19316
19317     default:
19318       gcc_unreachable ();
19319     }
19320 }
19321   [(set (attr "type")
19322         (cond [(eq_attr "alternative" "0")
19323                  (const_string "alu")
19324                (match_operand:DI 2 "const0_operand" "")
19325                  (const_string "imov")
19326               ]
19327               (const_string "lea")))
19328    (set_attr "mode" "DI")])
19329
19330 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19331   [(set (match_operand:DI 0 "register_operand" "=r,r")
19332         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19333                  (match_operand:DI 3 "immediate_operand" "i,i")))
19334    (use (match_operand:DI 2 "register_operand" "r,r"))
19335    (clobber (reg:CC FLAGS_REG))
19336    (clobber (mem:BLK (scratch)))]
19337   "TARGET_64BIT"
19338 {
19339   switch (get_attr_type (insn))
19340     {
19341     case TYPE_ALU:
19342       return "add{q}\t{%2, %0|%0, %2}";
19343
19344     case TYPE_LEA:
19345       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19346       return "lea{q}\t{%a2, %0|%0, %a2}";
19347
19348     default:
19349       gcc_unreachable ();
19350     }
19351 }
19352   [(set_attr "type" "alu,lea")
19353    (set_attr "mode" "DI")])
19354
19355 (define_insn "allocate_stack_worker_32"
19356   [(set (match_operand:SI 0 "register_operand" "+a")
19357         (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19358    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19359    (clobber (reg:CC FLAGS_REG))]
19360   "!TARGET_64BIT && TARGET_STACK_PROBE"
19361   "call\t__alloca"
19362   [(set_attr "type" "multi")
19363    (set_attr "length" "5")])
19364
19365 (define_insn "allocate_stack_worker_64"
19366   [(set (match_operand:DI 0 "register_operand" "=a")
19367         (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19368    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19369    (clobber (reg:DI R10_REG))
19370    (clobber (reg:DI R11_REG))
19371    (clobber (reg:CC FLAGS_REG))]
19372   "TARGET_64BIT && TARGET_STACK_PROBE"
19373   "call\t___chkstk"
19374   [(set_attr "type" "multi")
19375    (set_attr "length" "5")])
19376
19377 (define_expand "allocate_stack"
19378   [(match_operand 0 "register_operand" "")
19379    (match_operand 1 "general_operand" "")]
19380   "TARGET_STACK_PROBE"
19381 {
19382   rtx x;
19383
19384 #ifndef CHECK_STACK_LIMIT
19385 #define CHECK_STACK_LIMIT 0
19386 #endif
19387
19388   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19389       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19390     {
19391       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19392                                stack_pointer_rtx, 0, OPTAB_DIRECT);
19393       if (x != stack_pointer_rtx)
19394         emit_move_insn (stack_pointer_rtx, x);
19395     }
19396   else
19397     {
19398       x = copy_to_mode_reg (Pmode, operands[1]);
19399       if (TARGET_64BIT)
19400         x = gen_allocate_stack_worker_64 (x);
19401       else
19402         x = gen_allocate_stack_worker_32 (x);
19403       emit_insn (x);
19404     }
19405
19406   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19407   DONE;
19408 })
19409
19410 (define_expand "builtin_setjmp_receiver"
19411   [(label_ref (match_operand 0 "" ""))]
19412   "!TARGET_64BIT && flag_pic"
19413 {
19414   if (TARGET_MACHO)
19415     {
19416       rtx xops[3];
19417       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19418       rtx label_rtx = gen_label_rtx ();
19419       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19420       xops[0] = xops[1] = picreg;
19421       xops[2] = gen_rtx_CONST (SImode,
19422                   gen_rtx_MINUS (SImode,
19423                     gen_rtx_LABEL_REF (SImode, label_rtx),
19424                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19425       ix86_expand_binary_operator (MINUS, SImode, xops);
19426     }
19427   else
19428     emit_insn (gen_set_got (pic_offset_table_rtx));
19429   DONE;
19430 })
19431 \f
19432 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19433
19434 (define_split
19435   [(set (match_operand 0 "register_operand" "")
19436         (match_operator 3 "promotable_binary_operator"
19437            [(match_operand 1 "register_operand" "")
19438             (match_operand 2 "aligned_operand" "")]))
19439    (clobber (reg:CC FLAGS_REG))]
19440   "! TARGET_PARTIAL_REG_STALL && reload_completed
19441    && ((GET_MODE (operands[0]) == HImode
19442         && ((!optimize_size && !TARGET_FAST_PREFIX)
19443             /* ??? next two lines just !satisfies_constraint_K (...) */
19444             || !CONST_INT_P (operands[2])
19445             || satisfies_constraint_K (operands[2])))
19446        || (GET_MODE (operands[0]) == QImode
19447            && (TARGET_PROMOTE_QImode || optimize_size)))"
19448   [(parallel [(set (match_dup 0)
19449                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19450               (clobber (reg:CC FLAGS_REG))])]
19451   "operands[0] = gen_lowpart (SImode, operands[0]);
19452    operands[1] = gen_lowpart (SImode, operands[1]);
19453    if (GET_CODE (operands[3]) != ASHIFT)
19454      operands[2] = gen_lowpart (SImode, operands[2]);
19455    PUT_MODE (operands[3], SImode);")
19456
19457 ; Promote the QImode tests, as i386 has encoding of the AND
19458 ; instruction with 32-bit sign-extended immediate and thus the
19459 ; instruction size is unchanged, except in the %eax case for
19460 ; which it is increased by one byte, hence the ! optimize_size.
19461 (define_split
19462   [(set (match_operand 0 "flags_reg_operand" "")
19463         (match_operator 2 "compare_operator"
19464           [(and (match_operand 3 "aligned_operand" "")
19465                 (match_operand 4 "const_int_operand" ""))
19466            (const_int 0)]))
19467    (set (match_operand 1 "register_operand" "")
19468         (and (match_dup 3) (match_dup 4)))]
19469   "! TARGET_PARTIAL_REG_STALL && reload_completed
19470    /* Ensure that the operand will remain sign-extended immediate.  */
19471    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19472    && ! optimize_size
19473    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19474        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19475   [(parallel [(set (match_dup 0)
19476                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19477                                     (const_int 0)]))
19478               (set (match_dup 1)
19479                    (and:SI (match_dup 3) (match_dup 4)))])]
19480 {
19481   operands[4]
19482     = gen_int_mode (INTVAL (operands[4])
19483                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19484   operands[1] = gen_lowpart (SImode, operands[1]);
19485   operands[3] = gen_lowpart (SImode, operands[3]);
19486 })
19487
19488 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19489 ; the TEST instruction with 32-bit sign-extended immediate and thus
19490 ; the instruction size would at least double, which is not what we
19491 ; want even with ! optimize_size.
19492 (define_split
19493   [(set (match_operand 0 "flags_reg_operand" "")
19494         (match_operator 1 "compare_operator"
19495           [(and (match_operand:HI 2 "aligned_operand" "")
19496                 (match_operand:HI 3 "const_int_operand" ""))
19497            (const_int 0)]))]
19498   "! TARGET_PARTIAL_REG_STALL && reload_completed
19499    /* Ensure that the operand will remain sign-extended immediate.  */
19500    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19501    && ! TARGET_FAST_PREFIX
19502    && ! optimize_size"
19503   [(set (match_dup 0)
19504         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19505                          (const_int 0)]))]
19506 {
19507   operands[3]
19508     = gen_int_mode (INTVAL (operands[3])
19509                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19510   operands[2] = gen_lowpart (SImode, operands[2]);
19511 })
19512
19513 (define_split
19514   [(set (match_operand 0 "register_operand" "")
19515         (neg (match_operand 1 "register_operand" "")))
19516    (clobber (reg:CC FLAGS_REG))]
19517   "! TARGET_PARTIAL_REG_STALL && reload_completed
19518    && (GET_MODE (operands[0]) == HImode
19519        || (GET_MODE (operands[0]) == QImode
19520            && (TARGET_PROMOTE_QImode || optimize_size)))"
19521   [(parallel [(set (match_dup 0)
19522                    (neg:SI (match_dup 1)))
19523               (clobber (reg:CC FLAGS_REG))])]
19524   "operands[0] = gen_lowpart (SImode, operands[0]);
19525    operands[1] = gen_lowpart (SImode, operands[1]);")
19526
19527 (define_split
19528   [(set (match_operand 0 "register_operand" "")
19529         (not (match_operand 1 "register_operand" "")))]
19530   "! TARGET_PARTIAL_REG_STALL && reload_completed
19531    && (GET_MODE (operands[0]) == HImode
19532        || (GET_MODE (operands[0]) == QImode
19533            && (TARGET_PROMOTE_QImode || optimize_size)))"
19534   [(set (match_dup 0)
19535         (not:SI (match_dup 1)))]
19536   "operands[0] = gen_lowpart (SImode, operands[0]);
19537    operands[1] = gen_lowpart (SImode, operands[1]);")
19538
19539 (define_split
19540   [(set (match_operand 0 "register_operand" "")
19541         (if_then_else (match_operator 1 "comparison_operator"
19542                                 [(reg FLAGS_REG) (const_int 0)])
19543                       (match_operand 2 "register_operand" "")
19544                       (match_operand 3 "register_operand" "")))]
19545   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19546    && (GET_MODE (operands[0]) == HImode
19547        || (GET_MODE (operands[0]) == QImode
19548            && (TARGET_PROMOTE_QImode || optimize_size)))"
19549   [(set (match_dup 0)
19550         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19551   "operands[0] = gen_lowpart (SImode, operands[0]);
19552    operands[2] = gen_lowpart (SImode, operands[2]);
19553    operands[3] = gen_lowpart (SImode, operands[3]);")
19554
19555 \f
19556 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19557 ;; transform a complex memory operation into two memory to register operations.
19558
19559 ;; Don't push memory operands
19560 (define_peephole2
19561   [(set (match_operand:SI 0 "push_operand" "")
19562         (match_operand:SI 1 "memory_operand" ""))
19563    (match_scratch:SI 2 "r")]
19564   "!optimize_size && !TARGET_PUSH_MEMORY
19565    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19566   [(set (match_dup 2) (match_dup 1))
19567    (set (match_dup 0) (match_dup 2))]
19568   "")
19569
19570 (define_peephole2
19571   [(set (match_operand:DI 0 "push_operand" "")
19572         (match_operand:DI 1 "memory_operand" ""))
19573    (match_scratch:DI 2 "r")]
19574   "!optimize_size && !TARGET_PUSH_MEMORY
19575    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19576   [(set (match_dup 2) (match_dup 1))
19577    (set (match_dup 0) (match_dup 2))]
19578   "")
19579
19580 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19581 ;; SImode pushes.
19582 (define_peephole2
19583   [(set (match_operand:SF 0 "push_operand" "")
19584         (match_operand:SF 1 "memory_operand" ""))
19585    (match_scratch:SF 2 "r")]
19586   "!optimize_size && !TARGET_PUSH_MEMORY
19587    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19588   [(set (match_dup 2) (match_dup 1))
19589    (set (match_dup 0) (match_dup 2))]
19590   "")
19591
19592 (define_peephole2
19593   [(set (match_operand:HI 0 "push_operand" "")
19594         (match_operand:HI 1 "memory_operand" ""))
19595    (match_scratch:HI 2 "r")]
19596   "!optimize_size && !TARGET_PUSH_MEMORY
19597    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19598   [(set (match_dup 2) (match_dup 1))
19599    (set (match_dup 0) (match_dup 2))]
19600   "")
19601
19602 (define_peephole2
19603   [(set (match_operand:QI 0 "push_operand" "")
19604         (match_operand:QI 1 "memory_operand" ""))
19605    (match_scratch:QI 2 "q")]
19606   "!optimize_size && !TARGET_PUSH_MEMORY
19607    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19608   [(set (match_dup 2) (match_dup 1))
19609    (set (match_dup 0) (match_dup 2))]
19610   "")
19611
19612 ;; Don't move an immediate directly to memory when the instruction
19613 ;; gets too big.
19614 (define_peephole2
19615   [(match_scratch:SI 1 "r")
19616    (set (match_operand:SI 0 "memory_operand" "")
19617         (const_int 0))]
19618   "! optimize_size
19619    && ! TARGET_USE_MOV0
19620    && TARGET_SPLIT_LONG_MOVES
19621    && get_attr_length (insn) >= ix86_cost->large_insn
19622    && peep2_regno_dead_p (0, FLAGS_REG)"
19623   [(parallel [(set (match_dup 1) (const_int 0))
19624               (clobber (reg:CC FLAGS_REG))])
19625    (set (match_dup 0) (match_dup 1))]
19626   "")
19627
19628 (define_peephole2
19629   [(match_scratch:HI 1 "r")
19630    (set (match_operand:HI 0 "memory_operand" "")
19631         (const_int 0))]
19632   "! optimize_size
19633    && ! TARGET_USE_MOV0
19634    && TARGET_SPLIT_LONG_MOVES
19635    && get_attr_length (insn) >= ix86_cost->large_insn
19636    && peep2_regno_dead_p (0, FLAGS_REG)"
19637   [(parallel [(set (match_dup 2) (const_int 0))
19638               (clobber (reg:CC FLAGS_REG))])
19639    (set (match_dup 0) (match_dup 1))]
19640   "operands[2] = gen_lowpart (SImode, operands[1]);")
19641
19642 (define_peephole2
19643   [(match_scratch:QI 1 "q")
19644    (set (match_operand:QI 0 "memory_operand" "")
19645         (const_int 0))]
19646   "! optimize_size
19647    && ! TARGET_USE_MOV0
19648    && TARGET_SPLIT_LONG_MOVES
19649    && get_attr_length (insn) >= ix86_cost->large_insn
19650    && peep2_regno_dead_p (0, FLAGS_REG)"
19651   [(parallel [(set (match_dup 2) (const_int 0))
19652               (clobber (reg:CC FLAGS_REG))])
19653    (set (match_dup 0) (match_dup 1))]
19654   "operands[2] = gen_lowpart (SImode, operands[1]);")
19655
19656 (define_peephole2
19657   [(match_scratch:SI 2 "r")
19658    (set (match_operand:SI 0 "memory_operand" "")
19659         (match_operand:SI 1 "immediate_operand" ""))]
19660   "! optimize_size
19661    && get_attr_length (insn) >= ix86_cost->large_insn
19662    && TARGET_SPLIT_LONG_MOVES"
19663   [(set (match_dup 2) (match_dup 1))
19664    (set (match_dup 0) (match_dup 2))]
19665   "")
19666
19667 (define_peephole2
19668   [(match_scratch:HI 2 "r")
19669    (set (match_operand:HI 0 "memory_operand" "")
19670         (match_operand:HI 1 "immediate_operand" ""))]
19671   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19672   && TARGET_SPLIT_LONG_MOVES"
19673   [(set (match_dup 2) (match_dup 1))
19674    (set (match_dup 0) (match_dup 2))]
19675   "")
19676
19677 (define_peephole2
19678   [(match_scratch:QI 2 "q")
19679    (set (match_operand:QI 0 "memory_operand" "")
19680         (match_operand:QI 1 "immediate_operand" ""))]
19681   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19682   && TARGET_SPLIT_LONG_MOVES"
19683   [(set (match_dup 2) (match_dup 1))
19684    (set (match_dup 0) (match_dup 2))]
19685   "")
19686
19687 ;; Don't compare memory with zero, load and use a test instead.
19688 (define_peephole2
19689   [(set (match_operand 0 "flags_reg_operand" "")
19690         (match_operator 1 "compare_operator"
19691           [(match_operand:SI 2 "memory_operand" "")
19692            (const_int 0)]))
19693    (match_scratch:SI 3 "r")]
19694   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19695   [(set (match_dup 3) (match_dup 2))
19696    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19697   "")
19698
19699 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19700 ;; Don't split NOTs with a displacement operand, because resulting XOR
19701 ;; will not be pairable anyway.
19702 ;;
19703 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19704 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19705 ;; so this split helps here as well.
19706 ;;
19707 ;; Note: Can't do this as a regular split because we can't get proper
19708 ;; lifetime information then.
19709
19710 (define_peephole2
19711   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19712         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19713   "!optimize_size
19714    && peep2_regno_dead_p (0, FLAGS_REG)
19715    && ((TARGET_NOT_UNPAIRABLE
19716         && (!MEM_P (operands[0])
19717             || !memory_displacement_operand (operands[0], SImode)))
19718        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))"
19719   [(parallel [(set (match_dup 0)
19720                    (xor:SI (match_dup 1) (const_int -1)))
19721               (clobber (reg:CC FLAGS_REG))])]
19722   "")
19723
19724 (define_peephole2
19725   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19726         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19727   "!optimize_size
19728    && peep2_regno_dead_p (0, FLAGS_REG)
19729    && ((TARGET_NOT_UNPAIRABLE
19730         && (!MEM_P (operands[0])
19731             || !memory_displacement_operand (operands[0], HImode)))
19732        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))"
19733   [(parallel [(set (match_dup 0)
19734                    (xor:HI (match_dup 1) (const_int -1)))
19735               (clobber (reg:CC FLAGS_REG))])]
19736   "")
19737
19738 (define_peephole2
19739   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19740         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19741   "!optimize_size
19742    && peep2_regno_dead_p (0, FLAGS_REG)
19743    && ((TARGET_NOT_UNPAIRABLE
19744         && (!MEM_P (operands[0])
19745             || !memory_displacement_operand (operands[0], QImode)))
19746        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))"
19747   [(parallel [(set (match_dup 0)
19748                    (xor:QI (match_dup 1) (const_int -1)))
19749               (clobber (reg:CC FLAGS_REG))])]
19750   "")
19751
19752 ;; Non pairable "test imm, reg" instructions can be translated to
19753 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19754 ;; byte opcode instead of two, have a short form for byte operands),
19755 ;; so do it for other CPUs as well.  Given that the value was dead,
19756 ;; this should not create any new dependencies.  Pass on the sub-word
19757 ;; versions if we're concerned about partial register stalls.
19758
19759 (define_peephole2
19760   [(set (match_operand 0 "flags_reg_operand" "")
19761         (match_operator 1 "compare_operator"
19762           [(and:SI (match_operand:SI 2 "register_operand" "")
19763                    (match_operand:SI 3 "immediate_operand" ""))
19764            (const_int 0)]))]
19765   "ix86_match_ccmode (insn, CCNOmode)
19766    && (true_regnum (operands[2]) != 0
19767        || satisfies_constraint_K (operands[3]))
19768    && peep2_reg_dead_p (1, operands[2])"
19769   [(parallel
19770      [(set (match_dup 0)
19771            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19772                             (const_int 0)]))
19773       (set (match_dup 2)
19774            (and:SI (match_dup 2) (match_dup 3)))])]
19775   "")
19776
19777 ;; We don't need to handle HImode case, because it will be promoted to SImode
19778 ;; on ! TARGET_PARTIAL_REG_STALL
19779
19780 (define_peephole2
19781   [(set (match_operand 0 "flags_reg_operand" "")
19782         (match_operator 1 "compare_operator"
19783           [(and:QI (match_operand:QI 2 "register_operand" "")
19784                    (match_operand:QI 3 "immediate_operand" ""))
19785            (const_int 0)]))]
19786   "! TARGET_PARTIAL_REG_STALL
19787    && ix86_match_ccmode (insn, CCNOmode)
19788    && true_regnum (operands[2]) != 0
19789    && peep2_reg_dead_p (1, operands[2])"
19790   [(parallel
19791      [(set (match_dup 0)
19792            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19793                             (const_int 0)]))
19794       (set (match_dup 2)
19795            (and:QI (match_dup 2) (match_dup 3)))])]
19796   "")
19797
19798 (define_peephole2
19799   [(set (match_operand 0 "flags_reg_operand" "")
19800         (match_operator 1 "compare_operator"
19801           [(and:SI
19802              (zero_extract:SI
19803                (match_operand 2 "ext_register_operand" "")
19804                (const_int 8)
19805                (const_int 8))
19806              (match_operand 3 "const_int_operand" ""))
19807            (const_int 0)]))]
19808   "! TARGET_PARTIAL_REG_STALL
19809    && ix86_match_ccmode (insn, CCNOmode)
19810    && true_regnum (operands[2]) != 0
19811    && peep2_reg_dead_p (1, operands[2])"
19812   [(parallel [(set (match_dup 0)
19813                    (match_op_dup 1
19814                      [(and:SI
19815                         (zero_extract:SI
19816                           (match_dup 2)
19817                           (const_int 8)
19818                           (const_int 8))
19819                         (match_dup 3))
19820                       (const_int 0)]))
19821               (set (zero_extract:SI (match_dup 2)
19822                                     (const_int 8)
19823                                     (const_int 8))
19824                    (and:SI
19825                      (zero_extract:SI
19826                        (match_dup 2)
19827                        (const_int 8)
19828                        (const_int 8))
19829                      (match_dup 3)))])]
19830   "")
19831
19832 ;; Don't do logical operations with memory inputs.
19833 (define_peephole2
19834   [(match_scratch:SI 2 "r")
19835    (parallel [(set (match_operand:SI 0 "register_operand" "")
19836                    (match_operator:SI 3 "arith_or_logical_operator"
19837                      [(match_dup 0)
19838                       (match_operand:SI 1 "memory_operand" "")]))
19839               (clobber (reg:CC FLAGS_REG))])]
19840   "! optimize_size && ! TARGET_READ_MODIFY"
19841   [(set (match_dup 2) (match_dup 1))
19842    (parallel [(set (match_dup 0)
19843                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19844               (clobber (reg:CC FLAGS_REG))])]
19845   "")
19846
19847 (define_peephole2
19848   [(match_scratch:SI 2 "r")
19849    (parallel [(set (match_operand:SI 0 "register_operand" "")
19850                    (match_operator:SI 3 "arith_or_logical_operator"
19851                      [(match_operand:SI 1 "memory_operand" "")
19852                       (match_dup 0)]))
19853               (clobber (reg:CC FLAGS_REG))])]
19854   "! optimize_size && ! TARGET_READ_MODIFY"
19855   [(set (match_dup 2) (match_dup 1))
19856    (parallel [(set (match_dup 0)
19857                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19858               (clobber (reg:CC FLAGS_REG))])]
19859   "")
19860
19861 ; Don't do logical operations with memory outputs
19862 ;
19863 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19864 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19865 ; the same decoder scheduling characteristics as the original.
19866
19867 (define_peephole2
19868   [(match_scratch:SI 2 "r")
19869    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19870                    (match_operator:SI 3 "arith_or_logical_operator"
19871                      [(match_dup 0)
19872                       (match_operand:SI 1 "nonmemory_operand" "")]))
19873               (clobber (reg:CC FLAGS_REG))])]
19874   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19875   [(set (match_dup 2) (match_dup 0))
19876    (parallel [(set (match_dup 2)
19877                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19878               (clobber (reg:CC FLAGS_REG))])
19879    (set (match_dup 0) (match_dup 2))]
19880   "")
19881
19882 (define_peephole2
19883   [(match_scratch:SI 2 "r")
19884    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19885                    (match_operator:SI 3 "arith_or_logical_operator"
19886                      [(match_operand:SI 1 "nonmemory_operand" "")
19887                       (match_dup 0)]))
19888               (clobber (reg:CC FLAGS_REG))])]
19889   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19890   [(set (match_dup 2) (match_dup 0))
19891    (parallel [(set (match_dup 2)
19892                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19893               (clobber (reg:CC FLAGS_REG))])
19894    (set (match_dup 0) (match_dup 2))]
19895   "")
19896
19897 ;; Attempt to always use XOR for zeroing registers.
19898 (define_peephole2
19899   [(set (match_operand 0 "register_operand" "")
19900         (match_operand 1 "const0_operand" ""))]
19901   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19902    && (! TARGET_USE_MOV0 || optimize_size)
19903    && GENERAL_REG_P (operands[0])
19904    && peep2_regno_dead_p (0, FLAGS_REG)"
19905   [(parallel [(set (match_dup 0) (const_int 0))
19906               (clobber (reg:CC FLAGS_REG))])]
19907 {
19908   operands[0] = gen_lowpart (word_mode, operands[0]);
19909 })
19910
19911 (define_peephole2
19912   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19913         (const_int 0))]
19914   "(GET_MODE (operands[0]) == QImode
19915     || GET_MODE (operands[0]) == HImode)
19916    && (! TARGET_USE_MOV0 || optimize_size)
19917    && peep2_regno_dead_p (0, FLAGS_REG)"
19918   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19919               (clobber (reg:CC FLAGS_REG))])])
19920
19921 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19922 (define_peephole2
19923   [(set (match_operand 0 "register_operand" "")
19924         (const_int -1))]
19925   "(GET_MODE (operands[0]) == HImode
19926     || GET_MODE (operands[0]) == SImode
19927     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19928    && (optimize_size || TARGET_MOVE_M1_VIA_OR)
19929    && peep2_regno_dead_p (0, FLAGS_REG)"
19930   [(parallel [(set (match_dup 0) (const_int -1))
19931               (clobber (reg:CC FLAGS_REG))])]
19932   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19933                               operands[0]);")
19934
19935 ;; Attempt to convert simple leas to adds. These can be created by
19936 ;; move expanders.
19937 (define_peephole2
19938   [(set (match_operand:SI 0 "register_operand" "")
19939         (plus:SI (match_dup 0)
19940                  (match_operand:SI 1 "nonmemory_operand" "")))]
19941   "peep2_regno_dead_p (0, FLAGS_REG)"
19942   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19943               (clobber (reg:CC FLAGS_REG))])]
19944   "")
19945
19946 (define_peephole2
19947   [(set (match_operand:SI 0 "register_operand" "")
19948         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19949                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19950   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19951   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19952               (clobber (reg:CC FLAGS_REG))])]
19953   "operands[2] = gen_lowpart (SImode, operands[2]);")
19954
19955 (define_peephole2
19956   [(set (match_operand:DI 0 "register_operand" "")
19957         (plus:DI (match_dup 0)
19958                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19959   "peep2_regno_dead_p (0, FLAGS_REG)"
19960   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19961               (clobber (reg:CC FLAGS_REG))])]
19962   "")
19963
19964 (define_peephole2
19965   [(set (match_operand:SI 0 "register_operand" "")
19966         (mult:SI (match_dup 0)
19967                  (match_operand:SI 1 "const_int_operand" "")))]
19968   "exact_log2 (INTVAL (operands[1])) >= 0
19969    && peep2_regno_dead_p (0, FLAGS_REG)"
19970   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19971               (clobber (reg:CC FLAGS_REG))])]
19972   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19973
19974 (define_peephole2
19975   [(set (match_operand:DI 0 "register_operand" "")
19976         (mult:DI (match_dup 0)
19977                  (match_operand:DI 1 "const_int_operand" "")))]
19978   "exact_log2 (INTVAL (operands[1])) >= 0
19979    && peep2_regno_dead_p (0, FLAGS_REG)"
19980   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19981               (clobber (reg:CC FLAGS_REG))])]
19982   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19983
19984 (define_peephole2
19985   [(set (match_operand:SI 0 "register_operand" "")
19986         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19987                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19988   "exact_log2 (INTVAL (operands[2])) >= 0
19989    && REGNO (operands[0]) == REGNO (operands[1])
19990    && peep2_regno_dead_p (0, FLAGS_REG)"
19991   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19992               (clobber (reg:CC FLAGS_REG))])]
19993   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19994
19995 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19996 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19997 ;; many CPUs it is also faster, since special hardware to avoid esp
19998 ;; dependencies is present.
19999
20000 ;; While some of these conversions may be done using splitters, we use peepholes
20001 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20002
20003 ;; Convert prologue esp subtractions to push.
20004 ;; We need register to push.  In order to keep verify_flow_info happy we have
20005 ;; two choices
20006 ;; - use scratch and clobber it in order to avoid dependencies
20007 ;; - use already live register
20008 ;; We can't use the second way right now, since there is no reliable way how to
20009 ;; verify that given register is live.  First choice will also most likely in
20010 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20011 ;; call clobbered registers are dead.  We may want to use base pointer as an
20012 ;; alternative when no register is available later.
20013
20014 (define_peephole2
20015   [(match_scratch:SI 0 "r")
20016    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20017               (clobber (reg:CC FLAGS_REG))
20018               (clobber (mem:BLK (scratch)))])]
20019   "optimize_size || !TARGET_SUB_ESP_4"
20020   [(clobber (match_dup 0))
20021    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20022               (clobber (mem:BLK (scratch)))])])
20023
20024 (define_peephole2
20025   [(match_scratch:SI 0 "r")
20026    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20027               (clobber (reg:CC FLAGS_REG))
20028               (clobber (mem:BLK (scratch)))])]
20029   "optimize_size || !TARGET_SUB_ESP_8"
20030   [(clobber (match_dup 0))
20031    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20032    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20033               (clobber (mem:BLK (scratch)))])])
20034
20035 ;; Convert esp subtractions to push.
20036 (define_peephole2
20037   [(match_scratch:SI 0 "r")
20038    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20039               (clobber (reg:CC FLAGS_REG))])]
20040   "optimize_size || !TARGET_SUB_ESP_4"
20041   [(clobber (match_dup 0))
20042    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20043
20044 (define_peephole2
20045   [(match_scratch:SI 0 "r")
20046    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20047               (clobber (reg:CC FLAGS_REG))])]
20048   "optimize_size || !TARGET_SUB_ESP_8"
20049   [(clobber (match_dup 0))
20050    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20051    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20052
20053 ;; Convert epilogue deallocator to pop.
20054 (define_peephole2
20055   [(match_scratch:SI 0 "r")
20056    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20057               (clobber (reg:CC FLAGS_REG))
20058               (clobber (mem:BLK (scratch)))])]
20059   "optimize_size || !TARGET_ADD_ESP_4"
20060   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20061               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20062               (clobber (mem:BLK (scratch)))])]
20063   "")
20064
20065 ;; Two pops case is tricky, since pop causes dependency on destination register.
20066 ;; We use two registers if available.
20067 (define_peephole2
20068   [(match_scratch:SI 0 "r")
20069    (match_scratch:SI 1 "r")
20070    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20071               (clobber (reg:CC FLAGS_REG))
20072               (clobber (mem:BLK (scratch)))])]
20073   "optimize_size || !TARGET_ADD_ESP_8"
20074   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20075               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20076               (clobber (mem:BLK (scratch)))])
20077    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20078               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20079   "")
20080
20081 (define_peephole2
20082   [(match_scratch:SI 0 "r")
20083    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20084               (clobber (reg:CC FLAGS_REG))
20085               (clobber (mem:BLK (scratch)))])]
20086   "optimize_size"
20087   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20088               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20089               (clobber (mem:BLK (scratch)))])
20090    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20091               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20092   "")
20093
20094 ;; Convert esp additions to pop.
20095 (define_peephole2
20096   [(match_scratch:SI 0 "r")
20097    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20098               (clobber (reg:CC FLAGS_REG))])]
20099   ""
20100   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20101               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20102   "")
20103
20104 ;; Two pops case is tricky, since pop causes dependency on destination register.
20105 ;; We use two registers if available.
20106 (define_peephole2
20107   [(match_scratch:SI 0 "r")
20108    (match_scratch:SI 1 "r")
20109    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20110               (clobber (reg:CC FLAGS_REG))])]
20111   ""
20112   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20113               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20114    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20115               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20116   "")
20117
20118 (define_peephole2
20119   [(match_scratch:SI 0 "r")
20120    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20121               (clobber (reg:CC FLAGS_REG))])]
20122   "optimize_size"
20123   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20124               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20125    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20126               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20127   "")
20128 \f
20129 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20130 ;; required and register dies.  Similarly for 128 to plus -128.
20131 (define_peephole2
20132   [(set (match_operand 0 "flags_reg_operand" "")
20133         (match_operator 1 "compare_operator"
20134           [(match_operand 2 "register_operand" "")
20135            (match_operand 3 "const_int_operand" "")]))]
20136   "(INTVAL (operands[3]) == -1
20137     || INTVAL (operands[3]) == 1
20138     || INTVAL (operands[3]) == 128)
20139    && ix86_match_ccmode (insn, CCGCmode)
20140    && peep2_reg_dead_p (1, operands[2])"
20141   [(parallel [(set (match_dup 0)
20142                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20143               (clobber (match_dup 2))])]
20144   "")
20145 \f
20146 (define_peephole2
20147   [(match_scratch:DI 0 "r")
20148    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20149               (clobber (reg:CC FLAGS_REG))
20150               (clobber (mem:BLK (scratch)))])]
20151   "optimize_size || !TARGET_SUB_ESP_4"
20152   [(clobber (match_dup 0))
20153    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20154               (clobber (mem:BLK (scratch)))])])
20155
20156 (define_peephole2
20157   [(match_scratch:DI 0 "r")
20158    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20159               (clobber (reg:CC FLAGS_REG))
20160               (clobber (mem:BLK (scratch)))])]
20161   "optimize_size || !TARGET_SUB_ESP_8"
20162   [(clobber (match_dup 0))
20163    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20164    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20165               (clobber (mem:BLK (scratch)))])])
20166
20167 ;; Convert esp subtractions to push.
20168 (define_peephole2
20169   [(match_scratch:DI 0 "r")
20170    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20171               (clobber (reg:CC FLAGS_REG))])]
20172   "optimize_size || !TARGET_SUB_ESP_4"
20173   [(clobber (match_dup 0))
20174    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20175
20176 (define_peephole2
20177   [(match_scratch:DI 0 "r")
20178    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20179               (clobber (reg:CC FLAGS_REG))])]
20180   "optimize_size || !TARGET_SUB_ESP_8"
20181   [(clobber (match_dup 0))
20182    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20183    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20184
20185 ;; Convert epilogue deallocator to pop.
20186 (define_peephole2
20187   [(match_scratch:DI 0 "r")
20188    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20189               (clobber (reg:CC FLAGS_REG))
20190               (clobber (mem:BLK (scratch)))])]
20191   "optimize_size || !TARGET_ADD_ESP_4"
20192   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20193               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20194               (clobber (mem:BLK (scratch)))])]
20195   "")
20196
20197 ;; Two pops case is tricky, since pop causes dependency on destination register.
20198 ;; We use two registers if available.
20199 (define_peephole2
20200   [(match_scratch:DI 0 "r")
20201    (match_scratch:DI 1 "r")
20202    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20203               (clobber (reg:CC FLAGS_REG))
20204               (clobber (mem:BLK (scratch)))])]
20205   "optimize_size || !TARGET_ADD_ESP_8"
20206   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20207               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20208               (clobber (mem:BLK (scratch)))])
20209    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20210               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20211   "")
20212
20213 (define_peephole2
20214   [(match_scratch:DI 0 "r")
20215    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20216               (clobber (reg:CC FLAGS_REG))
20217               (clobber (mem:BLK (scratch)))])]
20218   "optimize_size"
20219   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20220               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20221               (clobber (mem:BLK (scratch)))])
20222    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20223               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20224   "")
20225
20226 ;; Convert esp additions to pop.
20227 (define_peephole2
20228   [(match_scratch:DI 0 "r")
20229    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20230               (clobber (reg:CC FLAGS_REG))])]
20231   ""
20232   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20233               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20234   "")
20235
20236 ;; Two pops case is tricky, since pop causes dependency on destination register.
20237 ;; We use two registers if available.
20238 (define_peephole2
20239   [(match_scratch:DI 0 "r")
20240    (match_scratch:DI 1 "r")
20241    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20242               (clobber (reg:CC FLAGS_REG))])]
20243   ""
20244   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20245               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20246    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20247               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20248   "")
20249
20250 (define_peephole2
20251   [(match_scratch:DI 0 "r")
20252    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20253               (clobber (reg:CC FLAGS_REG))])]
20254   "optimize_size"
20255   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20256               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20257    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20258               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20259   "")
20260 \f
20261 ;; Convert imul by three, five and nine into lea
20262 (define_peephole2
20263   [(parallel
20264     [(set (match_operand:SI 0 "register_operand" "")
20265           (mult:SI (match_operand:SI 1 "register_operand" "")
20266                    (match_operand:SI 2 "const_int_operand" "")))
20267      (clobber (reg:CC FLAGS_REG))])]
20268   "INTVAL (operands[2]) == 3
20269    || INTVAL (operands[2]) == 5
20270    || INTVAL (operands[2]) == 9"
20271   [(set (match_dup 0)
20272         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20273                  (match_dup 1)))]
20274   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20275
20276 (define_peephole2
20277   [(parallel
20278     [(set (match_operand:SI 0 "register_operand" "")
20279           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20280                    (match_operand:SI 2 "const_int_operand" "")))
20281      (clobber (reg:CC FLAGS_REG))])]
20282   "!optimize_size
20283    && (INTVAL (operands[2]) == 3
20284        || INTVAL (operands[2]) == 5
20285        || INTVAL (operands[2]) == 9)"
20286   [(set (match_dup 0) (match_dup 1))
20287    (set (match_dup 0)
20288         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20289                  (match_dup 0)))]
20290   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20291
20292 (define_peephole2
20293   [(parallel
20294     [(set (match_operand:DI 0 "register_operand" "")
20295           (mult:DI (match_operand:DI 1 "register_operand" "")
20296                    (match_operand:DI 2 "const_int_operand" "")))
20297      (clobber (reg:CC FLAGS_REG))])]
20298   "TARGET_64BIT
20299    && (INTVAL (operands[2]) == 3
20300        || INTVAL (operands[2]) == 5
20301        || INTVAL (operands[2]) == 9)"
20302   [(set (match_dup 0)
20303         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20304                  (match_dup 1)))]
20305   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20306
20307 (define_peephole2
20308   [(parallel
20309     [(set (match_operand:DI 0 "register_operand" "")
20310           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20311                    (match_operand:DI 2 "const_int_operand" "")))
20312      (clobber (reg:CC FLAGS_REG))])]
20313   "TARGET_64BIT
20314    && !optimize_size
20315    && (INTVAL (operands[2]) == 3
20316        || INTVAL (operands[2]) == 5
20317        || INTVAL (operands[2]) == 9)"
20318   [(set (match_dup 0) (match_dup 1))
20319    (set (match_dup 0)
20320         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20321                  (match_dup 0)))]
20322   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20323
20324 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20325 ;; imul $32bit_imm, reg, reg is direct decoded.
20326 (define_peephole2
20327   [(match_scratch:DI 3 "r")
20328    (parallel [(set (match_operand:DI 0 "register_operand" "")
20329                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20330                             (match_operand:DI 2 "immediate_operand" "")))
20331               (clobber (reg:CC FLAGS_REG))])]
20332   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20333    && !satisfies_constraint_K (operands[2])"
20334   [(set (match_dup 3) (match_dup 1))
20335    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20336               (clobber (reg:CC FLAGS_REG))])]
20337 "")
20338
20339 (define_peephole2
20340   [(match_scratch:SI 3 "r")
20341    (parallel [(set (match_operand:SI 0 "register_operand" "")
20342                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20343                             (match_operand:SI 2 "immediate_operand" "")))
20344               (clobber (reg:CC FLAGS_REG))])]
20345   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20346    && !satisfies_constraint_K (operands[2])"
20347   [(set (match_dup 3) (match_dup 1))
20348    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20349               (clobber (reg:CC FLAGS_REG))])]
20350 "")
20351
20352 (define_peephole2
20353   [(match_scratch:SI 3 "r")
20354    (parallel [(set (match_operand:DI 0 "register_operand" "")
20355                    (zero_extend:DI
20356                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20357                               (match_operand:SI 2 "immediate_operand" ""))))
20358               (clobber (reg:CC FLAGS_REG))])]
20359   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20360    && !satisfies_constraint_K (operands[2])"
20361   [(set (match_dup 3) (match_dup 1))
20362    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20363               (clobber (reg:CC FLAGS_REG))])]
20364 "")
20365
20366 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20367 ;; Convert it into imul reg, reg
20368 ;; It would be better to force assembler to encode instruction using long
20369 ;; immediate, but there is apparently no way to do so.
20370 (define_peephole2
20371   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20372                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20373                             (match_operand:DI 2 "const_int_operand" "")))
20374               (clobber (reg:CC FLAGS_REG))])
20375    (match_scratch:DI 3 "r")]
20376   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20377    && satisfies_constraint_K (operands[2])"
20378   [(set (match_dup 3) (match_dup 2))
20379    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20380               (clobber (reg:CC FLAGS_REG))])]
20381 {
20382   if (!rtx_equal_p (operands[0], operands[1]))
20383     emit_move_insn (operands[0], operands[1]);
20384 })
20385
20386 (define_peephole2
20387   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20388                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20389                             (match_operand:SI 2 "const_int_operand" "")))
20390               (clobber (reg:CC FLAGS_REG))])
20391    (match_scratch:SI 3 "r")]
20392   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20393    && satisfies_constraint_K (operands[2])"
20394   [(set (match_dup 3) (match_dup 2))
20395    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20396               (clobber (reg:CC FLAGS_REG))])]
20397 {
20398   if (!rtx_equal_p (operands[0], operands[1]))
20399     emit_move_insn (operands[0], operands[1]);
20400 })
20401
20402 (define_peephole2
20403   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20404                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20405                             (match_operand:HI 2 "immediate_operand" "")))
20406               (clobber (reg:CC FLAGS_REG))])
20407    (match_scratch:HI 3 "r")]
20408   "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20409   [(set (match_dup 3) (match_dup 2))
20410    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20411               (clobber (reg:CC FLAGS_REG))])]
20412 {
20413   if (!rtx_equal_p (operands[0], operands[1]))
20414     emit_move_insn (operands[0], operands[1]);
20415 })
20416
20417 ;; After splitting up read-modify operations, array accesses with memory
20418 ;; operands might end up in form:
20419 ;;  sall    $2, %eax
20420 ;;  movl    4(%esp), %edx
20421 ;;  addl    %edx, %eax
20422 ;; instead of pre-splitting:
20423 ;;  sall    $2, %eax
20424 ;;  addl    4(%esp), %eax
20425 ;; Turn it into:
20426 ;;  movl    4(%esp), %edx
20427 ;;  leal    (%edx,%eax,4), %eax
20428
20429 (define_peephole2
20430   [(parallel [(set (match_operand 0 "register_operand" "")
20431                    (ashift (match_operand 1 "register_operand" "")
20432                            (match_operand 2 "const_int_operand" "")))
20433                (clobber (reg:CC FLAGS_REG))])
20434    (set (match_operand 3 "register_operand")
20435         (match_operand 4 "x86_64_general_operand" ""))
20436    (parallel [(set (match_operand 5 "register_operand" "")
20437                    (plus (match_operand 6 "register_operand" "")
20438                          (match_operand 7 "register_operand" "")))
20439                    (clobber (reg:CC FLAGS_REG))])]
20440   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20441    /* Validate MODE for lea.  */
20442    && ((!TARGET_PARTIAL_REG_STALL
20443         && (GET_MODE (operands[0]) == QImode
20444             || GET_MODE (operands[0]) == HImode))
20445        || GET_MODE (operands[0]) == SImode
20446        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20447    /* We reorder load and the shift.  */
20448    && !rtx_equal_p (operands[1], operands[3])
20449    && !reg_overlap_mentioned_p (operands[0], operands[4])
20450    /* Last PLUS must consist of operand 0 and 3.  */
20451    && !rtx_equal_p (operands[0], operands[3])
20452    && (rtx_equal_p (operands[3], operands[6])
20453        || rtx_equal_p (operands[3], operands[7]))
20454    && (rtx_equal_p (operands[0], operands[6])
20455        || rtx_equal_p (operands[0], operands[7]))
20456    /* The intermediate operand 0 must die or be same as output.  */
20457    && (rtx_equal_p (operands[0], operands[5])
20458        || peep2_reg_dead_p (3, operands[0]))"
20459   [(set (match_dup 3) (match_dup 4))
20460    (set (match_dup 0) (match_dup 1))]
20461 {
20462   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20463   int scale = 1 << INTVAL (operands[2]);
20464   rtx index = gen_lowpart (Pmode, operands[1]);
20465   rtx base = gen_lowpart (Pmode, operands[3]);
20466   rtx dest = gen_lowpart (mode, operands[5]);
20467
20468   operands[1] = gen_rtx_PLUS (Pmode, base,
20469                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20470   if (mode != Pmode)
20471     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20472   operands[0] = dest;
20473 })
20474 \f
20475 ;; Call-value patterns last so that the wildcard operand does not
20476 ;; disrupt insn-recog's switch tables.
20477
20478 (define_insn "*call_value_pop_0"
20479   [(set (match_operand 0 "" "")
20480         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20481               (match_operand:SI 2 "" "")))
20482    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20483                             (match_operand:SI 3 "immediate_operand" "")))]
20484   "!TARGET_64BIT"
20485 {
20486   if (SIBLING_CALL_P (insn))
20487     return "jmp\t%P1";
20488   else
20489     return "call\t%P1";
20490 }
20491   [(set_attr "type" "callv")])
20492
20493 (define_insn "*call_value_pop_1"
20494   [(set (match_operand 0 "" "")
20495         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20496               (match_operand:SI 2 "" "")))
20497    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20498                             (match_operand:SI 3 "immediate_operand" "i")))]
20499   "!TARGET_64BIT"
20500 {
20501   if (constant_call_address_operand (operands[1], Pmode))
20502     {
20503       if (SIBLING_CALL_P (insn))
20504         return "jmp\t%P1";
20505       else
20506         return "call\t%P1";
20507     }
20508   if (SIBLING_CALL_P (insn))
20509     return "jmp\t%A1";
20510   else
20511     return "call\t%A1";
20512 }
20513   [(set_attr "type" "callv")])
20514
20515 (define_insn "*call_value_0"
20516   [(set (match_operand 0 "" "")
20517         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20518               (match_operand:SI 2 "" "")))]
20519   "!TARGET_64BIT"
20520 {
20521   if (SIBLING_CALL_P (insn))
20522     return "jmp\t%P1";
20523   else
20524     return "call\t%P1";
20525 }
20526   [(set_attr "type" "callv")])
20527
20528 (define_insn "*call_value_0_rex64"
20529   [(set (match_operand 0 "" "")
20530         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20531               (match_operand:DI 2 "const_int_operand" "")))]
20532   "TARGET_64BIT"
20533 {
20534   if (SIBLING_CALL_P (insn))
20535     return "jmp\t%P1";
20536   else
20537     return "call\t%P1";
20538 }
20539   [(set_attr "type" "callv")])
20540
20541 (define_insn "*call_value_1"
20542   [(set (match_operand 0 "" "")
20543         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20544               (match_operand:SI 2 "" "")))]
20545   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20546 {
20547   if (constant_call_address_operand (operands[1], Pmode))
20548     return "call\t%P1";
20549   return "call\t%A1";
20550 }
20551   [(set_attr "type" "callv")])
20552
20553 (define_insn "*sibcall_value_1"
20554   [(set (match_operand 0 "" "")
20555         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20556               (match_operand:SI 2 "" "")))]
20557   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20558 {
20559   if (constant_call_address_operand (operands[1], Pmode))
20560     return "jmp\t%P1";
20561   return "jmp\t%A1";
20562 }
20563   [(set_attr "type" "callv")])
20564
20565 (define_insn "*call_value_1_rex64"
20566   [(set (match_operand 0 "" "")
20567         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20568               (match_operand:DI 2 "" "")))]
20569   "!SIBLING_CALL_P (insn) && TARGET_64BIT
20570    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20571 {
20572   if (constant_call_address_operand (operands[1], Pmode))
20573     return "call\t%P1";
20574   return "call\t%A1";
20575 }
20576   [(set_attr "type" "callv")])
20577
20578 (define_insn "*call_value_1_rex64_large"
20579   [(set (match_operand 0 "" "")
20580         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20581               (match_operand:DI 2 "" "")))]
20582   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20583   "call\t%A1"
20584   [(set_attr "type" "callv")])
20585
20586 (define_insn "*sibcall_value_1_rex64"
20587   [(set (match_operand 0 "" "")
20588         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20589               (match_operand:DI 2 "" "")))]
20590   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20591   "jmp\t%P1"
20592   [(set_attr "type" "callv")])
20593
20594 (define_insn "*sibcall_value_1_rex64_v"
20595   [(set (match_operand 0 "" "")
20596         (call (mem:QI (reg:DI R11_REG))
20597               (match_operand:DI 1 "" "")))]
20598   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20599   "jmp\t*%%r11"
20600   [(set_attr "type" "callv")])
20601 \f
20602 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20603 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20604 ;; caught for use by garbage collectors and the like.  Using an insn that
20605 ;; maps to SIGILL makes it more likely the program will rightfully die.
20606 ;; Keeping with tradition, "6" is in honor of #UD.
20607 (define_insn "trap"
20608   [(trap_if (const_int 1) (const_int 6))]
20609   ""
20610   { return ASM_SHORT "0x0b0f"; }
20611   [(set_attr "length" "2")])
20612
20613 (define_expand "sse_prologue_save"
20614   [(parallel [(set (match_operand:BLK 0 "" "")
20615                    (unspec:BLK [(reg:DI 21)
20616                                 (reg:DI 22)
20617                                 (reg:DI 23)
20618                                 (reg:DI 24)
20619                                 (reg:DI 25)
20620                                 (reg:DI 26)
20621                                 (reg:DI 27)
20622                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20623               (use (match_operand:DI 1 "register_operand" ""))
20624               (use (match_operand:DI 2 "immediate_operand" ""))
20625               (use (label_ref:DI (match_operand 3 "" "")))])]
20626   "TARGET_64BIT"
20627   "")
20628
20629 (define_insn "*sse_prologue_save_insn"
20630   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20631                           (match_operand:DI 4 "const_int_operand" "n")))
20632         (unspec:BLK [(reg:DI 21)
20633                      (reg:DI 22)
20634                      (reg:DI 23)
20635                      (reg:DI 24)
20636                      (reg:DI 25)
20637                      (reg:DI 26)
20638                      (reg:DI 27)
20639                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20640    (use (match_operand:DI 1 "register_operand" "r"))
20641    (use (match_operand:DI 2 "const_int_operand" "i"))
20642    (use (label_ref:DI (match_operand 3 "" "X")))]
20643   "TARGET_64BIT
20644    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20645    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20646   "*
20647 {
20648   int i;
20649   operands[0] = gen_rtx_MEM (Pmode,
20650                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20651   output_asm_insn (\"jmp\\t%A1\", operands);
20652   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20653     {
20654       operands[4] = adjust_address (operands[0], DImode, i*16);
20655       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20656       PUT_MODE (operands[4], TImode);
20657       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20658         output_asm_insn (\"rex\", operands);
20659       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20660     }
20661   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20662                              CODE_LABEL_NUMBER (operands[3]));
20663   return \"\";
20664 }
20665   "
20666   [(set_attr "type" "other")
20667    (set_attr "length_immediate" "0")
20668    (set_attr "length_address" "0")
20669    (set_attr "length" "135")
20670    (set_attr "memory" "store")
20671    (set_attr "modrm" "0")
20672    (set_attr "mode" "DI")])
20673
20674 (define_expand "prefetch"
20675   [(prefetch (match_operand 0 "address_operand" "")
20676              (match_operand:SI 1 "const_int_operand" "")
20677              (match_operand:SI 2 "const_int_operand" ""))]
20678   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20679 {
20680   int rw = INTVAL (operands[1]);
20681   int locality = INTVAL (operands[2]);
20682
20683   gcc_assert (rw == 0 || rw == 1);
20684   gcc_assert (locality >= 0 && locality <= 3);
20685   gcc_assert (GET_MODE (operands[0]) == Pmode
20686               || GET_MODE (operands[0]) == VOIDmode);
20687
20688   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20689      supported by SSE counterpart or the SSE prefetch is not available
20690      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20691      of locality.  */
20692   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20693     operands[2] = GEN_INT (3);
20694   else
20695     operands[1] = const0_rtx;
20696 })
20697
20698 (define_insn "*prefetch_sse"
20699   [(prefetch (match_operand:SI 0 "address_operand" "p")
20700              (const_int 0)
20701              (match_operand:SI 1 "const_int_operand" ""))]
20702   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20703 {
20704   static const char * const patterns[4] = {
20705    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20706   };
20707
20708   int locality = INTVAL (operands[1]);
20709   gcc_assert (locality >= 0 && locality <= 3);
20710
20711   return patterns[locality];
20712 }
20713   [(set_attr "type" "sse")
20714    (set_attr "memory" "none")])
20715
20716 (define_insn "*prefetch_sse_rex"
20717   [(prefetch (match_operand:DI 0 "address_operand" "p")
20718              (const_int 0)
20719              (match_operand:SI 1 "const_int_operand" ""))]
20720   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20721 {
20722   static const char * const patterns[4] = {
20723    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20724   };
20725
20726   int locality = INTVAL (operands[1]);
20727   gcc_assert (locality >= 0 && locality <= 3);
20728
20729   return patterns[locality];
20730 }
20731   [(set_attr "type" "sse")
20732    (set_attr "memory" "none")])
20733
20734 (define_insn "*prefetch_3dnow"
20735   [(prefetch (match_operand:SI 0 "address_operand" "p")
20736              (match_operand:SI 1 "const_int_operand" "n")
20737              (const_int 3))]
20738   "TARGET_3DNOW && !TARGET_64BIT"
20739 {
20740   if (INTVAL (operands[1]) == 0)
20741     return "prefetch\t%a0";
20742   else
20743     return "prefetchw\t%a0";
20744 }
20745   [(set_attr "type" "mmx")
20746    (set_attr "memory" "none")])
20747
20748 (define_insn "*prefetch_3dnow_rex"
20749   [(prefetch (match_operand:DI 0 "address_operand" "p")
20750              (match_operand:SI 1 "const_int_operand" "n")
20751              (const_int 3))]
20752   "TARGET_3DNOW && TARGET_64BIT"
20753 {
20754   if (INTVAL (operands[1]) == 0)
20755     return "prefetch\t%a0";
20756   else
20757     return "prefetchw\t%a0";
20758 }
20759   [(set_attr "type" "mmx")
20760    (set_attr "memory" "none")])
20761
20762 (define_expand "stack_protect_set"
20763   [(match_operand 0 "memory_operand" "")
20764    (match_operand 1 "memory_operand" "")]
20765   ""
20766 {
20767 #ifdef TARGET_THREAD_SSP_OFFSET
20768   if (TARGET_64BIT)
20769     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20770                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20771   else
20772     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20773                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20774 #else
20775   if (TARGET_64BIT)
20776     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20777   else
20778     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20779 #endif
20780   DONE;
20781 })
20782
20783 (define_insn "stack_protect_set_si"
20784   [(set (match_operand:SI 0 "memory_operand" "=m")
20785         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20786    (set (match_scratch:SI 2 "=&r") (const_int 0))
20787    (clobber (reg:CC FLAGS_REG))]
20788   ""
20789   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20790   [(set_attr "type" "multi")])
20791
20792 (define_insn "stack_protect_set_di"
20793   [(set (match_operand:DI 0 "memory_operand" "=m")
20794         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20795    (set (match_scratch:DI 2 "=&r") (const_int 0))
20796    (clobber (reg:CC FLAGS_REG))]
20797   "TARGET_64BIT"
20798   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20799   [(set_attr "type" "multi")])
20800
20801 (define_insn "stack_tls_protect_set_si"
20802   [(set (match_operand:SI 0 "memory_operand" "=m")
20803         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20804    (set (match_scratch:SI 2 "=&r") (const_int 0))
20805    (clobber (reg:CC FLAGS_REG))]
20806   ""
20807   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20808   [(set_attr "type" "multi")])
20809
20810 (define_insn "stack_tls_protect_set_di"
20811   [(set (match_operand:DI 0 "memory_operand" "=m")
20812         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20813    (set (match_scratch:DI 2 "=&r") (const_int 0))
20814    (clobber (reg:CC FLAGS_REG))]
20815   "TARGET_64BIT"
20816   {
20817      /* The kernel uses a different segment register for performance reasons; a
20818         system call would not have to trash the userspace segment register,
20819         which would be expensive */
20820      if (ix86_cmodel != CM_KERNEL)
20821         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20822      else
20823         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20824   }
20825   [(set_attr "type" "multi")])
20826
20827 (define_expand "stack_protect_test"
20828   [(match_operand 0 "memory_operand" "")
20829    (match_operand 1 "memory_operand" "")
20830    (match_operand 2 "" "")]
20831   ""
20832 {
20833   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20834   ix86_compare_op0 = operands[0];
20835   ix86_compare_op1 = operands[1];
20836   ix86_compare_emitted = flags;
20837
20838 #ifdef TARGET_THREAD_SSP_OFFSET
20839   if (TARGET_64BIT)
20840     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20841                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20842   else
20843     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20844                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20845 #else
20846   if (TARGET_64BIT)
20847     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20848   else
20849     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20850 #endif
20851   emit_jump_insn (gen_beq (operands[2]));
20852   DONE;
20853 })
20854
20855 (define_insn "stack_protect_test_si"
20856   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20857         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20858                      (match_operand:SI 2 "memory_operand" "m")]
20859                     UNSPEC_SP_TEST))
20860    (clobber (match_scratch:SI 3 "=&r"))]
20861   ""
20862   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20863   [(set_attr "type" "multi")])
20864
20865 (define_insn "stack_protect_test_di"
20866   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20867         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20868                      (match_operand:DI 2 "memory_operand" "m")]
20869                     UNSPEC_SP_TEST))
20870    (clobber (match_scratch:DI 3 "=&r"))]
20871   "TARGET_64BIT"
20872   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20873   [(set_attr "type" "multi")])
20874
20875 (define_insn "stack_tls_protect_test_si"
20876   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20877         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20878                      (match_operand:SI 2 "const_int_operand" "i")]
20879                     UNSPEC_SP_TLS_TEST))
20880    (clobber (match_scratch:SI 3 "=r"))]
20881   ""
20882   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20883   [(set_attr "type" "multi")])
20884
20885 (define_insn "stack_tls_protect_test_di"
20886   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20887         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20888                      (match_operand:DI 2 "const_int_operand" "i")]
20889                     UNSPEC_SP_TLS_TEST))
20890    (clobber (match_scratch:DI 3 "=r"))]
20891   "TARGET_64BIT"
20892   {
20893      /* The kernel uses a different segment register for performance reasons; a
20894         system call would not have to trash the userspace segment register,
20895         which would be expensive */
20896      if (ix86_cmodel != CM_KERNEL)
20897         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20898      else
20899         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20900   }
20901   [(set_attr "type" "multi")])
20902
20903 (define_mode_macro CRC32MODE [QI HI SI])
20904 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
20905 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
20906
20907 (define_insn "sse4_2_crc32<mode>"
20908   [(set (match_operand:SI 0 "register_operand" "=r")
20909         (unspec:SI
20910           [(match_operand:SI 1 "register_operand" "0")
20911            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
20912           UNSPEC_CRC32))]
20913   "TARGET_SSE4_2"
20914   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
20915   [(set_attr "type" "sselog1")
20916    (set_attr "prefix_rep" "1")
20917    (set_attr "prefix_extra" "1")
20918    (set_attr "mode" "SI")])
20919
20920 (define_insn "sse4_2_crc32di"
20921   [(set (match_operand:DI 0 "register_operand" "=r")
20922         (unspec:DI
20923           [(match_operand:DI 1 "register_operand" "0")
20924            (match_operand:DI 2 "nonimmediate_operand" "rm")]
20925           UNSPEC_CRC32))]
20926   "TARGET_SSE4_2 && TARGET_64BIT"
20927   "crc32q\t{%2, %0|%0, %2}"
20928   [(set_attr "type" "sselog1")
20929    (set_attr "prefix_rep" "1")
20930    (set_attr "prefix_extra" "1")
20931    (set_attr "mode" "DI")])
20932
20933 (include "mmx.md")
20934 (include "sse.md")
20935 (include "sync.md")