OSDN Git Service

f3fb8487590bc5d7cebec1c42be4009788a14ee2
[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
167 (define_constants
168   [(UNSPECV_BLOCKAGE            0)
169    (UNSPECV_STACK_PROBE         1)
170    (UNSPECV_EMMS                2)
171    (UNSPECV_LDMXCSR             3)
172    (UNSPECV_STMXCSR             4)
173    (UNSPECV_FEMMS               5)
174    (UNSPECV_CLFLUSH             6)
175    (UNSPECV_ALIGN               7)
176    (UNSPECV_MONITOR             8)
177    (UNSPECV_MWAIT               9)
178    (UNSPECV_CMPXCHG_1           10)
179    (UNSPECV_CMPXCHG_2           11)
180    (UNSPECV_XCHG                12)
181    (UNSPECV_LOCK                13)
182   ])
183
184 ;; Registers by name.
185 (define_constants
186   [(BP_REG                       6)
187    (SP_REG                       7)
188    (FLAGS_REG                   17)
189    (FPSR_REG                    18)
190    (FPCR_REG                    19)
191    (R10_REG                     39)
192    (R11_REG                     40)
193   ])
194
195 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
196 ;; from i386.c.
197
198 ;; In C guard expressions, put expressions which may be compile-time
199 ;; constants first.  This allows for better optimization.  For
200 ;; example, write "TARGET_64BIT && reload_completed", not
201 ;; "reload_completed && TARGET_64BIT".
202
203 \f
204 ;; Processor type.  This attribute must exactly match the processor_type
205 ;; enumeration in i386.h.
206 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
207                     nocona,core2,generic32,generic64,amdfam10"
208   (const (symbol_ref "ix86_tune")))
209
210 ;; A basic instruction type.  Refinements due to arguments to be
211 ;; provided in other attributes.
212 (define_attr "type"
213   "other,multi,
214    alu,alu1,negnot,imov,imovx,lea,
215    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
216    icmp,test,ibr,setcc,icmov,
217    push,pop,call,callv,leave,
218    str,bitmanip,
219    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
220    sselog,sselog1,sseiadd,sseishft,sseimul,
221    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins,
222    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
223   (const_string "other"))
224
225 ;; Main data type used by the insn
226 (define_attr "mode"
227   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
228   (const_string "unknown"))
229
230 ;; The CPU unit operations uses.
231 (define_attr "unit" "integer,i387,sse,mmx,unknown"
232   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
233            (const_string "i387")
234          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
235                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins")
236            (const_string "sse")
237          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
238            (const_string "mmx")
239          (eq_attr "type" "other")
240            (const_string "unknown")]
241          (const_string "integer")))
242
243 ;; The (bounding maximum) length of an instruction immediate.
244 (define_attr "length_immediate" ""
245   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
246                           bitmanip")
247            (const_int 0)
248          (eq_attr "unit" "i387,sse,mmx")
249            (const_int 0)
250          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
251                           imul,icmp,push,pop")
252            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
253          (eq_attr "type" "imov,test")
254            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
255          (eq_attr "type" "call")
256            (if_then_else (match_operand 0 "constant_call_address_operand" "")
257              (const_int 4)
258              (const_int 0))
259          (eq_attr "type" "callv")
260            (if_then_else (match_operand 1 "constant_call_address_operand" "")
261              (const_int 4)
262              (const_int 0))
263          ;; We don't know the size before shorten_branches.  Expect
264          ;; the instruction to fit for better scheduling.
265          (eq_attr "type" "ibr")
266            (const_int 1)
267          ]
268          (symbol_ref "/* Update immediate_length and other attributes! */
269                       gcc_unreachable (),1")))
270
271 ;; The (bounding maximum) length of an instruction address.
272 (define_attr "length_address" ""
273   (cond [(eq_attr "type" "str,other,multi,fxch")
274            (const_int 0)
275          (and (eq_attr "type" "call")
276               (match_operand 0 "constant_call_address_operand" ""))
277              (const_int 0)
278          (and (eq_attr "type" "callv")
279               (match_operand 1 "constant_call_address_operand" ""))
280              (const_int 0)
281          ]
282          (symbol_ref "ix86_attr_length_address_default (insn)")))
283
284 ;; Set when length prefix is used.
285 (define_attr "prefix_data16" ""
286   (if_then_else (ior (eq_attr "mode" "HI")
287                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
288     (const_int 1)
289     (const_int 0)))
290
291 ;; Set when string REP prefix is used.
292 (define_attr "prefix_rep" ""
293   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
294     (const_int 1)
295     (const_int 0)))
296
297 ;; Set when 0f opcode prefix is used.
298 (define_attr "prefix_0f" ""
299   (if_then_else
300     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
301          (eq_attr "unit" "sse,mmx"))
302     (const_int 1)
303     (const_int 0)))
304
305 ;; Set when REX opcode prefix is used.
306 (define_attr "prefix_rex" ""
307   (cond [(and (eq_attr "mode" "DI")
308               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
309            (const_int 1)
310          (and (eq_attr "mode" "QI")
311               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
312                   (const_int 0)))
313            (const_int 1)
314          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
315              (const_int 0))
316            (const_int 1)
317         ]
318         (const_int 0)))
319
320 ;; Set when modrm byte is used.
321 (define_attr "modrm" ""
322   (cond [(eq_attr "type" "str,leave")
323            (const_int 0)
324          (eq_attr "unit" "i387")
325            (const_int 0)
326          (and (eq_attr "type" "incdec")
327               (ior (match_operand:SI 1 "register_operand" "")
328                    (match_operand:HI 1 "register_operand" "")))
329            (const_int 0)
330          (and (eq_attr "type" "push")
331               (not (match_operand 1 "memory_operand" "")))
332            (const_int 0)
333          (and (eq_attr "type" "pop")
334               (not (match_operand 0 "memory_operand" "")))
335            (const_int 0)
336          (and (eq_attr "type" "imov")
337               (ior (and (match_operand 0 "register_operand" "")
338                         (match_operand 1 "immediate_operand" ""))
339                    (ior (and (match_operand 0 "ax_reg_operand" "")
340                              (match_operand 1 "memory_displacement_only_operand" ""))
341                         (and (match_operand 0 "memory_displacement_only_operand" "")
342                              (match_operand 1 "ax_reg_operand" "")))))
343            (const_int 0)
344          (and (eq_attr "type" "call")
345               (match_operand 0 "constant_call_address_operand" ""))
346              (const_int 0)
347          (and (eq_attr "type" "callv")
348               (match_operand 1 "constant_call_address_operand" ""))
349              (const_int 0)
350          ]
351          (const_int 1)))
352
353 ;; The (bounding maximum) length of an instruction in bytes.
354 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
355 ;; Later we may want to split them and compute proper length as for
356 ;; other insns.
357 (define_attr "length" ""
358   (cond [(eq_attr "type" "other,multi,fistp,frndint")
359            (const_int 16)
360          (eq_attr "type" "fcmp")
361            (const_int 4)
362          (eq_attr "unit" "i387")
363            (plus (const_int 2)
364                  (plus (attr "prefix_data16")
365                        (attr "length_address")))]
366          (plus (plus (attr "modrm")
367                      (plus (attr "prefix_0f")
368                            (plus (attr "prefix_rex")
369                                  (const_int 1))))
370                (plus (attr "prefix_rep")
371                      (plus (attr "prefix_data16")
372                            (plus (attr "length_immediate")
373                                  (attr "length_address")))))))
374
375 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
376 ;; `store' if there is a simple memory reference therein, or `unknown'
377 ;; if the instruction is complex.
378
379 (define_attr "memory" "none,load,store,both,unknown"
380   (cond [(eq_attr "type" "other,multi,str")
381            (const_string "unknown")
382          (eq_attr "type" "lea,fcmov,fpspc")
383            (const_string "none")
384          (eq_attr "type" "fistp,leave")
385            (const_string "both")
386          (eq_attr "type" "frndint")
387            (const_string "load")
388          (eq_attr "type" "push")
389            (if_then_else (match_operand 1 "memory_operand" "")
390              (const_string "both")
391              (const_string "store"))
392          (eq_attr "type" "pop")
393            (if_then_else (match_operand 0 "memory_operand" "")
394              (const_string "both")
395              (const_string "load"))
396          (eq_attr "type" "setcc")
397            (if_then_else (match_operand 0 "memory_operand" "")
398              (const_string "store")
399              (const_string "none"))
400          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
401            (if_then_else (ior (match_operand 0 "memory_operand" "")
402                               (match_operand 1 "memory_operand" ""))
403              (const_string "load")
404              (const_string "none"))
405          (eq_attr "type" "ibr")
406            (if_then_else (match_operand 0 "memory_operand" "")
407              (const_string "load")
408              (const_string "none"))
409          (eq_attr "type" "call")
410            (if_then_else (match_operand 0 "constant_call_address_operand" "")
411              (const_string "none")
412              (const_string "load"))
413          (eq_attr "type" "callv")
414            (if_then_else (match_operand 1 "constant_call_address_operand" "")
415              (const_string "none")
416              (const_string "load"))
417          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
418               (match_operand 1 "memory_operand" ""))
419            (const_string "both")
420          (and (match_operand 0 "memory_operand" "")
421               (match_operand 1 "memory_operand" ""))
422            (const_string "both")
423          (match_operand 0 "memory_operand" "")
424            (const_string "store")
425          (match_operand 1 "memory_operand" "")
426            (const_string "load")
427          (and (eq_attr "type"
428                  "!alu1,negnot,ishift1,
429                    imov,imovx,icmp,test,bitmanip,
430                    fmov,fcmp,fsgn,
431                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
432                    mmx,mmxmov,mmxcmp,mmxcvt")
433               (match_operand 2 "memory_operand" ""))
434            (const_string "load")
435          (and (eq_attr "type" "icmov")
436               (match_operand 3 "memory_operand" ""))
437            (const_string "load")
438         ]
439         (const_string "none")))
440
441 ;; Indicates if an instruction has both an immediate and a displacement.
442
443 (define_attr "imm_disp" "false,true,unknown"
444   (cond [(eq_attr "type" "other,multi")
445            (const_string "unknown")
446          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
447               (and (match_operand 0 "memory_displacement_operand" "")
448                    (match_operand 1 "immediate_operand" "")))
449            (const_string "true")
450          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
451               (and (match_operand 0 "memory_displacement_operand" "")
452                    (match_operand 2 "immediate_operand" "")))
453            (const_string "true")
454         ]
455         (const_string "false")))
456
457 ;; Indicates if an FP operation has an integer source.
458
459 (define_attr "fp_int_src" "false,true"
460   (const_string "false"))
461
462 ;; Defines rounding mode of an FP operation.
463
464 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
465   (const_string "any"))
466
467 ;; Describe a user's asm statement.
468 (define_asm_attributes
469   [(set_attr "length" "128")
470    (set_attr "type" "multi")])
471
472 ;; All x87 floating point modes
473 (define_mode_macro X87MODEF [SF DF XF])
474
475 ;; x87 SFmode and DFMode floating point modes
476 (define_mode_macro X87MODEF12 [SF DF])
477
478 ;; All integer modes handled by x87 fisttp operator.
479 (define_mode_macro X87MODEI [HI SI DI])
480
481 ;; All integer modes handled by integer x87 operators.
482 (define_mode_macro X87MODEI12 [HI SI])
483
484 ;; All SSE floating point modes
485 (define_mode_macro SSEMODEF [SF DF])
486
487 ;; All integer modes handled by SSE cvtts?2si* operators.
488 (define_mode_macro SSEMODEI24 [SI DI])
489
490 ;; SSE asm suffix for floating point modes
491 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
492
493 ;; SSE vector mode corresponding to a scalar mode
494 (define_mode_attr ssevecmode
495   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
496 \f
497 ;; Scheduling descriptions
498
499 (include "pentium.md")
500 (include "ppro.md")
501 (include "k6.md")
502 (include "athlon.md")
503 (include "geode.md")
504
505 \f
506 ;; Operand and operator predicates and constraints
507
508 (include "predicates.md")
509 (include "constraints.md")
510
511 \f
512 ;; Compare instructions.
513
514 ;; All compare insns have expanders that save the operands away without
515 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
516 ;; after the cmp) will actually emit the cmpM.
517
518 (define_expand "cmpti"
519   [(set (reg:CC FLAGS_REG)
520         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
521                     (match_operand:TI 1 "x86_64_general_operand" "")))]
522   "TARGET_64BIT"
523 {
524   if (MEM_P (operands[0]) && MEM_P (operands[1]))
525     operands[0] = force_reg (TImode, operands[0]);
526   ix86_compare_op0 = operands[0];
527   ix86_compare_op1 = operands[1];
528   DONE;
529 })
530
531 (define_expand "cmpdi"
532   [(set (reg:CC FLAGS_REG)
533         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
534                     (match_operand:DI 1 "x86_64_general_operand" "")))]
535   ""
536 {
537   if (MEM_P (operands[0]) && MEM_P (operands[1]))
538     operands[0] = force_reg (DImode, operands[0]);
539   ix86_compare_op0 = operands[0];
540   ix86_compare_op1 = operands[1];
541   DONE;
542 })
543
544 (define_expand "cmpsi"
545   [(set (reg:CC FLAGS_REG)
546         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
547                     (match_operand:SI 1 "general_operand" "")))]
548   ""
549 {
550   if (MEM_P (operands[0]) && MEM_P (operands[1]))
551     operands[0] = force_reg (SImode, operands[0]);
552   ix86_compare_op0 = operands[0];
553   ix86_compare_op1 = operands[1];
554   DONE;
555 })
556
557 (define_expand "cmphi"
558   [(set (reg:CC FLAGS_REG)
559         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
560                     (match_operand:HI 1 "general_operand" "")))]
561   ""
562 {
563   if (MEM_P (operands[0]) && MEM_P (operands[1]))
564     operands[0] = force_reg (HImode, operands[0]);
565   ix86_compare_op0 = operands[0];
566   ix86_compare_op1 = operands[1];
567   DONE;
568 })
569
570 (define_expand "cmpqi"
571   [(set (reg:CC FLAGS_REG)
572         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
573                     (match_operand:QI 1 "general_operand" "")))]
574   "TARGET_QIMODE_MATH"
575 {
576   if (MEM_P (operands[0]) && MEM_P (operands[1]))
577     operands[0] = force_reg (QImode, operands[0]);
578   ix86_compare_op0 = operands[0];
579   ix86_compare_op1 = operands[1];
580   DONE;
581 })
582
583 (define_insn "cmpdi_ccno_1_rex64"
584   [(set (reg FLAGS_REG)
585         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
586                  (match_operand:DI 1 "const0_operand" "n,n")))]
587   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
588   "@
589    test{q}\t%0, %0
590    cmp{q}\t{%1, %0|%0, %1}"
591   [(set_attr "type" "test,icmp")
592    (set_attr "length_immediate" "0,1")
593    (set_attr "mode" "DI")])
594
595 (define_insn "*cmpdi_minus_1_rex64"
596   [(set (reg FLAGS_REG)
597         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
598                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
599                  (const_int 0)))]
600   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
601   "cmp{q}\t{%1, %0|%0, %1}"
602   [(set_attr "type" "icmp")
603    (set_attr "mode" "DI")])
604
605 (define_expand "cmpdi_1_rex64"
606   [(set (reg:CC FLAGS_REG)
607         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
608                     (match_operand:DI 1 "general_operand" "")))]
609   "TARGET_64BIT"
610   "")
611
612 (define_insn "cmpdi_1_insn_rex64"
613   [(set (reg FLAGS_REG)
614         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
615                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
616   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
617   "cmp{q}\t{%1, %0|%0, %1}"
618   [(set_attr "type" "icmp")
619    (set_attr "mode" "DI")])
620
621
622 (define_insn "*cmpsi_ccno_1"
623   [(set (reg FLAGS_REG)
624         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
625                  (match_operand:SI 1 "const0_operand" "n,n")))]
626   "ix86_match_ccmode (insn, CCNOmode)"
627   "@
628    test{l}\t%0, %0
629    cmp{l}\t{%1, %0|%0, %1}"
630   [(set_attr "type" "test,icmp")
631    (set_attr "length_immediate" "0,1")
632    (set_attr "mode" "SI")])
633
634 (define_insn "*cmpsi_minus_1"
635   [(set (reg FLAGS_REG)
636         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
637                            (match_operand:SI 1 "general_operand" "ri,mr"))
638                  (const_int 0)))]
639   "ix86_match_ccmode (insn, CCGOCmode)"
640   "cmp{l}\t{%1, %0|%0, %1}"
641   [(set_attr "type" "icmp")
642    (set_attr "mode" "SI")])
643
644 (define_expand "cmpsi_1"
645   [(set (reg:CC FLAGS_REG)
646         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
647                     (match_operand:SI 1 "general_operand" "ri,mr")))]
648   ""
649   "")
650
651 (define_insn "*cmpsi_1_insn"
652   [(set (reg FLAGS_REG)
653         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
654                  (match_operand:SI 1 "general_operand" "ri,mr")))]
655   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
656     && ix86_match_ccmode (insn, CCmode)"
657   "cmp{l}\t{%1, %0|%0, %1}"
658   [(set_attr "type" "icmp")
659    (set_attr "mode" "SI")])
660
661 (define_insn "*cmphi_ccno_1"
662   [(set (reg FLAGS_REG)
663         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
664                  (match_operand:HI 1 "const0_operand" "n,n")))]
665   "ix86_match_ccmode (insn, CCNOmode)"
666   "@
667    test{w}\t%0, %0
668    cmp{w}\t{%1, %0|%0, %1}"
669   [(set_attr "type" "test,icmp")
670    (set_attr "length_immediate" "0,1")
671    (set_attr "mode" "HI")])
672
673 (define_insn "*cmphi_minus_1"
674   [(set (reg FLAGS_REG)
675         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
676                            (match_operand:HI 1 "general_operand" "ri,mr"))
677                  (const_int 0)))]
678   "ix86_match_ccmode (insn, CCGOCmode)"
679   "cmp{w}\t{%1, %0|%0, %1}"
680   [(set_attr "type" "icmp")
681    (set_attr "mode" "HI")])
682
683 (define_insn "*cmphi_1"
684   [(set (reg FLAGS_REG)
685         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
686                  (match_operand:HI 1 "general_operand" "ri,mr")))]
687   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
688    && ix86_match_ccmode (insn, CCmode)"
689   "cmp{w}\t{%1, %0|%0, %1}"
690   [(set_attr "type" "icmp")
691    (set_attr "mode" "HI")])
692
693 (define_insn "*cmpqi_ccno_1"
694   [(set (reg FLAGS_REG)
695         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
696                  (match_operand:QI 1 "const0_operand" "n,n")))]
697   "ix86_match_ccmode (insn, CCNOmode)"
698   "@
699    test{b}\t%0, %0
700    cmp{b}\t{$0, %0|%0, 0}"
701   [(set_attr "type" "test,icmp")
702    (set_attr "length_immediate" "0,1")
703    (set_attr "mode" "QI")])
704
705 (define_insn "*cmpqi_1"
706   [(set (reg FLAGS_REG)
707         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
708                  (match_operand:QI 1 "general_operand" "qi,mq")))]
709   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
710     && ix86_match_ccmode (insn, CCmode)"
711   "cmp{b}\t{%1, %0|%0, %1}"
712   [(set_attr "type" "icmp")
713    (set_attr "mode" "QI")])
714
715 (define_insn "*cmpqi_minus_1"
716   [(set (reg FLAGS_REG)
717         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
718                            (match_operand:QI 1 "general_operand" "qi,mq"))
719                  (const_int 0)))]
720   "ix86_match_ccmode (insn, CCGOCmode)"
721   "cmp{b}\t{%1, %0|%0, %1}"
722   [(set_attr "type" "icmp")
723    (set_attr "mode" "QI")])
724
725 (define_insn "*cmpqi_ext_1"
726   [(set (reg FLAGS_REG)
727         (compare
728           (match_operand:QI 0 "general_operand" "Qm")
729           (subreg:QI
730             (zero_extract:SI
731               (match_operand 1 "ext_register_operand" "Q")
732               (const_int 8)
733               (const_int 8)) 0)))]
734   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
735   "cmp{b}\t{%h1, %0|%0, %h1}"
736   [(set_attr "type" "icmp")
737    (set_attr "mode" "QI")])
738
739 (define_insn "*cmpqi_ext_1_rex64"
740   [(set (reg FLAGS_REG)
741         (compare
742           (match_operand:QI 0 "register_operand" "Q")
743           (subreg:QI
744             (zero_extract:SI
745               (match_operand 1 "ext_register_operand" "Q")
746               (const_int 8)
747               (const_int 8)) 0)))]
748   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
749   "cmp{b}\t{%h1, %0|%0, %h1}"
750   [(set_attr "type" "icmp")
751    (set_attr "mode" "QI")])
752
753 (define_insn "*cmpqi_ext_2"
754   [(set (reg FLAGS_REG)
755         (compare
756           (subreg:QI
757             (zero_extract:SI
758               (match_operand 0 "ext_register_operand" "Q")
759               (const_int 8)
760               (const_int 8)) 0)
761           (match_operand:QI 1 "const0_operand" "n")))]
762   "ix86_match_ccmode (insn, CCNOmode)"
763   "test{b}\t%h0, %h0"
764   [(set_attr "type" "test")
765    (set_attr "length_immediate" "0")
766    (set_attr "mode" "QI")])
767
768 (define_expand "cmpqi_ext_3"
769   [(set (reg:CC FLAGS_REG)
770         (compare:CC
771           (subreg:QI
772             (zero_extract:SI
773               (match_operand 0 "ext_register_operand" "")
774               (const_int 8)
775               (const_int 8)) 0)
776           (match_operand:QI 1 "general_operand" "")))]
777   ""
778   "")
779
780 (define_insn "cmpqi_ext_3_insn"
781   [(set (reg FLAGS_REG)
782         (compare
783           (subreg:QI
784             (zero_extract:SI
785               (match_operand 0 "ext_register_operand" "Q")
786               (const_int 8)
787               (const_int 8)) 0)
788           (match_operand:QI 1 "general_operand" "Qmn")))]
789   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
790   "cmp{b}\t{%1, %h0|%h0, %1}"
791   [(set_attr "type" "icmp")
792    (set_attr "mode" "QI")])
793
794 (define_insn "cmpqi_ext_3_insn_rex64"
795   [(set (reg FLAGS_REG)
796         (compare
797           (subreg:QI
798             (zero_extract:SI
799               (match_operand 0 "ext_register_operand" "Q")
800               (const_int 8)
801               (const_int 8)) 0)
802           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
803   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
804   "cmp{b}\t{%1, %h0|%h0, %1}"
805   [(set_attr "type" "icmp")
806    (set_attr "mode" "QI")])
807
808 (define_insn "*cmpqi_ext_4"
809   [(set (reg FLAGS_REG)
810         (compare
811           (subreg:QI
812             (zero_extract:SI
813               (match_operand 0 "ext_register_operand" "Q")
814               (const_int 8)
815               (const_int 8)) 0)
816           (subreg:QI
817             (zero_extract:SI
818               (match_operand 1 "ext_register_operand" "Q")
819               (const_int 8)
820               (const_int 8)) 0)))]
821   "ix86_match_ccmode (insn, CCmode)"
822   "cmp{b}\t{%h1, %h0|%h0, %h1}"
823   [(set_attr "type" "icmp")
824    (set_attr "mode" "QI")])
825
826 ;; These implement float point compares.
827 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
828 ;; which would allow mix and match FP modes on the compares.  Which is what
829 ;; the old patterns did, but with many more of them.
830
831 (define_expand "cmpxf"
832   [(set (reg:CC FLAGS_REG)
833         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
834                     (match_operand:XF 1 "nonmemory_operand" "")))]
835   "TARGET_80387"
836 {
837   ix86_compare_op0 = operands[0];
838   ix86_compare_op1 = operands[1];
839   DONE;
840 })
841
842 (define_expand "cmpdf"
843   [(set (reg:CC FLAGS_REG)
844         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
845                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
846   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
847 {
848   ix86_compare_op0 = operands[0];
849   ix86_compare_op1 = operands[1];
850   DONE;
851 })
852
853 (define_expand "cmpsf"
854   [(set (reg:CC FLAGS_REG)
855         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
856                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
857   "TARGET_80387 || TARGET_SSE_MATH"
858 {
859   ix86_compare_op0 = operands[0];
860   ix86_compare_op1 = operands[1];
861   DONE;
862 })
863
864 ;; FP compares, step 1:
865 ;; Set the FP condition codes.
866 ;;
867 ;; CCFPmode     compare with exceptions
868 ;; CCFPUmode    compare with no exceptions
869
870 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
871 ;; used to manage the reg stack popping would not be preserved.
872
873 (define_insn "*cmpfp_0"
874   [(set (match_operand:HI 0 "register_operand" "=a")
875         (unspec:HI
876           [(compare:CCFP
877              (match_operand 1 "register_operand" "f")
878              (match_operand 2 "const0_operand" "X"))]
879         UNSPEC_FNSTSW))]
880   "TARGET_80387
881    && FLOAT_MODE_P (GET_MODE (operands[1]))
882    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
883   "* return output_fp_compare (insn, operands, 0, 0);"
884   [(set_attr "type" "multi")
885    (set_attr "unit" "i387")
886    (set (attr "mode")
887      (cond [(match_operand:SF 1 "" "")
888               (const_string "SF")
889             (match_operand:DF 1 "" "")
890               (const_string "DF")
891            ]
892            (const_string "XF")))])
893
894 (define_insn "*cmpfp_sf"
895   [(set (match_operand:HI 0 "register_operand" "=a")
896         (unspec:HI
897           [(compare:CCFP
898              (match_operand:SF 1 "register_operand" "f")
899              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
900           UNSPEC_FNSTSW))]
901   "TARGET_80387"
902   "* return output_fp_compare (insn, operands, 0, 0);"
903   [(set_attr "type" "multi")
904    (set_attr "unit" "i387")
905    (set_attr "mode" "SF")])
906
907 (define_insn "*cmpfp_df"
908   [(set (match_operand:HI 0 "register_operand" "=a")
909         (unspec:HI
910           [(compare:CCFP
911              (match_operand:DF 1 "register_operand" "f")
912              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
913           UNSPEC_FNSTSW))]
914   "TARGET_80387"
915   "* return output_fp_compare (insn, operands, 0, 0);"
916   [(set_attr "type" "multi")
917    (set_attr "unit" "i387")
918    (set_attr "mode" "DF")])
919
920 (define_insn "*cmpfp_xf"
921   [(set (match_operand:HI 0 "register_operand" "=a")
922         (unspec:HI
923           [(compare:CCFP
924              (match_operand:XF 1 "register_operand" "f")
925              (match_operand:XF 2 "register_operand" "f"))]
926           UNSPEC_FNSTSW))]
927   "TARGET_80387"
928   "* return output_fp_compare (insn, operands, 0, 0);"
929   [(set_attr "type" "multi")
930    (set_attr "unit" "i387")
931    (set_attr "mode" "XF")])
932
933 (define_insn "*cmpfp_u"
934   [(set (match_operand:HI 0 "register_operand" "=a")
935         (unspec:HI
936           [(compare:CCFPU
937              (match_operand 1 "register_operand" "f")
938              (match_operand 2 "register_operand" "f"))]
939           UNSPEC_FNSTSW))]
940   "TARGET_80387
941    && FLOAT_MODE_P (GET_MODE (operands[1]))
942    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
943   "* return output_fp_compare (insn, operands, 0, 1);"
944   [(set_attr "type" "multi")
945    (set_attr "unit" "i387")
946    (set (attr "mode")
947      (cond [(match_operand:SF 1 "" "")
948               (const_string "SF")
949             (match_operand:DF 1 "" "")
950               (const_string "DF")
951            ]
952            (const_string "XF")))])
953
954 (define_insn "*cmpfp_<mode>"
955   [(set (match_operand:HI 0 "register_operand" "=a")
956         (unspec:HI
957           [(compare:CCFP
958              (match_operand 1 "register_operand" "f")
959              (match_operator 3 "float_operator"
960                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
961           UNSPEC_FNSTSW))]
962   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
963    && FLOAT_MODE_P (GET_MODE (operands[1]))
964    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
965   "* return output_fp_compare (insn, operands, 0, 0);"
966   [(set_attr "type" "multi")
967    (set_attr "unit" "i387")
968    (set_attr "fp_int_src" "true")
969    (set_attr "mode" "<MODE>")])
970
971 ;; FP compares, step 2
972 ;; Move the fpsw to ax.
973
974 (define_insn "x86_fnstsw_1"
975   [(set (match_operand:HI 0 "register_operand" "=a")
976         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
977   "TARGET_80387"
978   "fnstsw\t%0"
979   [(set_attr "length" "2")
980    (set_attr "mode" "SI")
981    (set_attr "unit" "i387")])
982
983 ;; FP compares, step 3
984 ;; Get ax into flags, general case.
985
986 (define_insn "x86_sahf_1"
987   [(set (reg:CC FLAGS_REG)
988         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
989                    UNSPEC_SAHF))]
990   "TARGET_SAHF"
991   "sahf"
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   "TARGET_80387 && TARGET_CMOVE
1036    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1037    && 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   "TARGET_80387 && TARGET_CMOVE
1088    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1089    && 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_PENTIUM || 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_PENTIUM || 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
2185     ix86_expand_vector_move (TImode, operands);
2186   DONE;
2187 })
2188
2189 (define_insn "*movti_internal"
2190   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2191         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2192   "TARGET_SSE && !TARGET_64BIT
2193    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2194 {
2195   switch (which_alternative)
2196     {
2197     case 0:
2198       if (get_attr_mode (insn) == MODE_V4SF)
2199         return "xorps\t%0, %0";
2200       else
2201         return "pxor\t%0, %0";
2202     case 1:
2203     case 2:
2204       if (get_attr_mode (insn) == MODE_V4SF)
2205         return "movaps\t{%1, %0|%0, %1}";
2206       else
2207         return "movdqa\t{%1, %0|%0, %1}";
2208     default:
2209       gcc_unreachable ();
2210     }
2211 }
2212   [(set_attr "type" "sselog1,ssemov,ssemov")
2213    (set (attr "mode")
2214         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2215                     (ne (symbol_ref "optimize_size") (const_int 0)))
2216                  (const_string "V4SF")
2217                (and (eq_attr "alternative" "2")
2218                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2219                         (const_int 0)))
2220                  (const_string "V4SF")]
2221               (const_string "TI")))])
2222
2223 (define_insn "*movti_rex64"
2224   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2225         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2226   "TARGET_64BIT
2227    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2228 {
2229   switch (which_alternative)
2230     {
2231     case 0:
2232     case 1:
2233       return "#";
2234     case 2:
2235       if (get_attr_mode (insn) == MODE_V4SF)
2236         return "xorps\t%0, %0";
2237       else
2238         return "pxor\t%0, %0";
2239     case 3:
2240     case 4:
2241       if (get_attr_mode (insn) == MODE_V4SF)
2242         return "movaps\t{%1, %0|%0, %1}";
2243       else
2244         return "movdqa\t{%1, %0|%0, %1}";
2245     default:
2246       gcc_unreachable ();
2247     }
2248 }
2249   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2250    (set (attr "mode")
2251         (cond [(eq_attr "alternative" "2,3")
2252                  (if_then_else
2253                    (ne (symbol_ref "optimize_size")
2254                        (const_int 0))
2255                    (const_string "V4SF")
2256                    (const_string "TI"))
2257                (eq_attr "alternative" "4")
2258                  (if_then_else
2259                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2260                             (const_int 0))
2261                         (ne (symbol_ref "optimize_size")
2262                             (const_int 0)))
2263                    (const_string "V4SF")
2264                    (const_string "TI"))]
2265                (const_string "DI")))])
2266
2267 (define_split
2268   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2269         (match_operand:TI 1 "general_operand" ""))]
2270   "reload_completed && !SSE_REG_P (operands[0])
2271    && !SSE_REG_P (operands[1])"
2272   [(const_int 0)]
2273   "ix86_split_long_move (operands); DONE;")
2274
2275 ;; This expands to what emit_move_complex would generate if we didn't
2276 ;; have a movti pattern.  Having this avoids problems with reload on
2277 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2278 ;; to have around all the time.
2279 (define_expand "movcdi"
2280   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2281         (match_operand:CDI 1 "general_operand" ""))]
2282   ""
2283 {
2284   if (push_operand (operands[0], CDImode))
2285     emit_move_complex_push (CDImode, operands[0], operands[1]);
2286   else
2287     emit_move_complex_parts (operands[0], operands[1]);
2288   DONE;
2289 })
2290
2291 (define_expand "movsf"
2292   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2293         (match_operand:SF 1 "general_operand" ""))]
2294   ""
2295   "ix86_expand_move (SFmode, operands); DONE;")
2296
2297 (define_insn "*pushsf"
2298   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2299         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2300   "!TARGET_64BIT"
2301 {
2302   /* Anything else should be already split before reg-stack.  */
2303   gcc_assert (which_alternative == 1);
2304   return "push{l}\t%1";
2305 }
2306   [(set_attr "type" "multi,push,multi")
2307    (set_attr "unit" "i387,*,*")
2308    (set_attr "mode" "SF,SI,SF")])
2309
2310 (define_insn "*pushsf_rex64"
2311   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2312         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2313   "TARGET_64BIT"
2314 {
2315   /* Anything else should be already split before reg-stack.  */
2316   gcc_assert (which_alternative == 1);
2317   return "push{q}\t%q1";
2318 }
2319   [(set_attr "type" "multi,push,multi")
2320    (set_attr "unit" "i387,*,*")
2321    (set_attr "mode" "SF,DI,SF")])
2322
2323 (define_split
2324   [(set (match_operand:SF 0 "push_operand" "")
2325         (match_operand:SF 1 "memory_operand" ""))]
2326   "reload_completed
2327    && MEM_P (operands[1])
2328    && constant_pool_reference_p (operands[1])"
2329   [(set (match_dup 0)
2330         (match_dup 1))]
2331   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2332
2333
2334 ;; %%% Kill this when call knows how to work this out.
2335 (define_split
2336   [(set (match_operand:SF 0 "push_operand" "")
2337         (match_operand:SF 1 "any_fp_register_operand" ""))]
2338   "!TARGET_64BIT"
2339   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2340    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2341
2342 (define_split
2343   [(set (match_operand:SF 0 "push_operand" "")
2344         (match_operand:SF 1 "any_fp_register_operand" ""))]
2345   "TARGET_64BIT"
2346   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2347    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2348
2349 (define_insn "*movsf_1"
2350   [(set (match_operand:SF 0 "nonimmediate_operand"
2351           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2352         (match_operand:SF 1 "general_operand"
2353           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2354   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2355    && (reload_in_progress || reload_completed
2356        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2357        || (!TARGET_SSE_MATH && optimize_size
2358            && standard_80387_constant_p (operands[1]))
2359        || GET_CODE (operands[1]) != CONST_DOUBLE
2360        || memory_operand (operands[0], SFmode))"
2361 {
2362   switch (which_alternative)
2363     {
2364     case 0:
2365       return output_387_reg_move (insn, operands);
2366
2367     case 1:
2368       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2369         return "fstp%z0\t%y0";
2370       else
2371         return "fst%z0\t%y0";
2372
2373     case 2:
2374       return standard_80387_constant_opcode (operands[1]);
2375
2376     case 3:
2377     case 4:
2378       return "mov{l}\t{%1, %0|%0, %1}";
2379     case 5:
2380       if (get_attr_mode (insn) == MODE_TI)
2381         return "pxor\t%0, %0";
2382       else
2383         return "xorps\t%0, %0";
2384     case 6:
2385       if (get_attr_mode (insn) == MODE_V4SF)
2386         return "movaps\t{%1, %0|%0, %1}";
2387       else
2388         return "movss\t{%1, %0|%0, %1}";
2389     case 7: case 8:
2390       return "movss\t{%1, %0|%0, %1}";
2391
2392     case 9: case 10:
2393     case 12: case 13: case 14: case 15:
2394       return "movd\t{%1, %0|%0, %1}";
2395
2396     case 11:
2397       return "movq\t{%1, %0|%0, %1}";
2398
2399     default:
2400       gcc_unreachable ();
2401     }
2402 }
2403   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2404    (set (attr "mode")
2405         (cond [(eq_attr "alternative" "3,4,9,10")
2406                  (const_string "SI")
2407                (eq_attr "alternative" "5")
2408                  (if_then_else
2409                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2410                                  (const_int 0))
2411                              (ne (symbol_ref "TARGET_SSE2")
2412                                  (const_int 0)))
2413                         (eq (symbol_ref "optimize_size")
2414                             (const_int 0)))
2415                    (const_string "TI")
2416                    (const_string "V4SF"))
2417                /* For architectures resolving dependencies on
2418                   whole SSE registers use APS move to break dependency
2419                   chains, otherwise use short move to avoid extra work.
2420
2421                   Do the same for architectures resolving dependencies on
2422                   the parts.  While in DF mode it is better to always handle
2423                   just register parts, the SF mode is different due to lack
2424                   of instructions to load just part of the register.  It is
2425                   better to maintain the whole registers in single format
2426                   to avoid problems on using packed logical operations.  */
2427                (eq_attr "alternative" "6")
2428                  (if_then_else
2429                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2430                             (const_int 0))
2431                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2432                             (const_int 0)))
2433                    (const_string "V4SF")
2434                    (const_string "SF"))
2435                (eq_attr "alternative" "11")
2436                  (const_string "DI")]
2437                (const_string "SF")))])
2438
2439 (define_insn "*swapsf"
2440   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2441         (match_operand:SF 1 "fp_register_operand" "+f"))
2442    (set (match_dup 1)
2443         (match_dup 0))]
2444   "reload_completed || TARGET_80387"
2445 {
2446   if (STACK_TOP_P (operands[0]))
2447     return "fxch\t%1";
2448   else
2449     return "fxch\t%0";
2450 }
2451   [(set_attr "type" "fxch")
2452    (set_attr "mode" "SF")])
2453
2454 (define_expand "movdf"
2455   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2456         (match_operand:DF 1 "general_operand" ""))]
2457   ""
2458   "ix86_expand_move (DFmode, operands); DONE;")
2459
2460 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2461 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2462 ;; On the average, pushdf using integers can be still shorter.  Allow this
2463 ;; pattern for optimize_size too.
2464
2465 (define_insn "*pushdf_nointeger"
2466   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2467         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2468   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2469 {
2470   /* This insn should be already split before reg-stack.  */
2471   gcc_unreachable ();
2472 }
2473   [(set_attr "type" "multi")
2474    (set_attr "unit" "i387,*,*,*")
2475    (set_attr "mode" "DF,SI,SI,DF")])
2476
2477 (define_insn "*pushdf_integer"
2478   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2479         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2480   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2481 {
2482   /* This insn should be already split before reg-stack.  */
2483   gcc_unreachable ();
2484 }
2485   [(set_attr "type" "multi")
2486    (set_attr "unit" "i387,*,*")
2487    (set_attr "mode" "DF,SI,DF")])
2488
2489 ;; %%% Kill this when call knows how to work this out.
2490 (define_split
2491   [(set (match_operand:DF 0 "push_operand" "")
2492         (match_operand:DF 1 "any_fp_register_operand" ""))]
2493   "!TARGET_64BIT && reload_completed"
2494   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2495    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2496   "")
2497
2498 (define_split
2499   [(set (match_operand:DF 0 "push_operand" "")
2500         (match_operand:DF 1 "any_fp_register_operand" ""))]
2501   "TARGET_64BIT && reload_completed"
2502   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2503    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2504   "")
2505
2506 (define_split
2507   [(set (match_operand:DF 0 "push_operand" "")
2508         (match_operand:DF 1 "general_operand" ""))]
2509   "reload_completed"
2510   [(const_int 0)]
2511   "ix86_split_long_move (operands); DONE;")
2512
2513 ;; Moving is usually shorter when only FP registers are used. This separate
2514 ;; movdf pattern avoids the use of integer registers for FP operations
2515 ;; when optimizing for size.
2516
2517 (define_insn "*movdf_nointeger"
2518   [(set (match_operand:DF 0 "nonimmediate_operand"
2519                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2520         (match_operand:DF 1 "general_operand"
2521                         "fm,f,G,*roF,F*r,C   ,Y2*x,mY2*x,Y2*x"))]
2522   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2523    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2524    && (reload_in_progress || reload_completed
2525        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2526        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2527            && standard_80387_constant_p (operands[1]))
2528        || GET_CODE (operands[1]) != CONST_DOUBLE
2529        || memory_operand (operands[0], DFmode))"
2530 {
2531   switch (which_alternative)
2532     {
2533     case 0:
2534       return output_387_reg_move (insn, operands);
2535
2536     case 1:
2537       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2538         return "fstp%z0\t%y0";
2539       else
2540         return "fst%z0\t%y0";
2541
2542     case 2:
2543       return standard_80387_constant_opcode (operands[1]);
2544
2545     case 3:
2546     case 4:
2547       return "#";
2548     case 5:
2549       switch (get_attr_mode (insn))
2550         {
2551         case MODE_V4SF:
2552           return "xorps\t%0, %0";
2553         case MODE_V2DF:
2554           return "xorpd\t%0, %0";
2555         case MODE_TI:
2556           return "pxor\t%0, %0";
2557         default:
2558           gcc_unreachable ();
2559         }
2560     case 6:
2561     case 7:
2562     case 8:
2563       switch (get_attr_mode (insn))
2564         {
2565         case MODE_V4SF:
2566           return "movaps\t{%1, %0|%0, %1}";
2567         case MODE_V2DF:
2568           return "movapd\t{%1, %0|%0, %1}";
2569         case MODE_TI:
2570           return "movdqa\t{%1, %0|%0, %1}";
2571         case MODE_DI:
2572           return "movq\t{%1, %0|%0, %1}";
2573         case MODE_DF:
2574           return "movsd\t{%1, %0|%0, %1}";
2575         case MODE_V1DF:
2576           return "movlpd\t{%1, %0|%0, %1}";
2577         case MODE_V2SF:
2578           return "movlps\t{%1, %0|%0, %1}";
2579         default:
2580           gcc_unreachable ();
2581         }
2582
2583     default:
2584       gcc_unreachable ();
2585     }
2586 }
2587   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2588    (set (attr "mode")
2589         (cond [(eq_attr "alternative" "0,1,2")
2590                  (const_string "DF")
2591                (eq_attr "alternative" "3,4")
2592                  (const_string "SI")
2593
2594                /* For SSE1, we have many fewer alternatives.  */
2595                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2596                  (cond [(eq_attr "alternative" "5,6")
2597                           (const_string "V4SF")
2598                        ]
2599                    (const_string "V2SF"))
2600
2601                /* xorps is one byte shorter.  */
2602                (eq_attr "alternative" "5")
2603                  (cond [(ne (symbol_ref "optimize_size")
2604                             (const_int 0))
2605                           (const_string "V4SF")
2606                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2607                             (const_int 0))
2608                           (const_string "TI")
2609                        ]
2610                        (const_string "V2DF"))
2611
2612                /* For architectures resolving dependencies on
2613                   whole SSE registers use APD move to break dependency
2614                   chains, otherwise use short move to avoid extra work.
2615
2616                   movaps encodes one byte shorter.  */
2617                (eq_attr "alternative" "6")
2618                  (cond
2619                    [(ne (symbol_ref "optimize_size")
2620                         (const_int 0))
2621                       (const_string "V4SF")
2622                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2623                         (const_int 0))
2624                       (const_string "V2DF")
2625                    ]
2626                    (const_string "DF"))
2627                /* For architectures resolving dependencies on register
2628                   parts we may avoid extra work to zero out upper part
2629                   of register.  */
2630                (eq_attr "alternative" "7")
2631                  (if_then_else
2632                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2633                        (const_int 0))
2634                    (const_string "V1DF")
2635                    (const_string "DF"))
2636               ]
2637               (const_string "DF")))])
2638
2639 (define_insn "*movdf_integer_rex64"
2640   [(set (match_operand:DF 0 "nonimmediate_operand"
2641                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2642         (match_operand:DF 1 "general_operand"
2643                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2644   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2645    && (reload_in_progress || reload_completed
2646        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2647        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2648            && standard_80387_constant_p (operands[1]))
2649        || GET_CODE (operands[1]) != CONST_DOUBLE
2650        || memory_operand (operands[0], DFmode))"
2651 {
2652   switch (which_alternative)
2653     {
2654     case 0:
2655       return output_387_reg_move (insn, operands);
2656
2657     case 1:
2658       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2659         return "fstp%z0\t%y0";
2660       else
2661         return "fst%z0\t%y0";
2662
2663     case 2:
2664       return standard_80387_constant_opcode (operands[1]);
2665
2666     case 3:
2667     case 4:
2668       return "#";
2669
2670     case 5:
2671       switch (get_attr_mode (insn))
2672         {
2673         case MODE_V4SF:
2674           return "xorps\t%0, %0";
2675         case MODE_V2DF:
2676           return "xorpd\t%0, %0";
2677         case MODE_TI:
2678           return "pxor\t%0, %0";
2679         default:
2680           gcc_unreachable ();
2681         }
2682     case 6:
2683     case 7:
2684     case 8:
2685       switch (get_attr_mode (insn))
2686         {
2687         case MODE_V4SF:
2688           return "movaps\t{%1, %0|%0, %1}";
2689         case MODE_V2DF:
2690           return "movapd\t{%1, %0|%0, %1}";
2691         case MODE_TI:
2692           return "movdqa\t{%1, %0|%0, %1}";
2693         case MODE_DI:
2694           return "movq\t{%1, %0|%0, %1}";
2695         case MODE_DF:
2696           return "movsd\t{%1, %0|%0, %1}";
2697         case MODE_V1DF:
2698           return "movlpd\t{%1, %0|%0, %1}";
2699         case MODE_V2SF:
2700           return "movlps\t{%1, %0|%0, %1}";
2701         default:
2702           gcc_unreachable ();
2703         }
2704
2705     case 9:
2706     case 10:
2707       return "movd\t{%1, %0|%0, %1}";
2708
2709     default:
2710       gcc_unreachable();
2711     }
2712 }
2713   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2714    (set (attr "mode")
2715         (cond [(eq_attr "alternative" "0,1,2")
2716                  (const_string "DF")
2717                (eq_attr "alternative" "3,4,9,10")
2718                  (const_string "DI")
2719
2720                /* For SSE1, we have many fewer alternatives.  */
2721                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2722                  (cond [(eq_attr "alternative" "5,6")
2723                           (const_string "V4SF")
2724                        ]
2725                    (const_string "V2SF"))
2726
2727                /* xorps is one byte shorter.  */
2728                (eq_attr "alternative" "5")
2729                  (cond [(ne (symbol_ref "optimize_size")
2730                             (const_int 0))
2731                           (const_string "V4SF")
2732                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2733                             (const_int 0))
2734                           (const_string "TI")
2735                        ]
2736                        (const_string "V2DF"))
2737
2738                /* For architectures resolving dependencies on
2739                   whole SSE registers use APD move to break dependency
2740                   chains, otherwise use short move to avoid extra work.
2741
2742                   movaps encodes one byte shorter.  */
2743                (eq_attr "alternative" "6")
2744                  (cond
2745                    [(ne (symbol_ref "optimize_size")
2746                         (const_int 0))
2747                       (const_string "V4SF")
2748                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2749                         (const_int 0))
2750                       (const_string "V2DF")
2751                    ]
2752                    (const_string "DF"))
2753                /* For architectures resolving dependencies on register
2754                   parts we may avoid extra work to zero out upper part
2755                   of register.  */
2756                (eq_attr "alternative" "7")
2757                  (if_then_else
2758                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2759                        (const_int 0))
2760                    (const_string "V1DF")
2761                    (const_string "DF"))
2762               ]
2763               (const_string "DF")))])
2764
2765 (define_insn "*movdf_integer"
2766   [(set (match_operand:DF 0 "nonimmediate_operand"
2767                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
2768         (match_operand:DF 1 "general_operand"
2769                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
2770   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2771    && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2772    && (reload_in_progress || reload_completed
2773        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2774        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2775            && standard_80387_constant_p (operands[1]))
2776        || GET_CODE (operands[1]) != CONST_DOUBLE
2777        || memory_operand (operands[0], DFmode))"
2778 {
2779   switch (which_alternative)
2780     {
2781     case 0:
2782       return output_387_reg_move (insn, operands);
2783
2784     case 1:
2785       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2786         return "fstp%z0\t%y0";
2787       else
2788         return "fst%z0\t%y0";
2789
2790     case 2:
2791       return standard_80387_constant_opcode (operands[1]);
2792
2793     case 3:
2794     case 4:
2795       return "#";
2796
2797     case 5:
2798       switch (get_attr_mode (insn))
2799         {
2800         case MODE_V4SF:
2801           return "xorps\t%0, %0";
2802         case MODE_V2DF:
2803           return "xorpd\t%0, %0";
2804         case MODE_TI:
2805           return "pxor\t%0, %0";
2806         default:
2807           gcc_unreachable ();
2808         }
2809     case 6:
2810     case 7:
2811     case 8:
2812       switch (get_attr_mode (insn))
2813         {
2814         case MODE_V4SF:
2815           return "movaps\t{%1, %0|%0, %1}";
2816         case MODE_V2DF:
2817           return "movapd\t{%1, %0|%0, %1}";
2818         case MODE_TI:
2819           return "movdqa\t{%1, %0|%0, %1}";
2820         case MODE_DI:
2821           return "movq\t{%1, %0|%0, %1}";
2822         case MODE_DF:
2823           return "movsd\t{%1, %0|%0, %1}";
2824         case MODE_V1DF:
2825           return "movlpd\t{%1, %0|%0, %1}";
2826         case MODE_V2SF:
2827           return "movlps\t{%1, %0|%0, %1}";
2828         default:
2829           gcc_unreachable ();
2830         }
2831
2832     default:
2833       gcc_unreachable();
2834     }
2835 }
2836   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2837    (set (attr "mode")
2838         (cond [(eq_attr "alternative" "0,1,2")
2839                  (const_string "DF")
2840                (eq_attr "alternative" "3,4")
2841                  (const_string "SI")
2842
2843                /* For SSE1, we have many fewer alternatives.  */
2844                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2845                  (cond [(eq_attr "alternative" "5,6")
2846                           (const_string "V4SF")
2847                        ]
2848                    (const_string "V2SF"))
2849
2850                /* xorps is one byte shorter.  */
2851                (eq_attr "alternative" "5")
2852                  (cond [(ne (symbol_ref "optimize_size")
2853                             (const_int 0))
2854                           (const_string "V4SF")
2855                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2856                             (const_int 0))
2857                           (const_string "TI")
2858                        ]
2859                        (const_string "V2DF"))
2860
2861                /* For architectures resolving dependencies on
2862                   whole SSE registers use APD move to break dependency
2863                   chains, otherwise use short move to avoid extra work.
2864
2865                   movaps encodes one byte shorter.  */
2866                (eq_attr "alternative" "6")
2867                  (cond
2868                    [(ne (symbol_ref "optimize_size")
2869                         (const_int 0))
2870                       (const_string "V4SF")
2871                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2872                         (const_int 0))
2873                       (const_string "V2DF")
2874                    ]
2875                    (const_string "DF"))
2876                /* For architectures resolving dependencies on register
2877                   parts we may avoid extra work to zero out upper part
2878                   of register.  */
2879                (eq_attr "alternative" "7")
2880                  (if_then_else
2881                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2882                        (const_int 0))
2883                    (const_string "V1DF")
2884                    (const_string "DF"))
2885               ]
2886               (const_string "DF")))])
2887
2888 (define_split
2889   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2890         (match_operand:DF 1 "general_operand" ""))]
2891   "reload_completed
2892    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2893    && ! (ANY_FP_REG_P (operands[0]) ||
2894          (GET_CODE (operands[0]) == SUBREG
2895           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2896    && ! (ANY_FP_REG_P (operands[1]) ||
2897          (GET_CODE (operands[1]) == SUBREG
2898           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2899   [(const_int 0)]
2900   "ix86_split_long_move (operands); DONE;")
2901
2902 (define_insn "*swapdf"
2903   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2904         (match_operand:DF 1 "fp_register_operand" "+f"))
2905    (set (match_dup 1)
2906         (match_dup 0))]
2907   "reload_completed || TARGET_80387"
2908 {
2909   if (STACK_TOP_P (operands[0]))
2910     return "fxch\t%1";
2911   else
2912     return "fxch\t%0";
2913 }
2914   [(set_attr "type" "fxch")
2915    (set_attr "mode" "DF")])
2916
2917 (define_expand "movxf"
2918   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2919         (match_operand:XF 1 "general_operand" ""))]
2920   ""
2921   "ix86_expand_move (XFmode, operands); DONE;")
2922
2923 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2924 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2925 ;; Pushing using integer instructions is longer except for constants
2926 ;; and direct memory references.
2927 ;; (assuming that any given constant is pushed only once, but this ought to be
2928 ;;  handled elsewhere).
2929
2930 (define_insn "*pushxf_nointeger"
2931   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2932         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2933   "optimize_size"
2934 {
2935   /* This insn should be already split before reg-stack.  */
2936   gcc_unreachable ();
2937 }
2938   [(set_attr "type" "multi")
2939    (set_attr "unit" "i387,*,*")
2940    (set_attr "mode" "XF,SI,SI")])
2941
2942 (define_insn "*pushxf_integer"
2943   [(set (match_operand:XF 0 "push_operand" "=<,<")
2944         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2945   "!optimize_size"
2946 {
2947   /* This insn should be already split before reg-stack.  */
2948   gcc_unreachable ();
2949 }
2950   [(set_attr "type" "multi")
2951    (set_attr "unit" "i387,*")
2952    (set_attr "mode" "XF,SI")])
2953
2954 (define_split
2955   [(set (match_operand 0 "push_operand" "")
2956         (match_operand 1 "general_operand" ""))]
2957   "reload_completed
2958    && (GET_MODE (operands[0]) == XFmode
2959        || GET_MODE (operands[0]) == DFmode)
2960    && !ANY_FP_REG_P (operands[1])"
2961   [(const_int 0)]
2962   "ix86_split_long_move (operands); DONE;")
2963
2964 (define_split
2965   [(set (match_operand:XF 0 "push_operand" "")
2966         (match_operand:XF 1 "any_fp_register_operand" ""))]
2967   "!TARGET_64BIT"
2968   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2969    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2970   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2971
2972 (define_split
2973   [(set (match_operand:XF 0 "push_operand" "")
2974         (match_operand:XF 1 "any_fp_register_operand" ""))]
2975   "TARGET_64BIT"
2976   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2977    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2978   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2979
2980 ;; Do not use integer registers when optimizing for size
2981 (define_insn "*movxf_nointeger"
2982   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2983         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2984   "optimize_size
2985    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2986    && (reload_in_progress || reload_completed
2987        || (optimize_size && standard_80387_constant_p (operands[1]))
2988        || GET_CODE (operands[1]) != CONST_DOUBLE
2989        || memory_operand (operands[0], XFmode))"
2990 {
2991   switch (which_alternative)
2992     {
2993     case 0:
2994       return output_387_reg_move (insn, operands);
2995
2996     case 1:
2997       /* There is no non-popping store to memory for XFmode.  So if
2998          we need one, follow the store with a load.  */
2999       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3000         return "fstp%z0\t%y0\;fld%z0\t%y0";
3001       else
3002         return "fstp%z0\t%y0";
3003
3004     case 2:
3005       return standard_80387_constant_opcode (operands[1]);
3006
3007     case 3: case 4:
3008       return "#";
3009     default:
3010       gcc_unreachable ();
3011     }
3012 }
3013   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3014    (set_attr "mode" "XF,XF,XF,SI,SI")])
3015
3016 (define_insn "*movxf_integer"
3017   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3018         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3019   "!optimize_size
3020    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3021    && (reload_in_progress || reload_completed
3022        || (optimize_size && standard_80387_constant_p (operands[1]))
3023        || GET_CODE (operands[1]) != CONST_DOUBLE
3024        || memory_operand (operands[0], XFmode))"
3025 {
3026   switch (which_alternative)
3027     {
3028     case 0:
3029       return output_387_reg_move (insn, operands);
3030
3031     case 1:
3032       /* There is no non-popping store to memory for XFmode.  So if
3033          we need one, follow the store with a load.  */
3034       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3035         return "fstp%z0\t%y0\;fld%z0\t%y0";
3036       else
3037         return "fstp%z0\t%y0";
3038
3039     case 2:
3040       return standard_80387_constant_opcode (operands[1]);
3041
3042     case 3: case 4:
3043       return "#";
3044
3045     default:
3046       gcc_unreachable ();
3047     }
3048 }
3049   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3050    (set_attr "mode" "XF,XF,XF,SI,SI")])
3051
3052 (define_split
3053   [(set (match_operand 0 "nonimmediate_operand" "")
3054         (match_operand 1 "general_operand" ""))]
3055   "reload_completed
3056    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3057    && GET_MODE (operands[0]) == XFmode
3058    && ! (ANY_FP_REG_P (operands[0]) ||
3059          (GET_CODE (operands[0]) == SUBREG
3060           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3061    && ! (ANY_FP_REG_P (operands[1]) ||
3062          (GET_CODE (operands[1]) == SUBREG
3063           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3064   [(const_int 0)]
3065   "ix86_split_long_move (operands); DONE;")
3066
3067 (define_split
3068   [(set (match_operand 0 "register_operand" "")
3069         (match_operand 1 "memory_operand" ""))]
3070   "reload_completed
3071    && MEM_P (operands[1])
3072    && (GET_MODE (operands[0]) == XFmode
3073        || GET_MODE (operands[0]) == SFmode
3074        || GET_MODE (operands[0]) == DFmode)
3075    && constant_pool_reference_p (operands[1])"
3076   [(set (match_dup 0) (match_dup 1))]
3077 {
3078   rtx c = avoid_constant_pool_reference (operands[1]);
3079   rtx r = operands[0];
3080
3081   if (GET_CODE (r) == SUBREG)
3082     r = SUBREG_REG (r);
3083
3084   if (SSE_REG_P (r))
3085     {
3086       if (!standard_sse_constant_p (c))
3087         FAIL;
3088     }
3089   else if (FP_REG_P (r))
3090     {
3091       if (!standard_80387_constant_p (c))
3092         FAIL;
3093     }
3094   else if (MMX_REG_P (r))
3095     FAIL;
3096
3097   operands[1] = c;
3098 })
3099
3100 (define_split
3101   [(set (match_operand 0 "register_operand" "")
3102         (float_extend (match_operand 1 "memory_operand" "")))]
3103   "reload_completed
3104    && MEM_P (operands[1])
3105    && (GET_MODE (operands[0]) == XFmode
3106        || GET_MODE (operands[0]) == SFmode
3107        || GET_MODE (operands[0]) == DFmode)
3108    && constant_pool_reference_p (operands[1])"
3109   [(set (match_dup 0) (match_dup 1))]
3110 {
3111   rtx c = avoid_constant_pool_reference (SET_SRC (PATTERN (curr_insn)));
3112   rtx r = operands[0];
3113
3114   if (GET_CODE (r) == SUBREG)
3115     r = SUBREG_REG (r);
3116
3117   if (SSE_REG_P (r))
3118     {
3119       if (!standard_sse_constant_p (c))
3120         FAIL;
3121     }
3122   else if (FP_REG_P (r))
3123     {
3124       if (!standard_80387_constant_p (c))
3125         FAIL;
3126     }
3127   else if (MMX_REG_P (r))
3128     FAIL;
3129
3130   operands[1] = c;
3131 })
3132
3133 (define_insn "swapxf"
3134   [(set (match_operand:XF 0 "register_operand" "+f")
3135         (match_operand:XF 1 "register_operand" "+f"))
3136    (set (match_dup 1)
3137         (match_dup 0))]
3138   "TARGET_80387"
3139 {
3140   if (STACK_TOP_P (operands[0]))
3141     return "fxch\t%1";
3142   else
3143     return "fxch\t%0";
3144 }
3145   [(set_attr "type" "fxch")
3146    (set_attr "mode" "XF")])
3147
3148 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3149 (define_split
3150   [(set (match_operand:X87MODEF 0 "register_operand" "")
3151         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3152   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3153    && (standard_80387_constant_p (operands[1]) == 8
3154        || standard_80387_constant_p (operands[1]) == 9)"
3155   [(set (match_dup 0)(match_dup 1))
3156    (set (match_dup 0)
3157         (neg:X87MODEF (match_dup 0)))]
3158 {
3159   REAL_VALUE_TYPE r;
3160
3161   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3162   if (real_isnegzero (&r))
3163     operands[1] = CONST0_RTX (<MODE>mode);
3164   else
3165     operands[1] = CONST1_RTX (<MODE>mode);
3166 })
3167
3168 (define_expand "movtf"
3169   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3170         (match_operand:TF 1 "nonimmediate_operand" ""))]
3171   "TARGET_64BIT"
3172 {
3173   ix86_expand_move (TFmode, operands);
3174   DONE;
3175 })
3176
3177 (define_insn "*movtf_internal"
3178   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3179         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3180   "TARGET_64BIT
3181    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3182 {
3183   switch (which_alternative)
3184     {
3185     case 0:
3186     case 1:
3187       return "#";
3188     case 2:
3189       if (get_attr_mode (insn) == MODE_V4SF)
3190         return "xorps\t%0, %0";
3191       else
3192         return "pxor\t%0, %0";
3193     case 3:
3194     case 4:
3195       if (get_attr_mode (insn) == MODE_V4SF)
3196         return "movaps\t{%1, %0|%0, %1}";
3197       else
3198         return "movdqa\t{%1, %0|%0, %1}";
3199     default:
3200       gcc_unreachable ();
3201     }
3202 }
3203   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3204    (set (attr "mode")
3205         (cond [(eq_attr "alternative" "2,3")
3206                  (if_then_else
3207                    (ne (symbol_ref "optimize_size")
3208                        (const_int 0))
3209                    (const_string "V4SF")
3210                    (const_string "TI"))
3211                (eq_attr "alternative" "4")
3212                  (if_then_else
3213                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3214                             (const_int 0))
3215                         (ne (symbol_ref "optimize_size")
3216                             (const_int 0)))
3217                    (const_string "V4SF")
3218                    (const_string "TI"))]
3219                (const_string "DI")))])
3220
3221 (define_split
3222   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3223         (match_operand:TF 1 "general_operand" ""))]
3224   "reload_completed && !SSE_REG_P (operands[0])
3225    && !SSE_REG_P (operands[1])"
3226   [(const_int 0)]
3227   "ix86_split_long_move (operands); DONE;")
3228 \f
3229 ;; Zero extension instructions
3230
3231 (define_expand "zero_extendhisi2"
3232   [(set (match_operand:SI 0 "register_operand" "")
3233      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3234   ""
3235 {
3236   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3237     {
3238       operands[1] = force_reg (HImode, operands[1]);
3239       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3240       DONE;
3241     }
3242 })
3243
3244 (define_insn "zero_extendhisi2_and"
3245   [(set (match_operand:SI 0 "register_operand" "=r")
3246      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3247    (clobber (reg:CC FLAGS_REG))]
3248   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3249   "#"
3250   [(set_attr "type" "alu1")
3251    (set_attr "mode" "SI")])
3252
3253 (define_split
3254   [(set (match_operand:SI 0 "register_operand" "")
3255         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3256    (clobber (reg:CC FLAGS_REG))]
3257   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3258   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3259               (clobber (reg:CC FLAGS_REG))])]
3260   "")
3261
3262 (define_insn "*zero_extendhisi2_movzwl"
3263   [(set (match_operand:SI 0 "register_operand" "=r")
3264      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3265   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3266   "movz{wl|x}\t{%1, %0|%0, %1}"
3267   [(set_attr "type" "imovx")
3268    (set_attr "mode" "SI")])
3269
3270 (define_expand "zero_extendqihi2"
3271   [(parallel
3272     [(set (match_operand:HI 0 "register_operand" "")
3273        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3274      (clobber (reg:CC FLAGS_REG))])]
3275   ""
3276   "")
3277
3278 (define_insn "*zero_extendqihi2_and"
3279   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3280      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3281    (clobber (reg:CC FLAGS_REG))]
3282   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3283   "#"
3284   [(set_attr "type" "alu1")
3285    (set_attr "mode" "HI")])
3286
3287 (define_insn "*zero_extendqihi2_movzbw_and"
3288   [(set (match_operand:HI 0 "register_operand" "=r,r")
3289      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3290    (clobber (reg:CC FLAGS_REG))]
3291   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3292   "#"
3293   [(set_attr "type" "imovx,alu1")
3294    (set_attr "mode" "HI")])
3295
3296 ; zero extend to SImode here to avoid partial register stalls
3297 (define_insn "*zero_extendqihi2_movzbl"
3298   [(set (match_operand:HI 0 "register_operand" "=r")
3299      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3300   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3301   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3302   [(set_attr "type" "imovx")
3303    (set_attr "mode" "SI")])
3304
3305 ;; For the movzbw case strip only the clobber
3306 (define_split
3307   [(set (match_operand:HI 0 "register_operand" "")
3308         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3309    (clobber (reg:CC FLAGS_REG))]
3310   "reload_completed
3311    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3312    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3313   [(set (match_operand:HI 0 "register_operand" "")
3314         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3315
3316 ;; When source and destination does not overlap, clear destination
3317 ;; first and then do the movb
3318 (define_split
3319   [(set (match_operand:HI 0 "register_operand" "")
3320         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3321    (clobber (reg:CC FLAGS_REG))]
3322   "reload_completed
3323    && ANY_QI_REG_P (operands[0])
3324    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3325    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3326   [(set (match_dup 0) (const_int 0))
3327    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3328   "operands[2] = gen_lowpart (QImode, operands[0]);")
3329
3330 ;; Rest is handled by single and.
3331 (define_split
3332   [(set (match_operand:HI 0 "register_operand" "")
3333         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3334    (clobber (reg:CC FLAGS_REG))]
3335   "reload_completed
3336    && true_regnum (operands[0]) == true_regnum (operands[1])"
3337   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3338               (clobber (reg:CC FLAGS_REG))])]
3339   "")
3340
3341 (define_expand "zero_extendqisi2"
3342   [(parallel
3343     [(set (match_operand:SI 0 "register_operand" "")
3344        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3345      (clobber (reg:CC FLAGS_REG))])]
3346   ""
3347   "")
3348
3349 (define_insn "*zero_extendqisi2_and"
3350   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3351      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3352    (clobber (reg:CC FLAGS_REG))]
3353   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3354   "#"
3355   [(set_attr "type" "alu1")
3356    (set_attr "mode" "SI")])
3357
3358 (define_insn "*zero_extendqisi2_movzbw_and"
3359   [(set (match_operand:SI 0 "register_operand" "=r,r")
3360      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3361    (clobber (reg:CC FLAGS_REG))]
3362   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3363   "#"
3364   [(set_attr "type" "imovx,alu1")
3365    (set_attr "mode" "SI")])
3366
3367 (define_insn "*zero_extendqisi2_movzbw"
3368   [(set (match_operand:SI 0 "register_operand" "=r")
3369      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3370   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3371   "movz{bl|x}\t{%1, %0|%0, %1}"
3372   [(set_attr "type" "imovx")
3373    (set_attr "mode" "SI")])
3374
3375 ;; For the movzbl case strip only the clobber
3376 (define_split
3377   [(set (match_operand:SI 0 "register_operand" "")
3378         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3379    (clobber (reg:CC FLAGS_REG))]
3380   "reload_completed
3381    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3382    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3383   [(set (match_dup 0)
3384         (zero_extend:SI (match_dup 1)))])
3385
3386 ;; When source and destination does not overlap, clear destination
3387 ;; first and then do the movb
3388 (define_split
3389   [(set (match_operand:SI 0 "register_operand" "")
3390         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3391    (clobber (reg:CC FLAGS_REG))]
3392   "reload_completed
3393    && ANY_QI_REG_P (operands[0])
3394    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3395    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3396    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3397   [(set (match_dup 0) (const_int 0))
3398    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3399   "operands[2] = gen_lowpart (QImode, operands[0]);")
3400
3401 ;; Rest is handled by single and.
3402 (define_split
3403   [(set (match_operand:SI 0 "register_operand" "")
3404         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3405    (clobber (reg:CC FLAGS_REG))]
3406   "reload_completed
3407    && true_regnum (operands[0]) == true_regnum (operands[1])"
3408   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3409               (clobber (reg:CC FLAGS_REG))])]
3410   "")
3411
3412 ;; %%% Kill me once multi-word ops are sane.
3413 (define_expand "zero_extendsidi2"
3414   [(set (match_operand:DI 0 "register_operand" "=r")
3415      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3416   ""
3417 {
3418   if (!TARGET_64BIT)
3419     {
3420       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3421       DONE;
3422     }
3423 })
3424
3425 (define_insn "zero_extendsidi2_32"
3426   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3427         (zero_extend:DI
3428          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3429    (clobber (reg:CC FLAGS_REG))]
3430   "!TARGET_64BIT"
3431   "@
3432    #
3433    #
3434    #
3435    movd\t{%1, %0|%0, %1}
3436    movd\t{%1, %0|%0, %1}
3437    movd\t{%1, %0|%0, %1}
3438    movd\t{%1, %0|%0, %1}"
3439   [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3440    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3441
3442 (define_insn "zero_extendsidi2_rex64"
3443   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3444      (zero_extend:DI
3445        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3446   "TARGET_64BIT"
3447   "@
3448    mov\t{%k1, %k0|%k0, %k1}
3449    #
3450    movd\t{%1, %0|%0, %1}
3451    movd\t{%1, %0|%0, %1}
3452    movd\t{%1, %0|%0, %1}
3453    movd\t{%1, %0|%0, %1}"
3454   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3455    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3456
3457 (define_split
3458   [(set (match_operand:DI 0 "memory_operand" "")
3459      (zero_extend:DI (match_dup 0)))]
3460   "TARGET_64BIT"
3461   [(set (match_dup 4) (const_int 0))]
3462   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3463
3464 (define_split
3465   [(set (match_operand:DI 0 "register_operand" "")
3466         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3467    (clobber (reg:CC FLAGS_REG))]
3468   "!TARGET_64BIT && reload_completed
3469    && true_regnum (operands[0]) == true_regnum (operands[1])"
3470   [(set (match_dup 4) (const_int 0))]
3471   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3472
3473 (define_split
3474   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3475         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3476    (clobber (reg:CC FLAGS_REG))]
3477   "!TARGET_64BIT && reload_completed
3478    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3479   [(set (match_dup 3) (match_dup 1))
3480    (set (match_dup 4) (const_int 0))]
3481   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3482
3483 (define_insn "zero_extendhidi2"
3484   [(set (match_operand:DI 0 "register_operand" "=r")
3485      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3486   "TARGET_64BIT"
3487   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3488   [(set_attr "type" "imovx")
3489    (set_attr "mode" "DI")])
3490
3491 (define_insn "zero_extendqidi2"
3492   [(set (match_operand:DI 0 "register_operand" "=r")
3493      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3494   "TARGET_64BIT"
3495   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3496   [(set_attr "type" "imovx")
3497    (set_attr "mode" "DI")])
3498 \f
3499 ;; Sign extension instructions
3500
3501 (define_expand "extendsidi2"
3502   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3503                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3504               (clobber (reg:CC FLAGS_REG))
3505               (clobber (match_scratch:SI 2 ""))])]
3506   ""
3507 {
3508   if (TARGET_64BIT)
3509     {
3510       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3511       DONE;
3512     }
3513 })
3514
3515 (define_insn "*extendsidi2_1"
3516   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3517         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3518    (clobber (reg:CC FLAGS_REG))
3519    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3520   "!TARGET_64BIT"
3521   "#")
3522
3523 (define_insn "extendsidi2_rex64"
3524   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3525         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3526   "TARGET_64BIT"
3527   "@
3528    {cltq|cdqe}
3529    movs{lq|x}\t{%1,%0|%0, %1}"
3530   [(set_attr "type" "imovx")
3531    (set_attr "mode" "DI")
3532    (set_attr "prefix_0f" "0")
3533    (set_attr "modrm" "0,1")])
3534
3535 (define_insn "extendhidi2"
3536   [(set (match_operand:DI 0 "register_operand" "=r")
3537         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3538   "TARGET_64BIT"
3539   "movs{wq|x}\t{%1,%0|%0, %1}"
3540   [(set_attr "type" "imovx")
3541    (set_attr "mode" "DI")])
3542
3543 (define_insn "extendqidi2"
3544   [(set (match_operand:DI 0 "register_operand" "=r")
3545         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3546   "TARGET_64BIT"
3547   "movs{bq|x}\t{%1,%0|%0, %1}"
3548    [(set_attr "type" "imovx")
3549     (set_attr "mode" "DI")])
3550
3551 ;; Extend to memory case when source register does die.
3552 (define_split
3553   [(set (match_operand:DI 0 "memory_operand" "")
3554         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3555    (clobber (reg:CC FLAGS_REG))
3556    (clobber (match_operand:SI 2 "register_operand" ""))]
3557   "(reload_completed
3558     && dead_or_set_p (insn, operands[1])
3559     && !reg_mentioned_p (operands[1], operands[0]))"
3560   [(set (match_dup 3) (match_dup 1))
3561    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3562               (clobber (reg:CC FLAGS_REG))])
3563    (set (match_dup 4) (match_dup 1))]
3564   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3565
3566 ;; Extend to memory case when source register does not die.
3567 (define_split
3568   [(set (match_operand:DI 0 "memory_operand" "")
3569         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3570    (clobber (reg:CC FLAGS_REG))
3571    (clobber (match_operand:SI 2 "register_operand" ""))]
3572   "reload_completed"
3573   [(const_int 0)]
3574 {
3575   split_di (&operands[0], 1, &operands[3], &operands[4]);
3576
3577   emit_move_insn (operands[3], operands[1]);
3578
3579   /* Generate a cltd if possible and doing so it profitable.  */
3580   if (true_regnum (operands[1]) == 0
3581       && true_regnum (operands[2]) == 1
3582       && (optimize_size || TARGET_USE_CLTD))
3583     {
3584       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3585     }
3586   else
3587     {
3588       emit_move_insn (operands[2], operands[1]);
3589       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3590     }
3591   emit_move_insn (operands[4], operands[2]);
3592   DONE;
3593 })
3594
3595 ;; Extend to register case.  Optimize case where source and destination
3596 ;; registers match and cases where we can use cltd.
3597 (define_split
3598   [(set (match_operand:DI 0 "register_operand" "")
3599         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3600    (clobber (reg:CC FLAGS_REG))
3601    (clobber (match_scratch:SI 2 ""))]
3602   "reload_completed"
3603   [(const_int 0)]
3604 {
3605   split_di (&operands[0], 1, &operands[3], &operands[4]);
3606
3607   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3608     emit_move_insn (operands[3], operands[1]);
3609
3610   /* Generate a cltd if possible and doing so it profitable.  */
3611   if (true_regnum (operands[3]) == 0
3612       && (optimize_size || TARGET_USE_CLTD))
3613     {
3614       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3615       DONE;
3616     }
3617
3618   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3619     emit_move_insn (operands[4], operands[1]);
3620
3621   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3622   DONE;
3623 })
3624
3625 (define_insn "extendhisi2"
3626   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3627         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3628   ""
3629 {
3630   switch (get_attr_prefix_0f (insn))
3631     {
3632     case 0:
3633       return "{cwtl|cwde}";
3634     default:
3635       return "movs{wl|x}\t{%1,%0|%0, %1}";
3636     }
3637 }
3638   [(set_attr "type" "imovx")
3639    (set_attr "mode" "SI")
3640    (set (attr "prefix_0f")
3641      ;; movsx is short decodable while cwtl is vector decoded.
3642      (if_then_else (and (eq_attr "cpu" "!k6")
3643                         (eq_attr "alternative" "0"))
3644         (const_string "0")
3645         (const_string "1")))
3646    (set (attr "modrm")
3647      (if_then_else (eq_attr "prefix_0f" "0")
3648         (const_string "0")
3649         (const_string "1")))])
3650
3651 (define_insn "*extendhisi2_zext"
3652   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3653         (zero_extend:DI
3654           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3655   "TARGET_64BIT"
3656 {
3657   switch (get_attr_prefix_0f (insn))
3658     {
3659     case 0:
3660       return "{cwtl|cwde}";
3661     default:
3662       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3663     }
3664 }
3665   [(set_attr "type" "imovx")
3666    (set_attr "mode" "SI")
3667    (set (attr "prefix_0f")
3668      ;; movsx is short decodable while cwtl is vector decoded.
3669      (if_then_else (and (eq_attr "cpu" "!k6")
3670                         (eq_attr "alternative" "0"))
3671         (const_string "0")
3672         (const_string "1")))
3673    (set (attr "modrm")
3674      (if_then_else (eq_attr "prefix_0f" "0")
3675         (const_string "0")
3676         (const_string "1")))])
3677
3678 (define_insn "extendqihi2"
3679   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3680         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3681   ""
3682 {
3683   switch (get_attr_prefix_0f (insn))
3684     {
3685     case 0:
3686       return "{cbtw|cbw}";
3687     default:
3688       return "movs{bw|x}\t{%1,%0|%0, %1}";
3689     }
3690 }
3691   [(set_attr "type" "imovx")
3692    (set_attr "mode" "HI")
3693    (set (attr "prefix_0f")
3694      ;; movsx is short decodable while cwtl is vector decoded.
3695      (if_then_else (and (eq_attr "cpu" "!k6")
3696                         (eq_attr "alternative" "0"))
3697         (const_string "0")
3698         (const_string "1")))
3699    (set (attr "modrm")
3700      (if_then_else (eq_attr "prefix_0f" "0")
3701         (const_string "0")
3702         (const_string "1")))])
3703
3704 (define_insn "extendqisi2"
3705   [(set (match_operand:SI 0 "register_operand" "=r")
3706         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3707   ""
3708   "movs{bl|x}\t{%1,%0|%0, %1}"
3709    [(set_attr "type" "imovx")
3710     (set_attr "mode" "SI")])
3711
3712 (define_insn "*extendqisi2_zext"
3713   [(set (match_operand:DI 0 "register_operand" "=r")
3714         (zero_extend:DI
3715           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3716   "TARGET_64BIT"
3717   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3718    [(set_attr "type" "imovx")
3719     (set_attr "mode" "SI")])
3720 \f
3721 ;; Conversions between float and double.
3722
3723 ;; These are all no-ops in the model used for the 80387.  So just
3724 ;; emit moves.
3725
3726 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3727 (define_insn "*dummy_extendsfdf2"
3728   [(set (match_operand:DF 0 "push_operand" "=<")
3729         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3730   "0"
3731   "#")
3732
3733 (define_split
3734   [(set (match_operand:DF 0 "push_operand" "")
3735         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3736   "!TARGET_64BIT"
3737   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3738    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3739
3740 (define_split
3741   [(set (match_operand:DF 0 "push_operand" "")
3742         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3743   "TARGET_64BIT"
3744   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3745    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3746
3747 (define_insn "*dummy_extendsfxf2"
3748   [(set (match_operand:XF 0 "push_operand" "=<")
3749         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3750   "0"
3751   "#")
3752
3753 (define_split
3754   [(set (match_operand:XF 0 "push_operand" "")
3755         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3756   ""
3757   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3758    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3759   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3760
3761 (define_split
3762   [(set (match_operand:XF 0 "push_operand" "")
3763         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3764   "TARGET_64BIT"
3765   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3766    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3767   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3768
3769 (define_split
3770   [(set (match_operand:XF 0 "push_operand" "")
3771         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3772   ""
3773   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3774    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3775   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3776
3777 (define_split
3778   [(set (match_operand:XF 0 "push_operand" "")
3779         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3780   "TARGET_64BIT"
3781   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3782    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3783   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3784
3785 (define_expand "extendsfdf2"
3786   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3787         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3788   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3789 {
3790   /* ??? Needed for compress_float_constant since all fp constants
3791      are LEGITIMATE_CONSTANT_P.  */
3792   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3793     {
3794       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3795           && standard_80387_constant_p (operands[1]) > 0)
3796         {
3797           operands[1] = simplify_const_unary_operation
3798             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3799           emit_move_insn_1 (operands[0], operands[1]);
3800           DONE;
3801         }
3802       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3803     }
3804 })
3805
3806 (define_insn "*extendsfdf2_mixed"
3807   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3808         (float_extend:DF
3809           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3810   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3811 {
3812   switch (which_alternative)
3813     {
3814     case 0:
3815       return output_387_reg_move (insn, operands);
3816
3817     case 1:
3818       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3819         return "fstp%z0\t%y0";
3820       else
3821         return "fst%z0\t%y0";
3822
3823     case 2:
3824       return "cvtss2sd\t{%1, %0|%0, %1}";
3825
3826     default:
3827       gcc_unreachable ();
3828     }
3829 }
3830   [(set_attr "type" "fmov,fmov,ssecvt")
3831    (set_attr "mode" "SF,XF,DF")])
3832
3833 (define_insn "*extendsfdf2_sse"
3834   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3835         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3836   "TARGET_SSE2 && TARGET_SSE_MATH"
3837   "cvtss2sd\t{%1, %0|%0, %1}"
3838   [(set_attr "type" "ssecvt")
3839    (set_attr "mode" "DF")])
3840
3841 (define_insn "*extendsfdf2_i387"
3842   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3843         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3844   "TARGET_80387"
3845 {
3846   switch (which_alternative)
3847     {
3848     case 0:
3849       return output_387_reg_move (insn, operands);
3850
3851     case 1:
3852       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3853         return "fstp%z0\t%y0";
3854       else
3855         return "fst%z0\t%y0";
3856
3857     default:
3858       gcc_unreachable ();
3859     }
3860 }
3861   [(set_attr "type" "fmov")
3862    (set_attr "mode" "SF,XF")])
3863
3864 (define_expand "extendsfxf2"
3865   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3866         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3867   "TARGET_80387"
3868 {
3869   /* ??? Needed for compress_float_constant since all fp constants
3870      are LEGITIMATE_CONSTANT_P.  */
3871   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3872     {
3873       if (standard_80387_constant_p (operands[1]) > 0)
3874         {
3875           operands[1] = simplify_const_unary_operation
3876             (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3877           emit_move_insn_1 (operands[0], operands[1]);
3878           DONE;
3879         }
3880       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3881     }
3882 })
3883
3884 (define_insn "*extendsfxf2_i387"
3885   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3886         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3887   "TARGET_80387"
3888 {
3889   switch (which_alternative)
3890     {
3891     case 0:
3892       return output_387_reg_move (insn, operands);
3893
3894     case 1:
3895       /* There is no non-popping store to memory for XFmode.  So if
3896          we need one, follow the store with a load.  */
3897       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3898         return "fstp%z0\t%y0";
3899       else
3900         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3901
3902     default:
3903       gcc_unreachable ();
3904     }
3905 }
3906   [(set_attr "type" "fmov")
3907    (set_attr "mode" "SF,XF")])
3908
3909 (define_expand "extenddfxf2"
3910   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3911         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3912   "TARGET_80387"
3913 {
3914   /* ??? Needed for compress_float_constant since all fp constants
3915      are LEGITIMATE_CONSTANT_P.  */
3916   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3917     {
3918       if (standard_80387_constant_p (operands[1]) > 0)
3919         {
3920           operands[1] = simplify_const_unary_operation
3921             (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3922           emit_move_insn_1 (operands[0], operands[1]);
3923           DONE;
3924         }
3925       operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3926     }
3927 })
3928
3929 (define_insn "*extenddfxf2_i387"
3930   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3931         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3932   "TARGET_80387"
3933 {
3934   switch (which_alternative)
3935     {
3936     case 0:
3937       return output_387_reg_move (insn, operands);
3938
3939     case 1:
3940       /* There is no non-popping store to memory for XFmode.  So if
3941          we need one, follow the store with a load.  */
3942       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3943         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3944       else
3945         return "fstp%z0\t%y0";
3946
3947     default:
3948       gcc_unreachable ();
3949     }
3950 }
3951   [(set_attr "type" "fmov")
3952    (set_attr "mode" "DF,XF")])
3953
3954 ;; %%% This seems bad bad news.
3955 ;; This cannot output into an f-reg because there is no way to be sure
3956 ;; of truncating in that case.  Otherwise this is just like a simple move
3957 ;; insn.  So we pretend we can output to a reg in order to get better
3958 ;; register preferencing, but we really use a stack slot.
3959
3960 ;; Conversion from DFmode to SFmode.
3961
3962 (define_expand "truncdfsf2"
3963   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3964         (float_truncate:SF
3965           (match_operand:DF 1 "nonimmediate_operand" "")))]
3966   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3967 {
3968   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3969     ;
3970   else if (flag_unsafe_math_optimizations)
3971     ;
3972   else
3973     {
3974       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3975       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3976       DONE;
3977     }
3978 })
3979
3980 (define_expand "truncdfsf2_with_temp"
3981   [(parallel [(set (match_operand:SF 0 "" "")
3982                    (float_truncate:SF (match_operand:DF 1 "" "")))
3983               (clobber (match_operand:SF 2 "" ""))])]
3984   "")
3985
3986 (define_insn "*truncdfsf_fast_mixed"
3987   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,x")
3988         (float_truncate:SF
3989           (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
3990   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3991 {
3992   switch (which_alternative)
3993     {
3994     case 0:
3995       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3996         return "fstp%z0\t%y0";
3997       else
3998         return "fst%z0\t%y0";
3999     case 1:
4000       return output_387_reg_move (insn, operands);
4001     case 2:
4002       return "cvtsd2ss\t{%1, %0|%0, %1}";
4003     default:
4004       gcc_unreachable ();
4005     }
4006 }
4007   [(set_attr "type" "fmov,fmov,ssecvt")
4008    (set_attr "mode" "SF")])
4009
4010 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4011 ;; because nothing we do here is unsafe.
4012 (define_insn "*truncdfsf_fast_sse"
4013   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4014         (float_truncate:SF
4015           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4016   "TARGET_SSE2 && TARGET_SSE_MATH"
4017   "cvtsd2ss\t{%1, %0|%0, %1}"
4018   [(set_attr "type" "ssecvt")
4019    (set_attr "mode" "SF")])
4020
4021 (define_insn "*truncdfsf_fast_i387"
4022   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4023         (float_truncate:SF
4024           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4025   "TARGET_80387 && flag_unsafe_math_optimizations"
4026   "* return output_387_reg_move (insn, operands);"
4027   [(set_attr "type" "fmov")
4028    (set_attr "mode" "SF")])
4029
4030 (define_insn "*truncdfsf_mixed"
4031   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y2")
4032         (float_truncate:SF
4033           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Y2m")))
4034    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
4035   "TARGET_MIX_SSE_I387"
4036 {
4037   switch (which_alternative)
4038     {
4039     case 0:
4040       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4041         return "fstp%z0\t%y0";
4042       else
4043         return "fst%z0\t%y0";
4044     case 1:
4045       return "#";
4046     case 2:
4047       return "cvtsd2ss\t{%1, %0|%0, %1}";
4048     default:
4049       gcc_unreachable ();
4050     }
4051 }
4052   [(set_attr "type" "fmov,multi,ssecvt")
4053    (set_attr "unit" "*,i387,*")
4054    (set_attr "mode" "SF")])
4055
4056 (define_insn "*truncdfsf_i387"
4057   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4058         (float_truncate:SF
4059           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4060    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4061   "TARGET_80387"
4062 {
4063   switch (which_alternative)
4064     {
4065     case 0:
4066       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4067         return "fstp%z0\t%y0";
4068       else
4069         return "fst%z0\t%y0";
4070     case 1:
4071       return "#";
4072     default:
4073       gcc_unreachable ();
4074     }
4075 }
4076   [(set_attr "type" "fmov,multi")
4077    (set_attr "unit" "*,i387")
4078    (set_attr "mode" "SF")])
4079
4080 (define_insn "*truncdfsf2_i387_1"
4081   [(set (match_operand:SF 0 "memory_operand" "=m")
4082         (float_truncate:SF
4083           (match_operand:DF 1 "register_operand" "f")))]
4084   "TARGET_80387
4085    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4086    && !TARGET_MIX_SSE_I387"
4087 {
4088   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4089     return "fstp%z0\t%y0";
4090   else
4091     return "fst%z0\t%y0";
4092 }
4093   [(set_attr "type" "fmov")
4094    (set_attr "mode" "SF")])
4095
4096 (define_split
4097   [(set (match_operand:SF 0 "register_operand" "")
4098         (float_truncate:SF
4099          (match_operand:DF 1 "fp_register_operand" "")))
4100    (clobber (match_operand 2 "" ""))]
4101   "reload_completed"
4102   [(set (match_dup 2) (match_dup 1))
4103    (set (match_dup 0) (match_dup 2))]
4104 {
4105   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4106 })
4107
4108 ;; Conversion from XFmode to SFmode.
4109
4110 (define_expand "truncxfsf2"
4111   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4112                    (float_truncate:SF
4113                     (match_operand:XF 1 "register_operand" "")))
4114               (clobber (match_dup 2))])]
4115   "TARGET_80387"
4116 {
4117   if (flag_unsafe_math_optimizations)
4118     {
4119       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
4120       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
4121       if (reg != operands[0])
4122         emit_move_insn (operands[0], reg);
4123       DONE;
4124     }
4125   else
4126     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
4127 })
4128
4129 (define_insn "*truncxfsf2_mixed"
4130   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
4131         (float_truncate:SF
4132          (match_operand:XF 1 "register_operand" "f,f,f,f")))
4133    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4134   "TARGET_80387"
4135 {
4136   gcc_assert (!which_alternative);
4137   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4138     return "fstp%z0\t%y0";
4139   else
4140     return "fst%z0\t%y0";
4141 }
4142   [(set_attr "type" "fmov,multi,multi,multi")
4143    (set_attr "unit" "*,i387,i387,i387")
4144    (set_attr "mode" "SF")])
4145
4146 (define_insn "truncxfsf2_i387_noop"
4147   [(set (match_operand:SF 0 "register_operand" "=f")
4148         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
4149   "TARGET_80387 && flag_unsafe_math_optimizations"
4150   "* return output_387_reg_move (insn, operands);"
4151   [(set_attr "type" "fmov")
4152    (set_attr "mode" "SF")])
4153
4154 (define_insn "*truncxfsf2_i387"
4155   [(set (match_operand:SF 0 "memory_operand" "=m")
4156         (float_truncate:SF
4157          (match_operand:XF 1 "register_operand" "f")))]
4158   "TARGET_80387"
4159 {
4160   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4161     return "fstp%z0\t%y0";
4162   else
4163     return "fst%z0\t%y0";
4164 }
4165   [(set_attr "type" "fmov")
4166    (set_attr "mode" "SF")])
4167
4168 (define_split
4169   [(set (match_operand:SF 0 "register_operand" "")
4170         (float_truncate:SF
4171          (match_operand:XF 1 "register_operand" "")))
4172    (clobber (match_operand:SF 2 "memory_operand" ""))]
4173   "TARGET_80387 && reload_completed"
4174   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4175    (set (match_dup 0) (match_dup 2))]
4176   "")
4177
4178 (define_split
4179   [(set (match_operand:SF 0 "memory_operand" "")
4180         (float_truncate:SF
4181          (match_operand:XF 1 "register_operand" "")))
4182    (clobber (match_operand:SF 2 "memory_operand" ""))]
4183   "TARGET_80387"
4184   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4185   "")
4186
4187 ;; Conversion from XFmode to DFmode.
4188
4189 (define_expand "truncxfdf2"
4190   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4191                    (float_truncate:DF
4192                     (match_operand:XF 1 "register_operand" "")))
4193               (clobber (match_dup 2))])]
4194   "TARGET_80387"
4195 {
4196   if (flag_unsafe_math_optimizations)
4197     {
4198       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4199       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4200       if (reg != operands[0])
4201         emit_move_insn (operands[0], reg);
4202       DONE;
4203     }
4204   else
4205     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
4206 })
4207
4208 (define_insn "*truncxfdf2_mixed"
4209   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y2*x")
4210         (float_truncate:DF
4211          (match_operand:XF 1 "register_operand" "f,f,f,f")))
4212    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4213   "TARGET_80387"
4214 {
4215   gcc_assert (!which_alternative);
4216   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4217     return "fstp%z0\t%y0";
4218   else
4219     return "fst%z0\t%y0";
4220 }
4221   [(set_attr "type" "fmov,multi,multi,multi")
4222    (set_attr "unit" "*,i387,i387,i387")
4223    (set_attr "mode" "DF")])
4224
4225 (define_insn "truncxfdf2_i387_noop"
4226   [(set (match_operand:DF 0 "register_operand" "=f")
4227         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4228   "TARGET_80387 && flag_unsafe_math_optimizations"
4229   "* return output_387_reg_move (insn, operands);"
4230   [(set_attr "type" "fmov")
4231    (set_attr "mode" "DF")])
4232
4233 (define_insn "*truncxfdf2_i387"
4234   [(set (match_operand:DF 0 "memory_operand" "=m")
4235         (float_truncate:DF
4236           (match_operand:XF 1 "register_operand" "f")))]
4237   "TARGET_80387"
4238 {
4239   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4240     return "fstp%z0\t%y0";
4241   else
4242     return "fst%z0\t%y0";
4243 }
4244   [(set_attr "type" "fmov")
4245    (set_attr "mode" "DF")])
4246
4247 (define_split
4248   [(set (match_operand:DF 0 "register_operand" "")
4249         (float_truncate:DF
4250          (match_operand:XF 1 "register_operand" "")))
4251    (clobber (match_operand:DF 2 "memory_operand" ""))]
4252   "TARGET_80387 && reload_completed"
4253   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4254    (set (match_dup 0) (match_dup 2))]
4255   "")
4256
4257 (define_split
4258   [(set (match_operand:DF 0 "memory_operand" "")
4259         (float_truncate:DF
4260          (match_operand:XF 1 "register_operand" "")))
4261    (clobber (match_operand:DF 2 "memory_operand" ""))]
4262   "TARGET_80387"
4263   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4264   "")
4265 \f
4266 ;; Signed conversion to DImode.
4267
4268 (define_expand "fix_truncxfdi2"
4269   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4270                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4271               (clobber (reg:CC FLAGS_REG))])]
4272   "TARGET_80387"
4273 {
4274   if (TARGET_FISTTP)
4275    {
4276      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4277      DONE;
4278    }
4279 })
4280
4281 (define_expand "fix_trunc<mode>di2"
4282   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4283                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4284               (clobber (reg:CC FLAGS_REG))])]
4285   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4286 {
4287   if (TARGET_FISTTP
4288       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4289    {
4290      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4291      DONE;
4292    }
4293   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4294    {
4295      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4296      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4297      if (out != operands[0])
4298         emit_move_insn (operands[0], out);
4299      DONE;
4300    }
4301 })
4302
4303 ;; Signed conversion to SImode.
4304
4305 (define_expand "fix_truncxfsi2"
4306   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4307                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4308               (clobber (reg:CC FLAGS_REG))])]
4309   "TARGET_80387"
4310 {
4311   if (TARGET_FISTTP)
4312    {
4313      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4314      DONE;
4315    }
4316 })
4317
4318 (define_expand "fix_trunc<mode>si2"
4319   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4320                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4321               (clobber (reg:CC FLAGS_REG))])]
4322   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4323 {
4324   if (TARGET_FISTTP
4325       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4326    {
4327      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4328      DONE;
4329    }
4330   if (SSE_FLOAT_MODE_P (<MODE>mode))
4331    {
4332      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4333      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4334      if (out != operands[0])
4335         emit_move_insn (operands[0], out);
4336      DONE;
4337    }
4338 })
4339
4340 ;; Signed conversion to HImode.
4341
4342 (define_expand "fix_trunc<mode>hi2"
4343   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4344                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4345               (clobber (reg:CC FLAGS_REG))])]
4346   "TARGET_80387
4347    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4348 {
4349   if (TARGET_FISTTP)
4350    {
4351      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4352      DONE;
4353    }
4354 })
4355
4356 ;; Unsigned conversion to SImode.
4357
4358 (define_expand "fixuns_trunc<mode>si2"
4359   [(parallel
4360     [(set (match_operand:SI 0 "register_operand" "")
4361           (unsigned_fix:SI
4362             (match_operand:SSEMODEF 1 "nonimmediate_operand" "")))
4363      (use (match_dup 2))
4364      (clobber (match_scratch:<ssevecmode> 3 ""))
4365      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4366   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4367 {
4368   enum machine_mode mode = <MODE>mode;
4369   enum machine_mode vecmode = <ssevecmode>mode;
4370   REAL_VALUE_TYPE TWO31r;
4371   rtx two31;
4372
4373   real_ldexp (&TWO31r, &dconst1, 31);
4374   two31 = const_double_from_real_value (TWO31r, mode);
4375   two31 = ix86_build_const_vector (mode, true, two31);
4376   operands[2] = force_reg (vecmode, two31);
4377 })
4378
4379 (define_insn_and_split "*fixuns_trunc<mode>_1"
4380   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4381         (unsigned_fix:SI
4382           (match_operand:SSEMODEF 3 "nonimmediate_operand" "xm,xm")))
4383    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4384    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4385    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4386   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4387   "#"
4388   "&& reload_completed"
4389   [(const_int 0)]
4390 {
4391   ix86_split_convert_uns_si_sse (operands);
4392   DONE;
4393 })
4394
4395 ;; Unsigned conversion to HImode.
4396 ;; Without these patterns, we'll try the unsigned SI conversion which
4397 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4398
4399 (define_expand "fixuns_trunc<mode>hi2"
4400   [(set (match_dup 2)
4401         (fix:SI (match_operand:SSEMODEF 1 "nonimmediate_operand" "")))
4402    (set (match_operand:HI 0 "nonimmediate_operand" "")
4403         (subreg:HI (match_dup 2) 0))]
4404   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4405   "operands[2] = gen_reg_rtx (SImode);")
4406
4407 ;; When SSE is available, it is always faster to use it!
4408 (define_insn "fix_trunc<mode>di_sse"
4409   [(set (match_operand:DI 0 "register_operand" "=r,r")
4410         (fix:DI (match_operand:SSEMODEF 1 "nonimmediate_operand" "x,xm")))]
4411   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4412    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4413   "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4414   [(set_attr "type" "sseicvt")
4415    (set_attr "mode" "<MODE>")
4416    (set_attr "athlon_decode" "double,vector")
4417    (set_attr "amdfam10_decode" "double,double")])
4418
4419 (define_insn "fix_trunc<mode>si_sse"
4420   [(set (match_operand:SI 0 "register_operand" "=r,r")
4421         (fix:SI (match_operand:SSEMODEF 1 "nonimmediate_operand" "x,xm")))]
4422   "SSE_FLOAT_MODE_P (<MODE>mode)
4423    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4424   "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4425   [(set_attr "type" "sseicvt")
4426    (set_attr "mode" "<MODE>")
4427    (set_attr "athlon_decode" "double,vector")
4428    (set_attr "amdfam10_decode" "double,double")])
4429
4430 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4431 (define_peephole2
4432   [(set (match_operand:SSEMODEF 0 "register_operand" "")
4433         (match_operand:SSEMODEF 1 "memory_operand" ""))
4434    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4435         (fix:SSEMODEI24 (match_dup 0)))]
4436   "!TARGET_K8
4437    && peep2_reg_dead_p (2, operands[0])"
4438   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4439   "")
4440
4441 ;; Avoid vector decoded forms of the instruction.
4442 (define_peephole2
4443   [(match_scratch:DF 2 "Y2")
4444    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4445         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4446   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4447   [(set (match_dup 2) (match_dup 1))
4448    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4449   "")
4450
4451 (define_peephole2
4452   [(match_scratch:SF 2 "x")
4453    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4454         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4455   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4456   [(set (match_dup 2) (match_dup 1))
4457    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4458   "")
4459
4460 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4461   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4462         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4463   "TARGET_FISTTP
4464    && FLOAT_MODE_P (GET_MODE (operands[1]))
4465    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4466          && (TARGET_64BIT || <MODE>mode != DImode))
4467         && TARGET_SSE_MATH)
4468    && !(reload_completed || reload_in_progress)"
4469   "#"
4470   "&& 1"
4471   [(const_int 0)]
4472 {
4473   if (memory_operand (operands[0], VOIDmode))
4474     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4475   else
4476     {
4477       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4478       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4479                                                             operands[1],
4480                                                             operands[2]));
4481     }
4482   DONE;
4483 }
4484   [(set_attr "type" "fisttp")
4485    (set_attr "mode" "<MODE>")])
4486
4487 (define_insn "fix_trunc<mode>_i387_fisttp"
4488   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4489         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4490    (clobber (match_scratch:XF 2 "=&1f"))]
4491   "TARGET_FISTTP
4492    && FLOAT_MODE_P (GET_MODE (operands[1]))
4493    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4494          && (TARGET_64BIT || <MODE>mode != DImode))
4495         && TARGET_SSE_MATH)"
4496   "* return output_fix_trunc (insn, operands, 1);"
4497   [(set_attr "type" "fisttp")
4498    (set_attr "mode" "<MODE>")])
4499
4500 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4501   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4502         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4503    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4504    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4505   "TARGET_FISTTP
4506    && FLOAT_MODE_P (GET_MODE (operands[1]))
4507    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4508         && (TARGET_64BIT || <MODE>mode != DImode))
4509         && TARGET_SSE_MATH)"
4510   "#"
4511   [(set_attr "type" "fisttp")
4512    (set_attr "mode" "<MODE>")])
4513
4514 (define_split
4515   [(set (match_operand:X87MODEI 0 "register_operand" "")
4516         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4517    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4518    (clobber (match_scratch 3 ""))]
4519   "reload_completed"
4520   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4521               (clobber (match_dup 3))])
4522    (set (match_dup 0) (match_dup 2))]
4523   "")
4524
4525 (define_split
4526   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4527         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4528    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4529    (clobber (match_scratch 3 ""))]
4530   "reload_completed"
4531   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4532               (clobber (match_dup 3))])]
4533   "")
4534
4535 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4536 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4537 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4538 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4539 ;; function in i386.c.
4540 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4541   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4542         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4543    (clobber (reg:CC FLAGS_REG))]
4544   "TARGET_80387 && !TARGET_FISTTP
4545    && FLOAT_MODE_P (GET_MODE (operands[1]))
4546    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4547          && (TARGET_64BIT || <MODE>mode != DImode))
4548    && !(reload_completed || reload_in_progress)"
4549   "#"
4550   "&& 1"
4551   [(const_int 0)]
4552 {
4553   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4554
4555   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4556   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4557   if (memory_operand (operands[0], VOIDmode))
4558     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4559                                          operands[2], operands[3]));
4560   else
4561     {
4562       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4563       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4564                                                      operands[2], operands[3],
4565                                                      operands[4]));
4566     }
4567   DONE;
4568 }
4569   [(set_attr "type" "fistp")
4570    (set_attr "i387_cw" "trunc")
4571    (set_attr "mode" "<MODE>")])
4572
4573 (define_insn "fix_truncdi_i387"
4574   [(set (match_operand:DI 0 "memory_operand" "=m")
4575         (fix:DI (match_operand 1 "register_operand" "f")))
4576    (use (match_operand:HI 2 "memory_operand" "m"))
4577    (use (match_operand:HI 3 "memory_operand" "m"))
4578    (clobber (match_scratch:XF 4 "=&1f"))]
4579   "TARGET_80387 && !TARGET_FISTTP
4580    && FLOAT_MODE_P (GET_MODE (operands[1]))
4581    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4582   "* return output_fix_trunc (insn, operands, 0);"
4583   [(set_attr "type" "fistp")
4584    (set_attr "i387_cw" "trunc")
4585    (set_attr "mode" "DI")])
4586
4587 (define_insn "fix_truncdi_i387_with_temp"
4588   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4589         (fix:DI (match_operand 1 "register_operand" "f,f")))
4590    (use (match_operand:HI 2 "memory_operand" "m,m"))
4591    (use (match_operand:HI 3 "memory_operand" "m,m"))
4592    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4593    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4594   "TARGET_80387 && !TARGET_FISTTP
4595    && FLOAT_MODE_P (GET_MODE (operands[1]))
4596    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4597   "#"
4598   [(set_attr "type" "fistp")
4599    (set_attr "i387_cw" "trunc")
4600    (set_attr "mode" "DI")])
4601
4602 (define_split
4603   [(set (match_operand:DI 0 "register_operand" "")
4604         (fix:DI (match_operand 1 "register_operand" "")))
4605    (use (match_operand:HI 2 "memory_operand" ""))
4606    (use (match_operand:HI 3 "memory_operand" ""))
4607    (clobber (match_operand:DI 4 "memory_operand" ""))
4608    (clobber (match_scratch 5 ""))]
4609   "reload_completed"
4610   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4611               (use (match_dup 2))
4612               (use (match_dup 3))
4613               (clobber (match_dup 5))])
4614    (set (match_dup 0) (match_dup 4))]
4615   "")
4616
4617 (define_split
4618   [(set (match_operand:DI 0 "memory_operand" "")
4619         (fix:DI (match_operand 1 "register_operand" "")))
4620    (use (match_operand:HI 2 "memory_operand" ""))
4621    (use (match_operand:HI 3 "memory_operand" ""))
4622    (clobber (match_operand:DI 4 "memory_operand" ""))
4623    (clobber (match_scratch 5 ""))]
4624   "reload_completed"
4625   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4626               (use (match_dup 2))
4627               (use (match_dup 3))
4628               (clobber (match_dup 5))])]
4629   "")
4630
4631 (define_insn "fix_trunc<mode>_i387"
4632   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4633         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4634    (use (match_operand:HI 2 "memory_operand" "m"))
4635    (use (match_operand:HI 3 "memory_operand" "m"))]
4636   "TARGET_80387 && !TARGET_FISTTP
4637    && FLOAT_MODE_P (GET_MODE (operands[1]))
4638    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4639   "* return output_fix_trunc (insn, operands, 0);"
4640   [(set_attr "type" "fistp")
4641    (set_attr "i387_cw" "trunc")
4642    (set_attr "mode" "<MODE>")])
4643
4644 (define_insn "fix_trunc<mode>_i387_with_temp"
4645   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4646         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4647    (use (match_operand:HI 2 "memory_operand" "m,m"))
4648    (use (match_operand:HI 3 "memory_operand" "m,m"))
4649    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4650   "TARGET_80387 && !TARGET_FISTTP
4651    && FLOAT_MODE_P (GET_MODE (operands[1]))
4652    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4653   "#"
4654   [(set_attr "type" "fistp")
4655    (set_attr "i387_cw" "trunc")
4656    (set_attr "mode" "<MODE>")])
4657
4658 (define_split
4659   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4660         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4661    (use (match_operand:HI 2 "memory_operand" ""))
4662    (use (match_operand:HI 3 "memory_operand" ""))
4663    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4664   "reload_completed"
4665   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4666               (use (match_dup 2))
4667               (use (match_dup 3))])
4668    (set (match_dup 0) (match_dup 4))]
4669   "")
4670
4671 (define_split
4672   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4673         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4674    (use (match_operand:HI 2 "memory_operand" ""))
4675    (use (match_operand:HI 3 "memory_operand" ""))
4676    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4677   "reload_completed"
4678   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4679               (use (match_dup 2))
4680               (use (match_dup 3))])]
4681   "")
4682
4683 (define_insn "x86_fnstcw_1"
4684   [(set (match_operand:HI 0 "memory_operand" "=m")
4685         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4686   "TARGET_80387"
4687   "fnstcw\t%0"
4688   [(set_attr "length" "2")
4689    (set_attr "mode" "HI")
4690    (set_attr "unit" "i387")])
4691
4692 (define_insn "x86_fldcw_1"
4693   [(set (reg:HI FPCR_REG)
4694         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4695   "TARGET_80387"
4696   "fldcw\t%0"
4697   [(set_attr "length" "2")
4698    (set_attr "mode" "HI")
4699    (set_attr "unit" "i387")
4700    (set_attr "athlon_decode" "vector")
4701    (set_attr "amdfam10_decode" "vector")])   
4702 \f
4703 ;; Conversion between fixed point and floating point.
4704
4705 ;; Even though we only accept memory inputs, the backend _really_
4706 ;; wants to be able to do this between registers.
4707
4708 (define_expand "floathisf2"
4709   [(set (match_operand:SF 0 "register_operand" "")
4710         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4711   "TARGET_80387 || TARGET_SSE_MATH"
4712 {
4713   if (TARGET_SSE_MATH)
4714     {
4715       emit_insn (gen_floatsisf2 (operands[0],
4716                                  convert_to_mode (SImode, operands[1], 0)));
4717       DONE;
4718     }
4719 })
4720
4721 (define_insn "*floathisf2_i387"
4722   [(set (match_operand:SF 0 "register_operand" "=f,f")
4723         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4724   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4725   "@
4726    fild%z1\t%1
4727    #"
4728   [(set_attr "type" "fmov,multi")
4729    (set_attr "mode" "SF")
4730    (set_attr "unit" "*,i387")
4731    (set_attr "fp_int_src" "true")])
4732
4733 (define_expand "floatsisf2"
4734   [(set (match_operand:SF 0 "register_operand" "")
4735         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4736   "TARGET_80387 || TARGET_SSE_MATH"
4737   "")
4738
4739 (define_insn "*floatsisf2_mixed"
4740   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4741         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4742   "TARGET_MIX_SSE_I387"
4743   "@
4744    fild%z1\t%1
4745    #
4746    cvtsi2ss\t{%1, %0|%0, %1}
4747    cvtsi2ss\t{%1, %0|%0, %1}"
4748   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4749    (set_attr "mode" "SF")
4750    (set_attr "unit" "*,i387,*,*")
4751    (set_attr "athlon_decode" "*,*,vector,double")
4752    (set_attr "amdfam10_decode" "*,*,vector,double")
4753    (set_attr "fp_int_src" "true")])
4754
4755 (define_insn "*floatsisf2_sse"
4756   [(set (match_operand:SF 0 "register_operand" "=x,x")
4757         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4758   "TARGET_SSE_MATH"
4759   "cvtsi2ss\t{%1, %0|%0, %1}"
4760   [(set_attr "type" "sseicvt")
4761    (set_attr "mode" "SF")
4762    (set_attr "athlon_decode" "vector,double")
4763    (set_attr "amdfam10_decode" "vector,double")
4764    (set_attr "fp_int_src" "true")])
4765
4766 (define_insn "*floatsisf2_i387"
4767   [(set (match_operand:SF 0 "register_operand" "=f,f")
4768         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4769   "TARGET_80387"
4770   "@
4771    fild%z1\t%1
4772    #"
4773   [(set_attr "type" "fmov,multi")
4774    (set_attr "mode" "SF")
4775    (set_attr "unit" "*,i387")
4776    (set_attr "fp_int_src" "true")])
4777
4778 (define_expand "floatdisf2"
4779   [(set (match_operand:SF 0 "register_operand" "")
4780         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4781   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4782   "")
4783
4784 (define_insn "*floatdisf2_mixed"
4785   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4786         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4787   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4788   "@
4789    fild%z1\t%1
4790    #
4791    cvtsi2ss{q}\t{%1, %0|%0, %1}
4792    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4793   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4794    (set_attr "mode" "SF")
4795    (set_attr "unit" "*,i387,*,*")
4796    (set_attr "athlon_decode" "*,*,vector,double")
4797    (set_attr "amdfam10_decode" "*,*,vector,double")
4798    (set_attr "fp_int_src" "true")])
4799
4800 (define_insn "*floatdisf2_sse"
4801   [(set (match_operand:SF 0 "register_operand" "=x,x")
4802         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4803   "TARGET_64BIT && TARGET_SSE_MATH"
4804   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4805   [(set_attr "type" "sseicvt")
4806    (set_attr "mode" "SF")
4807    (set_attr "athlon_decode" "vector,double")
4808    (set_attr "amdfam10_decode" "vector,double")
4809    (set_attr "fp_int_src" "true")])
4810
4811 (define_insn "*floatdisf2_i387"
4812   [(set (match_operand:SF 0 "register_operand" "=f,f")
4813         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4814   "TARGET_80387"
4815   "@
4816    fild%z1\t%1
4817    #"
4818   [(set_attr "type" "fmov,multi")
4819    (set_attr "mode" "SF")
4820    (set_attr "unit" "*,i387")
4821    (set_attr "fp_int_src" "true")])
4822
4823 (define_expand "floathidf2"
4824   [(set (match_operand:DF 0 "register_operand" "")
4825         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4826   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4827 {
4828   if (TARGET_SSE2 && TARGET_SSE_MATH)
4829     {
4830       emit_insn (gen_floatsidf2 (operands[0],
4831                                  convert_to_mode (SImode, operands[1], 0)));
4832       DONE;
4833     }
4834 })
4835
4836 (define_insn "*floathidf2_i387"
4837   [(set (match_operand:DF 0 "register_operand" "=f,f")
4838         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4839   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4840   "@
4841    fild%z1\t%1
4842    #"
4843   [(set_attr "type" "fmov,multi")
4844    (set_attr "mode" "DF")
4845    (set_attr "unit" "*,i387")
4846    (set_attr "fp_int_src" "true")])
4847
4848 (define_expand "floatsidf2"
4849   [(set (match_operand:DF 0 "register_operand" "")
4850         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4851   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4852   "")
4853
4854 (define_insn "*floatsidf2_mixed"
4855   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4856         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4857   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4858   "@
4859    fild%z1\t%1
4860    #
4861    cvtsi2sd\t{%1, %0|%0, %1}
4862    cvtsi2sd\t{%1, %0|%0, %1}"
4863   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4864    (set_attr "mode" "DF")
4865    (set_attr "unit" "*,i387,*,*")
4866    (set_attr "athlon_decode" "*,*,double,direct")
4867    (set_attr "amdfam10_decode" "*,*,vector,double")
4868    (set_attr "fp_int_src" "true")])
4869
4870 (define_insn "*floatsidf2_sse"
4871   [(set (match_operand:DF 0 "register_operand" "=x,x")
4872         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4873   "TARGET_SSE2 && TARGET_SSE_MATH"
4874   "cvtsi2sd\t{%1, %0|%0, %1}"
4875   [(set_attr "type" "sseicvt")
4876    (set_attr "mode" "DF")
4877    (set_attr "athlon_decode" "double,direct")
4878    (set_attr "amdfam10_decode" "vector,double")
4879    (set_attr "fp_int_src" "true")])
4880
4881 (define_insn "*floatsidf2_i387"
4882   [(set (match_operand:DF 0 "register_operand" "=f,f")
4883         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4884   "TARGET_80387"
4885   "@
4886    fild%z1\t%1
4887    #"
4888   [(set_attr "type" "fmov,multi")
4889    (set_attr "mode" "DF")
4890    (set_attr "unit" "*,i387")
4891    (set_attr "fp_int_src" "true")])
4892
4893 (define_expand "floatdidf2"
4894   [(set (match_operand:DF 0 "register_operand" "")
4895         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4896   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4897 {
4898   if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
4899     {
4900       ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
4901       DONE;
4902     }
4903 })
4904
4905 (define_insn "*floatdidf2_mixed"
4906   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4907         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4908   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4909   "@
4910    fild%z1\t%1
4911    #
4912    cvtsi2sd{q}\t{%1, %0|%0, %1}
4913    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4914   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4915    (set_attr "mode" "DF")
4916    (set_attr "unit" "*,i387,*,*")
4917    (set_attr "athlon_decode" "*,*,double,direct")
4918    (set_attr "amdfam10_decode" "*,*,vector,double")
4919    (set_attr "fp_int_src" "true")])
4920
4921 (define_insn "*floatdidf2_sse"
4922   [(set (match_operand:DF 0 "register_operand" "=x,x")
4923         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4924   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4925   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4926   [(set_attr "type" "sseicvt")
4927    (set_attr "mode" "DF")
4928    (set_attr "athlon_decode" "double,direct")
4929    (set_attr "amdfam10_decode" "vector,double")
4930    (set_attr "fp_int_src" "true")])
4931
4932 (define_insn "*floatdidf2_i387"
4933   [(set (match_operand:DF 0 "register_operand" "=f,f")
4934         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4935   "TARGET_80387"
4936   "@
4937    fild%z1\t%1
4938    #"
4939   [(set_attr "type" "fmov,multi")
4940    (set_attr "mode" "DF")
4941    (set_attr "unit" "*,i387")
4942    (set_attr "fp_int_src" "true")])
4943
4944 (define_insn "floathixf2"
4945   [(set (match_operand:XF 0 "register_operand" "=f,f")
4946         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4947   "TARGET_80387"
4948   "@
4949    fild%z1\t%1
4950    #"
4951   [(set_attr "type" "fmov,multi")
4952    (set_attr "mode" "XF")
4953    (set_attr "unit" "*,i387")
4954    (set_attr "fp_int_src" "true")])
4955
4956 (define_insn "floatsixf2"
4957   [(set (match_operand:XF 0 "register_operand" "=f,f")
4958         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4959   "TARGET_80387"
4960   "@
4961    fild%z1\t%1
4962    #"
4963   [(set_attr "type" "fmov,multi")
4964    (set_attr "mode" "XF")
4965    (set_attr "unit" "*,i387")
4966    (set_attr "fp_int_src" "true")])
4967
4968 (define_insn "floatdixf2"
4969   [(set (match_operand:XF 0 "register_operand" "=f,f")
4970         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4971   "TARGET_80387"
4972   "@
4973    fild%z1\t%1
4974    #"
4975   [(set_attr "type" "fmov,multi")
4976    (set_attr "mode" "XF")
4977    (set_attr "unit" "*,i387")
4978    (set_attr "fp_int_src" "true")])
4979
4980 ;; %%% Kill these when reload knows how to do it.
4981 (define_split
4982   [(set (match_operand 0 "fp_register_operand" "")
4983         (float (match_operand 1 "register_operand" "")))]
4984   "reload_completed
4985    && TARGET_80387
4986    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4987   [(const_int 0)]
4988 {
4989   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4990   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4991   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4992   ix86_free_from_memory (GET_MODE (operands[1]));
4993   DONE;
4994 })
4995
4996 (define_expand "floatunssisf2"
4997   [(use (match_operand:SF 0 "register_operand" ""))
4998    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
4999   "!TARGET_64BIT"
5000 {
5001   if (TARGET_SSE_MATH && TARGET_SSE2)
5002     ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
5003   else
5004     x86_emit_floatuns (operands);
5005   DONE;
5006 })
5007
5008 (define_expand "floatunssidf2"
5009   [(use (match_operand:DF 0 "register_operand" ""))
5010    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5011   "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
5012   "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
5013
5014 (define_expand "floatunsdisf2"
5015   [(use (match_operand:SF 0 "register_operand" ""))
5016    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5017   "TARGET_64BIT && TARGET_SSE_MATH"
5018   "x86_emit_floatuns (operands); DONE;")
5019
5020 (define_expand "floatunsdidf2"
5021   [(use (match_operand:DF 0 "register_operand" ""))
5022    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5023   "TARGET_SSE_MATH && TARGET_SSE2
5024    && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
5025 {
5026   if (TARGET_64BIT)
5027     x86_emit_floatuns (operands);
5028   else
5029     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5030   DONE;
5031 })
5032 \f
5033 ;; SSE extract/set expanders
5034
5035 \f
5036 ;; Add instructions
5037
5038 ;; %%% splits for addditi3
5039
5040 (define_expand "addti3"
5041   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5042         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5043                  (match_operand:TI 2 "x86_64_general_operand" "")))
5044    (clobber (reg:CC FLAGS_REG))]
5045   "TARGET_64BIT"
5046   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5047
5048 (define_insn "*addti3_1"
5049   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5050         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5051                  (match_operand:TI 2 "general_operand" "roiF,riF")))
5052    (clobber (reg:CC FLAGS_REG))]
5053   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5054   "#")
5055
5056 (define_split
5057   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5058         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5059                  (match_operand:TI 2 "general_operand" "")))
5060    (clobber (reg:CC FLAGS_REG))]
5061   "TARGET_64BIT && reload_completed"
5062   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5063                                           UNSPEC_ADD_CARRY))
5064               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5065    (parallel [(set (match_dup 3)
5066                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5067                                      (match_dup 4))
5068                             (match_dup 5)))
5069               (clobber (reg:CC FLAGS_REG))])]
5070   "split_ti (operands+0, 1, operands+0, operands+3);
5071    split_ti (operands+1, 1, operands+1, operands+4);
5072    split_ti (operands+2, 1, operands+2, operands+5);")
5073
5074 ;; %%% splits for addsidi3
5075 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5076 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5077 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5078
5079 (define_expand "adddi3"
5080   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5081         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5082                  (match_operand:DI 2 "x86_64_general_operand" "")))
5083    (clobber (reg:CC FLAGS_REG))]
5084   ""
5085   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5086
5087 (define_insn "*adddi3_1"
5088   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5089         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5090                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5091    (clobber (reg:CC FLAGS_REG))]
5092   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5093   "#")
5094
5095 (define_split
5096   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5097         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5098                  (match_operand:DI 2 "general_operand" "")))
5099    (clobber (reg:CC FLAGS_REG))]
5100   "!TARGET_64BIT && reload_completed"
5101   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5102                                           UNSPEC_ADD_CARRY))
5103               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5104    (parallel [(set (match_dup 3)
5105                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5106                                      (match_dup 4))
5107                             (match_dup 5)))
5108               (clobber (reg:CC FLAGS_REG))])]
5109   "split_di (operands+0, 1, operands+0, operands+3);
5110    split_di (operands+1, 1, operands+1, operands+4);
5111    split_di (operands+2, 1, operands+2, operands+5);")
5112
5113 (define_insn "adddi3_carry_rex64"
5114   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5115           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5116                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5117                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5118    (clobber (reg:CC FLAGS_REG))]
5119   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5120   "adc{q}\t{%2, %0|%0, %2}"
5121   [(set_attr "type" "alu")
5122    (set_attr "pent_pair" "pu")
5123    (set_attr "mode" "DI")])
5124
5125 (define_insn "*adddi3_cc_rex64"
5126   [(set (reg:CC FLAGS_REG)
5127         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5128                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5129                    UNSPEC_ADD_CARRY))
5130    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5131         (plus:DI (match_dup 1) (match_dup 2)))]
5132   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5133   "add{q}\t{%2, %0|%0, %2}"
5134   [(set_attr "type" "alu")
5135    (set_attr "mode" "DI")])
5136
5137 (define_insn "addqi3_carry"
5138   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5139           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5140                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5141                    (match_operand:QI 2 "general_operand" "qi,qm")))
5142    (clobber (reg:CC FLAGS_REG))]
5143   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5144   "adc{b}\t{%2, %0|%0, %2}"
5145   [(set_attr "type" "alu")
5146    (set_attr "pent_pair" "pu")
5147    (set_attr "mode" "QI")])
5148
5149 (define_insn "addhi3_carry"
5150   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5151           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5152                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5153                    (match_operand:HI 2 "general_operand" "ri,rm")))
5154    (clobber (reg:CC FLAGS_REG))]
5155   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5156   "adc{w}\t{%2, %0|%0, %2}"
5157   [(set_attr "type" "alu")
5158    (set_attr "pent_pair" "pu")
5159    (set_attr "mode" "HI")])
5160
5161 (define_insn "addsi3_carry"
5162   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5163           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5164                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5165                    (match_operand:SI 2 "general_operand" "ri,rm")))
5166    (clobber (reg:CC FLAGS_REG))]
5167   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5168   "adc{l}\t{%2, %0|%0, %2}"
5169   [(set_attr "type" "alu")
5170    (set_attr "pent_pair" "pu")
5171    (set_attr "mode" "SI")])
5172
5173 (define_insn "*addsi3_carry_zext"
5174   [(set (match_operand:DI 0 "register_operand" "=r")
5175           (zero_extend:DI
5176             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5177                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5178                      (match_operand:SI 2 "general_operand" "rim"))))
5179    (clobber (reg:CC FLAGS_REG))]
5180   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5181   "adc{l}\t{%2, %k0|%k0, %2}"
5182   [(set_attr "type" "alu")
5183    (set_attr "pent_pair" "pu")
5184    (set_attr "mode" "SI")])
5185
5186 (define_insn "*addsi3_cc"
5187   [(set (reg:CC FLAGS_REG)
5188         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5189                     (match_operand:SI 2 "general_operand" "ri,rm")]
5190                    UNSPEC_ADD_CARRY))
5191    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5192         (plus:SI (match_dup 1) (match_dup 2)))]
5193   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5194   "add{l}\t{%2, %0|%0, %2}"
5195   [(set_attr "type" "alu")
5196    (set_attr "mode" "SI")])
5197
5198 (define_insn "addqi3_cc"
5199   [(set (reg:CC FLAGS_REG)
5200         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5201                     (match_operand:QI 2 "general_operand" "qi,qm")]
5202                    UNSPEC_ADD_CARRY))
5203    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5204         (plus:QI (match_dup 1) (match_dup 2)))]
5205   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5206   "add{b}\t{%2, %0|%0, %2}"
5207   [(set_attr "type" "alu")
5208    (set_attr "mode" "QI")])
5209
5210 (define_expand "addsi3"
5211   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5212                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5213                             (match_operand:SI 2 "general_operand" "")))
5214               (clobber (reg:CC FLAGS_REG))])]
5215   ""
5216   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5217
5218 (define_insn "*lea_1"
5219   [(set (match_operand:SI 0 "register_operand" "=r")
5220         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5221   "!TARGET_64BIT"
5222   "lea{l}\t{%a1, %0|%0, %a1}"
5223   [(set_attr "type" "lea")
5224    (set_attr "mode" "SI")])
5225
5226 (define_insn "*lea_1_rex64"
5227   [(set (match_operand:SI 0 "register_operand" "=r")
5228         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5229   "TARGET_64BIT"
5230   "lea{l}\t{%a1, %0|%0, %a1}"
5231   [(set_attr "type" "lea")
5232    (set_attr "mode" "SI")])
5233
5234 (define_insn "*lea_1_zext"
5235   [(set (match_operand:DI 0 "register_operand" "=r")
5236         (zero_extend:DI
5237          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5238   "TARGET_64BIT"
5239   "lea{l}\t{%a1, %k0|%k0, %a1}"
5240   [(set_attr "type" "lea")
5241    (set_attr "mode" "SI")])
5242
5243 (define_insn "*lea_2_rex64"
5244   [(set (match_operand:DI 0 "register_operand" "=r")
5245         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5246   "TARGET_64BIT"
5247   "lea{q}\t{%a1, %0|%0, %a1}"
5248   [(set_attr "type" "lea")
5249    (set_attr "mode" "DI")])
5250
5251 ;; The lea patterns for non-Pmodes needs to be matched by several
5252 ;; insns converted to real lea by splitters.
5253
5254 (define_insn_and_split "*lea_general_1"
5255   [(set (match_operand 0 "register_operand" "=r")
5256         (plus (plus (match_operand 1 "index_register_operand" "l")
5257                     (match_operand 2 "register_operand" "r"))
5258               (match_operand 3 "immediate_operand" "i")))]
5259   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5260     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5261    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5262    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5263    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5264    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5265        || GET_MODE (operands[3]) == VOIDmode)"
5266   "#"
5267   "&& reload_completed"
5268   [(const_int 0)]
5269 {
5270   rtx pat;
5271   operands[0] = gen_lowpart (SImode, operands[0]);
5272   operands[1] = gen_lowpart (Pmode, operands[1]);
5273   operands[2] = gen_lowpart (Pmode, operands[2]);
5274   operands[3] = gen_lowpart (Pmode, operands[3]);
5275   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5276                       operands[3]);
5277   if (Pmode != SImode)
5278     pat = gen_rtx_SUBREG (SImode, pat, 0);
5279   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5280   DONE;
5281 }
5282   [(set_attr "type" "lea")
5283    (set_attr "mode" "SI")])
5284
5285 (define_insn_and_split "*lea_general_1_zext"
5286   [(set (match_operand:DI 0 "register_operand" "=r")
5287         (zero_extend:DI
5288           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5289                             (match_operand:SI 2 "register_operand" "r"))
5290                    (match_operand:SI 3 "immediate_operand" "i"))))]
5291   "TARGET_64BIT"
5292   "#"
5293   "&& reload_completed"
5294   [(set (match_dup 0)
5295         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5296                                                      (match_dup 2))
5297                                             (match_dup 3)) 0)))]
5298 {
5299   operands[1] = gen_lowpart (Pmode, operands[1]);
5300   operands[2] = gen_lowpart (Pmode, operands[2]);
5301   operands[3] = gen_lowpart (Pmode, operands[3]);
5302 }
5303   [(set_attr "type" "lea")
5304    (set_attr "mode" "SI")])
5305
5306 (define_insn_and_split "*lea_general_2"
5307   [(set (match_operand 0 "register_operand" "=r")
5308         (plus (mult (match_operand 1 "index_register_operand" "l")
5309                     (match_operand 2 "const248_operand" "i"))
5310               (match_operand 3 "nonmemory_operand" "ri")))]
5311   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5312     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5313    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5314    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5315    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5316        || GET_MODE (operands[3]) == VOIDmode)"
5317   "#"
5318   "&& reload_completed"
5319   [(const_int 0)]
5320 {
5321   rtx pat;
5322   operands[0] = gen_lowpart (SImode, operands[0]);
5323   operands[1] = gen_lowpart (Pmode, operands[1]);
5324   operands[3] = gen_lowpart (Pmode, operands[3]);
5325   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5326                       operands[3]);
5327   if (Pmode != SImode)
5328     pat = gen_rtx_SUBREG (SImode, pat, 0);
5329   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5330   DONE;
5331 }
5332   [(set_attr "type" "lea")
5333    (set_attr "mode" "SI")])
5334
5335 (define_insn_and_split "*lea_general_2_zext"
5336   [(set (match_operand:DI 0 "register_operand" "=r")
5337         (zero_extend:DI
5338           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5339                             (match_operand:SI 2 "const248_operand" "n"))
5340                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5341   "TARGET_64BIT"
5342   "#"
5343   "&& reload_completed"
5344   [(set (match_dup 0)
5345         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5346                                                      (match_dup 2))
5347                                             (match_dup 3)) 0)))]
5348 {
5349   operands[1] = gen_lowpart (Pmode, operands[1]);
5350   operands[3] = gen_lowpart (Pmode, operands[3]);
5351 }
5352   [(set_attr "type" "lea")
5353    (set_attr "mode" "SI")])
5354
5355 (define_insn_and_split "*lea_general_3"
5356   [(set (match_operand 0 "register_operand" "=r")
5357         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5358                           (match_operand 2 "const248_operand" "i"))
5359                     (match_operand 3 "register_operand" "r"))
5360               (match_operand 4 "immediate_operand" "i")))]
5361   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5362     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5363    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5364    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5365    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5366   "#"
5367   "&& reload_completed"
5368   [(const_int 0)]
5369 {
5370   rtx pat;
5371   operands[0] = gen_lowpart (SImode, operands[0]);
5372   operands[1] = gen_lowpart (Pmode, operands[1]);
5373   operands[3] = gen_lowpart (Pmode, operands[3]);
5374   operands[4] = gen_lowpart (Pmode, operands[4]);
5375   pat = gen_rtx_PLUS (Pmode,
5376                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5377                                                          operands[2]),
5378                                     operands[3]),
5379                       operands[4]);
5380   if (Pmode != SImode)
5381     pat = gen_rtx_SUBREG (SImode, pat, 0);
5382   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5383   DONE;
5384 }
5385   [(set_attr "type" "lea")
5386    (set_attr "mode" "SI")])
5387
5388 (define_insn_and_split "*lea_general_3_zext"
5389   [(set (match_operand:DI 0 "register_operand" "=r")
5390         (zero_extend:DI
5391           (plus:SI (plus:SI (mult:SI
5392                               (match_operand:SI 1 "index_register_operand" "l")
5393                               (match_operand:SI 2 "const248_operand" "n"))
5394                             (match_operand:SI 3 "register_operand" "r"))
5395                    (match_operand:SI 4 "immediate_operand" "i"))))]
5396   "TARGET_64BIT"
5397   "#"
5398   "&& reload_completed"
5399   [(set (match_dup 0)
5400         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5401                                                               (match_dup 2))
5402                                                      (match_dup 3))
5403                                             (match_dup 4)) 0)))]
5404 {
5405   operands[1] = gen_lowpart (Pmode, operands[1]);
5406   operands[3] = gen_lowpart (Pmode, operands[3]);
5407   operands[4] = gen_lowpart (Pmode, operands[4]);
5408 }
5409   [(set_attr "type" "lea")
5410    (set_attr "mode" "SI")])
5411
5412 (define_insn "*adddi_1_rex64"
5413   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5414         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5415                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5416    (clobber (reg:CC FLAGS_REG))]
5417   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5418 {
5419   switch (get_attr_type (insn))
5420     {
5421     case TYPE_LEA:
5422       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5423       return "lea{q}\t{%a2, %0|%0, %a2}";
5424
5425     case TYPE_INCDEC:
5426       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5427       if (operands[2] == const1_rtx)
5428         return "inc{q}\t%0";
5429       else
5430         {
5431           gcc_assert (operands[2] == constm1_rtx);
5432           return "dec{q}\t%0";
5433         }
5434
5435     default:
5436       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5437
5438       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5439          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5440       if (CONST_INT_P (operands[2])
5441           /* Avoid overflows.  */
5442           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5443           && (INTVAL (operands[2]) == 128
5444               || (INTVAL (operands[2]) < 0
5445                   && INTVAL (operands[2]) != -128)))
5446         {
5447           operands[2] = GEN_INT (-INTVAL (operands[2]));
5448           return "sub{q}\t{%2, %0|%0, %2}";
5449         }
5450       return "add{q}\t{%2, %0|%0, %2}";
5451     }
5452 }
5453   [(set (attr "type")
5454      (cond [(eq_attr "alternative" "2")
5455               (const_string "lea")
5456             ; Current assemblers are broken and do not allow @GOTOFF in
5457             ; ought but a memory context.
5458             (match_operand:DI 2 "pic_symbolic_operand" "")
5459               (const_string "lea")
5460             (match_operand:DI 2 "incdec_operand" "")
5461               (const_string "incdec")
5462            ]
5463            (const_string "alu")))
5464    (set_attr "mode" "DI")])
5465
5466 ;; Convert lea to the lea pattern to avoid flags dependency.
5467 (define_split
5468   [(set (match_operand:DI 0 "register_operand" "")
5469         (plus:DI (match_operand:DI 1 "register_operand" "")
5470                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5471    (clobber (reg:CC FLAGS_REG))]
5472   "TARGET_64BIT && reload_completed
5473    && true_regnum (operands[0]) != true_regnum (operands[1])"
5474   [(set (match_dup 0)
5475         (plus:DI (match_dup 1)
5476                  (match_dup 2)))]
5477   "")
5478
5479 (define_insn "*adddi_2_rex64"
5480   [(set (reg FLAGS_REG)
5481         (compare
5482           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5483                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5484           (const_int 0)))
5485    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5486         (plus:DI (match_dup 1) (match_dup 2)))]
5487   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5488    && ix86_binary_operator_ok (PLUS, DImode, operands)
5489    /* Current assemblers are broken and do not allow @GOTOFF in
5490       ought but a memory context.  */
5491    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5492 {
5493   switch (get_attr_type (insn))
5494     {
5495     case TYPE_INCDEC:
5496       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5497       if (operands[2] == const1_rtx)
5498         return "inc{q}\t%0";
5499       else
5500         {
5501           gcc_assert (operands[2] == constm1_rtx);
5502           return "dec{q}\t%0";
5503         }
5504
5505     default:
5506       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5507       /* ???? We ought to handle there the 32bit case too
5508          - do we need new constraint?  */
5509       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5510          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5511       if (CONST_INT_P (operands[2])
5512           /* Avoid overflows.  */
5513           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5514           && (INTVAL (operands[2]) == 128
5515               || (INTVAL (operands[2]) < 0
5516                   && INTVAL (operands[2]) != -128)))
5517         {
5518           operands[2] = GEN_INT (-INTVAL (operands[2]));
5519           return "sub{q}\t{%2, %0|%0, %2}";
5520         }
5521       return "add{q}\t{%2, %0|%0, %2}";
5522     }
5523 }
5524   [(set (attr "type")
5525      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5526         (const_string "incdec")
5527         (const_string "alu")))
5528    (set_attr "mode" "DI")])
5529
5530 (define_insn "*adddi_3_rex64"
5531   [(set (reg FLAGS_REG)
5532         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5533                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5534    (clobber (match_scratch:DI 0 "=r"))]
5535   "TARGET_64BIT
5536    && ix86_match_ccmode (insn, CCZmode)
5537    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5538    /* Current assemblers are broken and do not allow @GOTOFF in
5539       ought but a memory context.  */
5540    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5541 {
5542   switch (get_attr_type (insn))
5543     {
5544     case TYPE_INCDEC:
5545       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5546       if (operands[2] == const1_rtx)
5547         return "inc{q}\t%0";
5548       else
5549         {
5550           gcc_assert (operands[2] == constm1_rtx);
5551           return "dec{q}\t%0";
5552         }
5553
5554     default:
5555       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5556       /* ???? We ought to handle there the 32bit case too
5557          - do we need new constraint?  */
5558       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5559          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5560       if (CONST_INT_P (operands[2])
5561           /* Avoid overflows.  */
5562           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5563           && (INTVAL (operands[2]) == 128
5564               || (INTVAL (operands[2]) < 0
5565                   && INTVAL (operands[2]) != -128)))
5566         {
5567           operands[2] = GEN_INT (-INTVAL (operands[2]));
5568           return "sub{q}\t{%2, %0|%0, %2}";
5569         }
5570       return "add{q}\t{%2, %0|%0, %2}";
5571     }
5572 }
5573   [(set (attr "type")
5574      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5575         (const_string "incdec")
5576         (const_string "alu")))
5577    (set_attr "mode" "DI")])
5578
5579 ; For comparisons against 1, -1 and 128, we may generate better code
5580 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5581 ; is matched then.  We can't accept general immediate, because for
5582 ; case of overflows,  the result is messed up.
5583 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5584 ; when negated.
5585 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5586 ; only for comparisons not depending on it.
5587 (define_insn "*adddi_4_rex64"
5588   [(set (reg FLAGS_REG)
5589         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5590                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5591    (clobber (match_scratch:DI 0 "=rm"))]
5592   "TARGET_64BIT
5593    &&  ix86_match_ccmode (insn, CCGCmode)"
5594 {
5595   switch (get_attr_type (insn))
5596     {
5597     case TYPE_INCDEC:
5598       if (operands[2] == constm1_rtx)
5599         return "inc{q}\t%0";
5600       else
5601         {
5602           gcc_assert (operands[2] == const1_rtx);
5603           return "dec{q}\t%0";
5604         }
5605
5606     default:
5607       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5608       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5609          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5610       if ((INTVAL (operands[2]) == -128
5611            || (INTVAL (operands[2]) > 0
5612                && INTVAL (operands[2]) != 128))
5613           /* Avoid overflows.  */
5614           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5615         return "sub{q}\t{%2, %0|%0, %2}";
5616       operands[2] = GEN_INT (-INTVAL (operands[2]));
5617       return "add{q}\t{%2, %0|%0, %2}";
5618     }
5619 }
5620   [(set (attr "type")
5621      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5622         (const_string "incdec")
5623         (const_string "alu")))
5624    (set_attr "mode" "DI")])
5625
5626 (define_insn "*adddi_5_rex64"
5627   [(set (reg FLAGS_REG)
5628         (compare
5629           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5630                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5631           (const_int 0)))
5632    (clobber (match_scratch:DI 0 "=r"))]
5633   "TARGET_64BIT
5634    && ix86_match_ccmode (insn, CCGOCmode)
5635    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5636    /* Current assemblers are broken and do not allow @GOTOFF in
5637       ought but a memory context.  */
5638    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5639 {
5640   switch (get_attr_type (insn))
5641     {
5642     case TYPE_INCDEC:
5643       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5644       if (operands[2] == const1_rtx)
5645         return "inc{q}\t%0";
5646       else
5647         {
5648           gcc_assert (operands[2] == constm1_rtx);
5649           return "dec{q}\t%0";
5650         }
5651
5652     default:
5653       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5654       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5655          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5656       if (CONST_INT_P (operands[2])
5657           /* Avoid overflows.  */
5658           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5659           && (INTVAL (operands[2]) == 128
5660               || (INTVAL (operands[2]) < 0
5661                   && INTVAL (operands[2]) != -128)))
5662         {
5663           operands[2] = GEN_INT (-INTVAL (operands[2]));
5664           return "sub{q}\t{%2, %0|%0, %2}";
5665         }
5666       return "add{q}\t{%2, %0|%0, %2}";
5667     }
5668 }
5669   [(set (attr "type")
5670      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5671         (const_string "incdec")
5672         (const_string "alu")))
5673    (set_attr "mode" "DI")])
5674
5675
5676 (define_insn "*addsi_1"
5677   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5678         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5679                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5680    (clobber (reg:CC FLAGS_REG))]
5681   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5682 {
5683   switch (get_attr_type (insn))
5684     {
5685     case TYPE_LEA:
5686       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5687       return "lea{l}\t{%a2, %0|%0, %a2}";
5688
5689     case TYPE_INCDEC:
5690       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5691       if (operands[2] == const1_rtx)
5692         return "inc{l}\t%0";
5693       else
5694         {
5695           gcc_assert (operands[2] == constm1_rtx);
5696           return "dec{l}\t%0";
5697         }
5698
5699     default:
5700       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5701
5702       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5703          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5704       if (CONST_INT_P (operands[2])
5705           && (INTVAL (operands[2]) == 128
5706               || (INTVAL (operands[2]) < 0
5707                   && INTVAL (operands[2]) != -128)))
5708         {
5709           operands[2] = GEN_INT (-INTVAL (operands[2]));
5710           return "sub{l}\t{%2, %0|%0, %2}";
5711         }
5712       return "add{l}\t{%2, %0|%0, %2}";
5713     }
5714 }
5715   [(set (attr "type")
5716      (cond [(eq_attr "alternative" "2")
5717               (const_string "lea")
5718             ; Current assemblers are broken and do not allow @GOTOFF in
5719             ; ought but a memory context.
5720             (match_operand:SI 2 "pic_symbolic_operand" "")
5721               (const_string "lea")
5722             (match_operand:SI 2 "incdec_operand" "")
5723               (const_string "incdec")
5724            ]
5725            (const_string "alu")))
5726    (set_attr "mode" "SI")])
5727
5728 ;; Convert lea to the lea pattern to avoid flags dependency.
5729 (define_split
5730   [(set (match_operand 0 "register_operand" "")
5731         (plus (match_operand 1 "register_operand" "")
5732               (match_operand 2 "nonmemory_operand" "")))
5733    (clobber (reg:CC FLAGS_REG))]
5734   "reload_completed
5735    && true_regnum (operands[0]) != true_regnum (operands[1])"
5736   [(const_int 0)]
5737 {
5738   rtx pat;
5739   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5740      may confuse gen_lowpart.  */
5741   if (GET_MODE (operands[0]) != Pmode)
5742     {
5743       operands[1] = gen_lowpart (Pmode, operands[1]);
5744       operands[2] = gen_lowpart (Pmode, operands[2]);
5745     }
5746   operands[0] = gen_lowpart (SImode, operands[0]);
5747   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5748   if (Pmode != SImode)
5749     pat = gen_rtx_SUBREG (SImode, pat, 0);
5750   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5751   DONE;
5752 })
5753
5754 ;; It may seem that nonimmediate operand is proper one for operand 1.
5755 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5756 ;; we take care in ix86_binary_operator_ok to not allow two memory
5757 ;; operands so proper swapping will be done in reload.  This allow
5758 ;; patterns constructed from addsi_1 to match.
5759 (define_insn "addsi_1_zext"
5760   [(set (match_operand:DI 0 "register_operand" "=r,r")
5761         (zero_extend:DI
5762           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5763                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5764    (clobber (reg:CC FLAGS_REG))]
5765   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5766 {
5767   switch (get_attr_type (insn))
5768     {
5769     case TYPE_LEA:
5770       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5771       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5772
5773     case TYPE_INCDEC:
5774       if (operands[2] == const1_rtx)
5775         return "inc{l}\t%k0";
5776       else
5777         {
5778           gcc_assert (operands[2] == constm1_rtx);
5779           return "dec{l}\t%k0";
5780         }
5781
5782     default:
5783       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5784          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5785       if (CONST_INT_P (operands[2])
5786           && (INTVAL (operands[2]) == 128
5787               || (INTVAL (operands[2]) < 0
5788                   && INTVAL (operands[2]) != -128)))
5789         {
5790           operands[2] = GEN_INT (-INTVAL (operands[2]));
5791           return "sub{l}\t{%2, %k0|%k0, %2}";
5792         }
5793       return "add{l}\t{%2, %k0|%k0, %2}";
5794     }
5795 }
5796   [(set (attr "type")
5797      (cond [(eq_attr "alternative" "1")
5798               (const_string "lea")
5799             ; Current assemblers are broken and do not allow @GOTOFF in
5800             ; ought but a memory context.
5801             (match_operand:SI 2 "pic_symbolic_operand" "")
5802               (const_string "lea")
5803             (match_operand:SI 2 "incdec_operand" "")
5804               (const_string "incdec")
5805            ]
5806            (const_string "alu")))
5807    (set_attr "mode" "SI")])
5808
5809 ;; Convert lea to the lea pattern to avoid flags dependency.
5810 (define_split
5811   [(set (match_operand:DI 0 "register_operand" "")
5812         (zero_extend:DI
5813           (plus:SI (match_operand:SI 1 "register_operand" "")
5814                    (match_operand:SI 2 "nonmemory_operand" ""))))
5815    (clobber (reg:CC FLAGS_REG))]
5816   "TARGET_64BIT && reload_completed
5817    && true_regnum (operands[0]) != true_regnum (operands[1])"
5818   [(set (match_dup 0)
5819         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5820 {
5821   operands[1] = gen_lowpart (Pmode, operands[1]);
5822   operands[2] = gen_lowpart (Pmode, operands[2]);
5823 })
5824
5825 (define_insn "*addsi_2"
5826   [(set (reg FLAGS_REG)
5827         (compare
5828           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5829                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5830           (const_int 0)))
5831    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5832         (plus:SI (match_dup 1) (match_dup 2)))]
5833   "ix86_match_ccmode (insn, CCGOCmode)
5834    && ix86_binary_operator_ok (PLUS, SImode, operands)
5835    /* Current assemblers are broken and do not allow @GOTOFF in
5836       ought but a memory context.  */
5837    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5838 {
5839   switch (get_attr_type (insn))
5840     {
5841     case TYPE_INCDEC:
5842       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5843       if (operands[2] == const1_rtx)
5844         return "inc{l}\t%0";
5845       else
5846         {
5847           gcc_assert (operands[2] == constm1_rtx);
5848           return "dec{l}\t%0";
5849         }
5850
5851     default:
5852       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5853       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5854          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5855       if (CONST_INT_P (operands[2])
5856           && (INTVAL (operands[2]) == 128
5857               || (INTVAL (operands[2]) < 0
5858                   && INTVAL (operands[2]) != -128)))
5859         {
5860           operands[2] = GEN_INT (-INTVAL (operands[2]));
5861           return "sub{l}\t{%2, %0|%0, %2}";
5862         }
5863       return "add{l}\t{%2, %0|%0, %2}";
5864     }
5865 }
5866   [(set (attr "type")
5867      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5868         (const_string "incdec")
5869         (const_string "alu")))
5870    (set_attr "mode" "SI")])
5871
5872 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5873 (define_insn "*addsi_2_zext"
5874   [(set (reg FLAGS_REG)
5875         (compare
5876           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5877                    (match_operand:SI 2 "general_operand" "rmni"))
5878           (const_int 0)))
5879    (set (match_operand:DI 0 "register_operand" "=r")
5880         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5881   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5882    && ix86_binary_operator_ok (PLUS, SImode, operands)
5883    /* Current assemblers are broken and do not allow @GOTOFF in
5884       ought but a memory context.  */
5885    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5886 {
5887   switch (get_attr_type (insn))
5888     {
5889     case TYPE_INCDEC:
5890       if (operands[2] == const1_rtx)
5891         return "inc{l}\t%k0";
5892       else
5893         {
5894           gcc_assert (operands[2] == constm1_rtx);
5895           return "dec{l}\t%k0";
5896         }
5897
5898     default:
5899       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5900          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5901       if (CONST_INT_P (operands[2])
5902           && (INTVAL (operands[2]) == 128
5903               || (INTVAL (operands[2]) < 0
5904                   && INTVAL (operands[2]) != -128)))
5905         {
5906           operands[2] = GEN_INT (-INTVAL (operands[2]));
5907           return "sub{l}\t{%2, %k0|%k0, %2}";
5908         }
5909       return "add{l}\t{%2, %k0|%k0, %2}";
5910     }
5911 }
5912   [(set (attr "type")
5913      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5914         (const_string "incdec")
5915         (const_string "alu")))
5916    (set_attr "mode" "SI")])
5917
5918 (define_insn "*addsi_3"
5919   [(set (reg FLAGS_REG)
5920         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5921                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5922    (clobber (match_scratch:SI 0 "=r"))]
5923   "ix86_match_ccmode (insn, CCZmode)
5924    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5925    /* Current assemblers are broken and do not allow @GOTOFF in
5926       ought but a memory context.  */
5927    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5928 {
5929   switch (get_attr_type (insn))
5930     {
5931     case TYPE_INCDEC:
5932       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5933       if (operands[2] == const1_rtx)
5934         return "inc{l}\t%0";
5935       else
5936         {
5937           gcc_assert (operands[2] == constm1_rtx);
5938           return "dec{l}\t%0";
5939         }
5940
5941     default:
5942       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5943       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5944          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5945       if (CONST_INT_P (operands[2])
5946           && (INTVAL (operands[2]) == 128
5947               || (INTVAL (operands[2]) < 0
5948                   && INTVAL (operands[2]) != -128)))
5949         {
5950           operands[2] = GEN_INT (-INTVAL (operands[2]));
5951           return "sub{l}\t{%2, %0|%0, %2}";
5952         }
5953       return "add{l}\t{%2, %0|%0, %2}";
5954     }
5955 }
5956   [(set (attr "type")
5957      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5958         (const_string "incdec")
5959         (const_string "alu")))
5960    (set_attr "mode" "SI")])
5961
5962 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5963 (define_insn "*addsi_3_zext"
5964   [(set (reg FLAGS_REG)
5965         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5966                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5967    (set (match_operand:DI 0 "register_operand" "=r")
5968         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5969   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5970    && ix86_binary_operator_ok (PLUS, SImode, operands)
5971    /* Current assemblers are broken and do not allow @GOTOFF in
5972       ought but a memory context.  */
5973    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5974 {
5975   switch (get_attr_type (insn))
5976     {
5977     case TYPE_INCDEC:
5978       if (operands[2] == const1_rtx)
5979         return "inc{l}\t%k0";
5980       else
5981         {
5982           gcc_assert (operands[2] == constm1_rtx);
5983           return "dec{l}\t%k0";
5984         }
5985
5986     default:
5987       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5988          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5989       if (CONST_INT_P (operands[2])
5990           && (INTVAL (operands[2]) == 128
5991               || (INTVAL (operands[2]) < 0
5992                   && INTVAL (operands[2]) != -128)))
5993         {
5994           operands[2] = GEN_INT (-INTVAL (operands[2]));
5995           return "sub{l}\t{%2, %k0|%k0, %2}";
5996         }
5997       return "add{l}\t{%2, %k0|%k0, %2}";
5998     }
5999 }
6000   [(set (attr "type")
6001      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6002         (const_string "incdec")
6003         (const_string "alu")))
6004    (set_attr "mode" "SI")])
6005
6006 ; For comparisons against 1, -1 and 128, we may generate better code
6007 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6008 ; is matched then.  We can't accept general immediate, because for
6009 ; case of overflows,  the result is messed up.
6010 ; This pattern also don't hold of 0x80000000, since the value overflows
6011 ; when negated.
6012 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6013 ; only for comparisons not depending on it.
6014 (define_insn "*addsi_4"
6015   [(set (reg FLAGS_REG)
6016         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6017                  (match_operand:SI 2 "const_int_operand" "n")))
6018    (clobber (match_scratch:SI 0 "=rm"))]
6019   "ix86_match_ccmode (insn, CCGCmode)
6020    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6021 {
6022   switch (get_attr_type (insn))
6023     {
6024     case TYPE_INCDEC:
6025       if (operands[2] == constm1_rtx)
6026         return "inc{l}\t%0";
6027       else
6028         {
6029           gcc_assert (operands[2] == const1_rtx);
6030           return "dec{l}\t%0";
6031         }
6032
6033     default:
6034       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6035       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6036          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6037       if ((INTVAL (operands[2]) == -128
6038            || (INTVAL (operands[2]) > 0
6039                && INTVAL (operands[2]) != 128)))
6040         return "sub{l}\t{%2, %0|%0, %2}";
6041       operands[2] = GEN_INT (-INTVAL (operands[2]));
6042       return "add{l}\t{%2, %0|%0, %2}";
6043     }
6044 }
6045   [(set (attr "type")
6046      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6047         (const_string "incdec")
6048         (const_string "alu")))
6049    (set_attr "mode" "SI")])
6050
6051 (define_insn "*addsi_5"
6052   [(set (reg FLAGS_REG)
6053         (compare
6054           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6055                    (match_operand:SI 2 "general_operand" "rmni"))
6056           (const_int 0)))
6057    (clobber (match_scratch:SI 0 "=r"))]
6058   "ix86_match_ccmode (insn, CCGOCmode)
6059    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6060    /* Current assemblers are broken and do not allow @GOTOFF in
6061       ought but a memory context.  */
6062    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6063 {
6064   switch (get_attr_type (insn))
6065     {
6066     case TYPE_INCDEC:
6067       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6068       if (operands[2] == const1_rtx)
6069         return "inc{l}\t%0";
6070       else
6071         {
6072           gcc_assert (operands[2] == constm1_rtx);
6073           return "dec{l}\t%0";
6074         }
6075
6076     default:
6077       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6078       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6079          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6080       if (CONST_INT_P (operands[2])
6081           && (INTVAL (operands[2]) == 128
6082               || (INTVAL (operands[2]) < 0
6083                   && INTVAL (operands[2]) != -128)))
6084         {
6085           operands[2] = GEN_INT (-INTVAL (operands[2]));
6086           return "sub{l}\t{%2, %0|%0, %2}";
6087         }
6088       return "add{l}\t{%2, %0|%0, %2}";
6089     }
6090 }
6091   [(set (attr "type")
6092      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6093         (const_string "incdec")
6094         (const_string "alu")))
6095    (set_attr "mode" "SI")])
6096
6097 (define_expand "addhi3"
6098   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6099                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6100                             (match_operand:HI 2 "general_operand" "")))
6101               (clobber (reg:CC FLAGS_REG))])]
6102   "TARGET_HIMODE_MATH"
6103   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6104
6105 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6106 ;; type optimizations enabled by define-splits.  This is not important
6107 ;; for PII, and in fact harmful because of partial register stalls.
6108
6109 (define_insn "*addhi_1_lea"
6110   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6111         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6112                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6113    (clobber (reg:CC FLAGS_REG))]
6114   "!TARGET_PARTIAL_REG_STALL
6115    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6116 {
6117   switch (get_attr_type (insn))
6118     {
6119     case TYPE_LEA:
6120       return "#";
6121     case TYPE_INCDEC:
6122       if (operands[2] == const1_rtx)
6123         return "inc{w}\t%0";
6124       else
6125         {
6126           gcc_assert (operands[2] == constm1_rtx);
6127           return "dec{w}\t%0";
6128         }
6129
6130     default:
6131       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6132          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6133       if (CONST_INT_P (operands[2])
6134           && (INTVAL (operands[2]) == 128
6135               || (INTVAL (operands[2]) < 0
6136                   && INTVAL (operands[2]) != -128)))
6137         {
6138           operands[2] = GEN_INT (-INTVAL (operands[2]));
6139           return "sub{w}\t{%2, %0|%0, %2}";
6140         }
6141       return "add{w}\t{%2, %0|%0, %2}";
6142     }
6143 }
6144   [(set (attr "type")
6145      (if_then_else (eq_attr "alternative" "2")
6146         (const_string "lea")
6147         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6148            (const_string "incdec")
6149            (const_string "alu"))))
6150    (set_attr "mode" "HI,HI,SI")])
6151
6152 (define_insn "*addhi_1"
6153   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6154         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6155                  (match_operand:HI 2 "general_operand" "ri,rm")))
6156    (clobber (reg:CC FLAGS_REG))]
6157   "TARGET_PARTIAL_REG_STALL
6158    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6159 {
6160   switch (get_attr_type (insn))
6161     {
6162     case TYPE_INCDEC:
6163       if (operands[2] == const1_rtx)
6164         return "inc{w}\t%0";
6165       else
6166         {
6167           gcc_assert (operands[2] == constm1_rtx);
6168           return "dec{w}\t%0";
6169         }
6170
6171     default:
6172       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6173          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6174       if (CONST_INT_P (operands[2])
6175           && (INTVAL (operands[2]) == 128
6176               || (INTVAL (operands[2]) < 0
6177                   && INTVAL (operands[2]) != -128)))
6178         {
6179           operands[2] = GEN_INT (-INTVAL (operands[2]));
6180           return "sub{w}\t{%2, %0|%0, %2}";
6181         }
6182       return "add{w}\t{%2, %0|%0, %2}";
6183     }
6184 }
6185   [(set (attr "type")
6186      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6187         (const_string "incdec")
6188         (const_string "alu")))
6189    (set_attr "mode" "HI")])
6190
6191 (define_insn "*addhi_2"
6192   [(set (reg FLAGS_REG)
6193         (compare
6194           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6195                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6196           (const_int 0)))
6197    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6198         (plus:HI (match_dup 1) (match_dup 2)))]
6199   "ix86_match_ccmode (insn, CCGOCmode)
6200    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6201 {
6202   switch (get_attr_type (insn))
6203     {
6204     case TYPE_INCDEC:
6205       if (operands[2] == const1_rtx)
6206         return "inc{w}\t%0";
6207       else
6208         {
6209           gcc_assert (operands[2] == constm1_rtx);
6210           return "dec{w}\t%0";
6211         }
6212
6213     default:
6214       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6215          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6216       if (CONST_INT_P (operands[2])
6217           && (INTVAL (operands[2]) == 128
6218               || (INTVAL (operands[2]) < 0
6219                   && INTVAL (operands[2]) != -128)))
6220         {
6221           operands[2] = GEN_INT (-INTVAL (operands[2]));
6222           return "sub{w}\t{%2, %0|%0, %2}";
6223         }
6224       return "add{w}\t{%2, %0|%0, %2}";
6225     }
6226 }
6227   [(set (attr "type")
6228      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6229         (const_string "incdec")
6230         (const_string "alu")))
6231    (set_attr "mode" "HI")])
6232
6233 (define_insn "*addhi_3"
6234   [(set (reg FLAGS_REG)
6235         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6236                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6237    (clobber (match_scratch:HI 0 "=r"))]
6238   "ix86_match_ccmode (insn, CCZmode)
6239    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6240 {
6241   switch (get_attr_type (insn))
6242     {
6243     case TYPE_INCDEC:
6244       if (operands[2] == const1_rtx)
6245         return "inc{w}\t%0";
6246       else
6247         {
6248           gcc_assert (operands[2] == constm1_rtx);
6249           return "dec{w}\t%0";
6250         }
6251
6252     default:
6253       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6254          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6255       if (CONST_INT_P (operands[2])
6256           && (INTVAL (operands[2]) == 128
6257               || (INTVAL (operands[2]) < 0
6258                   && INTVAL (operands[2]) != -128)))
6259         {
6260           operands[2] = GEN_INT (-INTVAL (operands[2]));
6261           return "sub{w}\t{%2, %0|%0, %2}";
6262         }
6263       return "add{w}\t{%2, %0|%0, %2}";
6264     }
6265 }
6266   [(set (attr "type")
6267      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6268         (const_string "incdec")
6269         (const_string "alu")))
6270    (set_attr "mode" "HI")])
6271
6272 ; See comments above addsi_4 for details.
6273 (define_insn "*addhi_4"
6274   [(set (reg FLAGS_REG)
6275         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6276                  (match_operand:HI 2 "const_int_operand" "n")))
6277    (clobber (match_scratch:HI 0 "=rm"))]
6278   "ix86_match_ccmode (insn, CCGCmode)
6279    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6280 {
6281   switch (get_attr_type (insn))
6282     {
6283     case TYPE_INCDEC:
6284       if (operands[2] == constm1_rtx)
6285         return "inc{w}\t%0";
6286       else
6287         {
6288           gcc_assert (operands[2] == const1_rtx);
6289           return "dec{w}\t%0";
6290         }
6291
6292     default:
6293       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6294       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6295          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6296       if ((INTVAL (operands[2]) == -128
6297            || (INTVAL (operands[2]) > 0
6298                && INTVAL (operands[2]) != 128)))
6299         return "sub{w}\t{%2, %0|%0, %2}";
6300       operands[2] = GEN_INT (-INTVAL (operands[2]));
6301       return "add{w}\t{%2, %0|%0, %2}";
6302     }
6303 }
6304   [(set (attr "type")
6305      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6306         (const_string "incdec")
6307         (const_string "alu")))
6308    (set_attr "mode" "SI")])
6309
6310
6311 (define_insn "*addhi_5"
6312   [(set (reg FLAGS_REG)
6313         (compare
6314           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6315                    (match_operand:HI 2 "general_operand" "rmni"))
6316           (const_int 0)))
6317    (clobber (match_scratch:HI 0 "=r"))]
6318   "ix86_match_ccmode (insn, CCGOCmode)
6319    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6320 {
6321   switch (get_attr_type (insn))
6322     {
6323     case TYPE_INCDEC:
6324       if (operands[2] == const1_rtx)
6325         return "inc{w}\t%0";
6326       else
6327         {
6328           gcc_assert (operands[2] == constm1_rtx);
6329           return "dec{w}\t%0";
6330         }
6331
6332     default:
6333       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6334          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6335       if (CONST_INT_P (operands[2])
6336           && (INTVAL (operands[2]) == 128
6337               || (INTVAL (operands[2]) < 0
6338                   && INTVAL (operands[2]) != -128)))
6339         {
6340           operands[2] = GEN_INT (-INTVAL (operands[2]));
6341           return "sub{w}\t{%2, %0|%0, %2}";
6342         }
6343       return "add{w}\t{%2, %0|%0, %2}";
6344     }
6345 }
6346   [(set (attr "type")
6347      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6348         (const_string "incdec")
6349         (const_string "alu")))
6350    (set_attr "mode" "HI")])
6351
6352 (define_expand "addqi3"
6353   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6354                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6355                             (match_operand:QI 2 "general_operand" "")))
6356               (clobber (reg:CC FLAGS_REG))])]
6357   "TARGET_QIMODE_MATH"
6358   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6359
6360 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6361 (define_insn "*addqi_1_lea"
6362   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6363         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6364                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6365    (clobber (reg:CC FLAGS_REG))]
6366   "!TARGET_PARTIAL_REG_STALL
6367    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6368 {
6369   int widen = (which_alternative == 2);
6370   switch (get_attr_type (insn))
6371     {
6372     case TYPE_LEA:
6373       return "#";
6374     case TYPE_INCDEC:
6375       if (operands[2] == const1_rtx)
6376         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6377       else
6378         {
6379           gcc_assert (operands[2] == constm1_rtx);
6380           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6381         }
6382
6383     default:
6384       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6385          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6386       if (CONST_INT_P (operands[2])
6387           && (INTVAL (operands[2]) == 128
6388               || (INTVAL (operands[2]) < 0
6389                   && INTVAL (operands[2]) != -128)))
6390         {
6391           operands[2] = GEN_INT (-INTVAL (operands[2]));
6392           if (widen)
6393             return "sub{l}\t{%2, %k0|%k0, %2}";
6394           else
6395             return "sub{b}\t{%2, %0|%0, %2}";
6396         }
6397       if (widen)
6398         return "add{l}\t{%k2, %k0|%k0, %k2}";
6399       else
6400         return "add{b}\t{%2, %0|%0, %2}";
6401     }
6402 }
6403   [(set (attr "type")
6404      (if_then_else (eq_attr "alternative" "3")
6405         (const_string "lea")
6406         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6407            (const_string "incdec")
6408            (const_string "alu"))))
6409    (set_attr "mode" "QI,QI,SI,SI")])
6410
6411 (define_insn "*addqi_1"
6412   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6413         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6414                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6415    (clobber (reg:CC FLAGS_REG))]
6416   "TARGET_PARTIAL_REG_STALL
6417    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6418 {
6419   int widen = (which_alternative == 2);
6420   switch (get_attr_type (insn))
6421     {
6422     case TYPE_INCDEC:
6423       if (operands[2] == const1_rtx)
6424         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6425       else
6426         {
6427           gcc_assert (operands[2] == constm1_rtx);
6428           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6429         }
6430
6431     default:
6432       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6433          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6434       if (CONST_INT_P (operands[2])
6435           && (INTVAL (operands[2]) == 128
6436               || (INTVAL (operands[2]) < 0
6437                   && INTVAL (operands[2]) != -128)))
6438         {
6439           operands[2] = GEN_INT (-INTVAL (operands[2]));
6440           if (widen)
6441             return "sub{l}\t{%2, %k0|%k0, %2}";
6442           else
6443             return "sub{b}\t{%2, %0|%0, %2}";
6444         }
6445       if (widen)
6446         return "add{l}\t{%k2, %k0|%k0, %k2}";
6447       else
6448         return "add{b}\t{%2, %0|%0, %2}";
6449     }
6450 }
6451   [(set (attr "type")
6452      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6453         (const_string "incdec")
6454         (const_string "alu")))
6455    (set_attr "mode" "QI,QI,SI")])
6456
6457 (define_insn "*addqi_1_slp"
6458   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6459         (plus:QI (match_dup 0)
6460                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6461    (clobber (reg:CC FLAGS_REG))]
6462   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6463    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6464 {
6465   switch (get_attr_type (insn))
6466     {
6467     case TYPE_INCDEC:
6468       if (operands[1] == const1_rtx)
6469         return "inc{b}\t%0";
6470       else
6471         {
6472           gcc_assert (operands[1] == constm1_rtx);
6473           return "dec{b}\t%0";
6474         }
6475
6476     default:
6477       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6478       if (CONST_INT_P (operands[1])
6479           && INTVAL (operands[1]) < 0)
6480         {
6481           operands[1] = GEN_INT (-INTVAL (operands[1]));
6482           return "sub{b}\t{%1, %0|%0, %1}";
6483         }
6484       return "add{b}\t{%1, %0|%0, %1}";
6485     }
6486 }
6487   [(set (attr "type")
6488      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6489         (const_string "incdec")
6490         (const_string "alu1")))
6491    (set (attr "memory")
6492      (if_then_else (match_operand 1 "memory_operand" "")
6493         (const_string "load")
6494         (const_string "none")))
6495    (set_attr "mode" "QI")])
6496
6497 (define_insn "*addqi_2"
6498   [(set (reg FLAGS_REG)
6499         (compare
6500           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6501                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6502           (const_int 0)))
6503    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6504         (plus:QI (match_dup 1) (match_dup 2)))]
6505   "ix86_match_ccmode (insn, CCGOCmode)
6506    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6507 {
6508   switch (get_attr_type (insn))
6509     {
6510     case TYPE_INCDEC:
6511       if (operands[2] == const1_rtx)
6512         return "inc{b}\t%0";
6513       else
6514         {
6515           gcc_assert (operands[2] == constm1_rtx
6516                       || (CONST_INT_P (operands[2])
6517                           && INTVAL (operands[2]) == 255));
6518           return "dec{b}\t%0";
6519         }
6520
6521     default:
6522       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6523       if (CONST_INT_P (operands[2])
6524           && INTVAL (operands[2]) < 0)
6525         {
6526           operands[2] = GEN_INT (-INTVAL (operands[2]));
6527           return "sub{b}\t{%2, %0|%0, %2}";
6528         }
6529       return "add{b}\t{%2, %0|%0, %2}";
6530     }
6531 }
6532   [(set (attr "type")
6533      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6534         (const_string "incdec")
6535         (const_string "alu")))
6536    (set_attr "mode" "QI")])
6537
6538 (define_insn "*addqi_3"
6539   [(set (reg FLAGS_REG)
6540         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6541                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6542    (clobber (match_scratch:QI 0 "=q"))]
6543   "ix86_match_ccmode (insn, CCZmode)
6544    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6545 {
6546   switch (get_attr_type (insn))
6547     {
6548     case TYPE_INCDEC:
6549       if (operands[2] == const1_rtx)
6550         return "inc{b}\t%0";
6551       else
6552         {
6553           gcc_assert (operands[2] == constm1_rtx
6554                       || (CONST_INT_P (operands[2])
6555                           && INTVAL (operands[2]) == 255));
6556           return "dec{b}\t%0";
6557         }
6558
6559     default:
6560       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6561       if (CONST_INT_P (operands[2])
6562           && INTVAL (operands[2]) < 0)
6563         {
6564           operands[2] = GEN_INT (-INTVAL (operands[2]));
6565           return "sub{b}\t{%2, %0|%0, %2}";
6566         }
6567       return "add{b}\t{%2, %0|%0, %2}";
6568     }
6569 }
6570   [(set (attr "type")
6571      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6572         (const_string "incdec")
6573         (const_string "alu")))
6574    (set_attr "mode" "QI")])
6575
6576 ; See comments above addsi_4 for details.
6577 (define_insn "*addqi_4"
6578   [(set (reg FLAGS_REG)
6579         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6580                  (match_operand:QI 2 "const_int_operand" "n")))
6581    (clobber (match_scratch:QI 0 "=qm"))]
6582   "ix86_match_ccmode (insn, CCGCmode)
6583    && (INTVAL (operands[2]) & 0xff) != 0x80"
6584 {
6585   switch (get_attr_type (insn))
6586     {
6587     case TYPE_INCDEC:
6588       if (operands[2] == constm1_rtx
6589           || (CONST_INT_P (operands[2])
6590               && INTVAL (operands[2]) == 255))
6591         return "inc{b}\t%0";
6592       else
6593         {
6594           gcc_assert (operands[2] == const1_rtx);
6595           return "dec{b}\t%0";
6596         }
6597
6598     default:
6599       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6600       if (INTVAL (operands[2]) < 0)
6601         {
6602           operands[2] = GEN_INT (-INTVAL (operands[2]));
6603           return "add{b}\t{%2, %0|%0, %2}";
6604         }
6605       return "sub{b}\t{%2, %0|%0, %2}";
6606     }
6607 }
6608   [(set (attr "type")
6609      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6610         (const_string "incdec")
6611         (const_string "alu")))
6612    (set_attr "mode" "QI")])
6613
6614
6615 (define_insn "*addqi_5"
6616   [(set (reg FLAGS_REG)
6617         (compare
6618           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6619                    (match_operand:QI 2 "general_operand" "qmni"))
6620           (const_int 0)))
6621    (clobber (match_scratch:QI 0 "=q"))]
6622   "ix86_match_ccmode (insn, CCGOCmode)
6623    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6624 {
6625   switch (get_attr_type (insn))
6626     {
6627     case TYPE_INCDEC:
6628       if (operands[2] == const1_rtx)
6629         return "inc{b}\t%0";
6630       else
6631         {
6632           gcc_assert (operands[2] == constm1_rtx
6633                       || (CONST_INT_P (operands[2])
6634                           && INTVAL (operands[2]) == 255));
6635           return "dec{b}\t%0";
6636         }
6637
6638     default:
6639       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6640       if (CONST_INT_P (operands[2])
6641           && INTVAL (operands[2]) < 0)
6642         {
6643           operands[2] = GEN_INT (-INTVAL (operands[2]));
6644           return "sub{b}\t{%2, %0|%0, %2}";
6645         }
6646       return "add{b}\t{%2, %0|%0, %2}";
6647     }
6648 }
6649   [(set (attr "type")
6650      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6651         (const_string "incdec")
6652         (const_string "alu")))
6653    (set_attr "mode" "QI")])
6654
6655
6656 (define_insn "addqi_ext_1"
6657   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6658                          (const_int 8)
6659                          (const_int 8))
6660         (plus:SI
6661           (zero_extract:SI
6662             (match_operand 1 "ext_register_operand" "0")
6663             (const_int 8)
6664             (const_int 8))
6665           (match_operand:QI 2 "general_operand" "Qmn")))
6666    (clobber (reg:CC FLAGS_REG))]
6667   "!TARGET_64BIT"
6668 {
6669   switch (get_attr_type (insn))
6670     {
6671     case TYPE_INCDEC:
6672       if (operands[2] == const1_rtx)
6673         return "inc{b}\t%h0";
6674       else
6675         {
6676           gcc_assert (operands[2] == constm1_rtx
6677                       || (CONST_INT_P (operands[2])
6678                           && INTVAL (operands[2]) == 255));
6679           return "dec{b}\t%h0";
6680         }
6681
6682     default:
6683       return "add{b}\t{%2, %h0|%h0, %2}";
6684     }
6685 }
6686   [(set (attr "type")
6687      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6688         (const_string "incdec")
6689         (const_string "alu")))
6690    (set_attr "mode" "QI")])
6691
6692 (define_insn "*addqi_ext_1_rex64"
6693   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6694                          (const_int 8)
6695                          (const_int 8))
6696         (plus:SI
6697           (zero_extract:SI
6698             (match_operand 1 "ext_register_operand" "0")
6699             (const_int 8)
6700             (const_int 8))
6701           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6702    (clobber (reg:CC FLAGS_REG))]
6703   "TARGET_64BIT"
6704 {
6705   switch (get_attr_type (insn))
6706     {
6707     case TYPE_INCDEC:
6708       if (operands[2] == const1_rtx)
6709         return "inc{b}\t%h0";
6710       else
6711         {
6712           gcc_assert (operands[2] == constm1_rtx
6713                       || (CONST_INT_P (operands[2])
6714                           && INTVAL (operands[2]) == 255));
6715           return "dec{b}\t%h0";
6716         }
6717
6718     default:
6719       return "add{b}\t{%2, %h0|%h0, %2}";
6720     }
6721 }
6722   [(set (attr "type")
6723      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6724         (const_string "incdec")
6725         (const_string "alu")))
6726    (set_attr "mode" "QI")])
6727
6728 (define_insn "*addqi_ext_2"
6729   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6730                          (const_int 8)
6731                          (const_int 8))
6732         (plus:SI
6733           (zero_extract:SI
6734             (match_operand 1 "ext_register_operand" "%0")
6735             (const_int 8)
6736             (const_int 8))
6737           (zero_extract:SI
6738             (match_operand 2 "ext_register_operand" "Q")
6739             (const_int 8)
6740             (const_int 8))))
6741    (clobber (reg:CC FLAGS_REG))]
6742   ""
6743   "add{b}\t{%h2, %h0|%h0, %h2}"
6744   [(set_attr "type" "alu")
6745    (set_attr "mode" "QI")])
6746
6747 ;; The patterns that match these are at the end of this file.
6748
6749 (define_expand "addxf3"
6750   [(set (match_operand:XF 0 "register_operand" "")
6751         (plus:XF (match_operand:XF 1 "register_operand" "")
6752                  (match_operand:XF 2 "register_operand" "")))]
6753   "TARGET_80387"
6754   "")
6755
6756 (define_expand "adddf3"
6757   [(set (match_operand:DF 0 "register_operand" "")
6758         (plus:DF (match_operand:DF 1 "register_operand" "")
6759                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6760   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6761   "")
6762
6763 (define_expand "addsf3"
6764   [(set (match_operand:SF 0 "register_operand" "")
6765         (plus:SF (match_operand:SF 1 "register_operand" "")
6766                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6767   "TARGET_80387 || TARGET_SSE_MATH"
6768   "")
6769 \f
6770 ;; Subtract instructions
6771
6772 ;; %%% splits for subditi3
6773
6774 (define_expand "subti3"
6775   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6776                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6777                              (match_operand:TI 2 "x86_64_general_operand" "")))
6778               (clobber (reg:CC FLAGS_REG))])]
6779   "TARGET_64BIT"
6780   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6781
6782 (define_insn "*subti3_1"
6783   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6784         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6785                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6786    (clobber (reg:CC FLAGS_REG))]
6787   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6788   "#")
6789
6790 (define_split
6791   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6792         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6793                   (match_operand:TI 2 "general_operand" "")))
6794    (clobber (reg:CC FLAGS_REG))]
6795   "TARGET_64BIT && reload_completed"
6796   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6797               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6798    (parallel [(set (match_dup 3)
6799                    (minus:DI (match_dup 4)
6800                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6801                                       (match_dup 5))))
6802               (clobber (reg:CC FLAGS_REG))])]
6803   "split_ti (operands+0, 1, operands+0, operands+3);
6804    split_ti (operands+1, 1, operands+1, operands+4);
6805    split_ti (operands+2, 1, operands+2, operands+5);")
6806
6807 ;; %%% splits for subsidi3
6808
6809 (define_expand "subdi3"
6810   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6811                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6812                              (match_operand:DI 2 "x86_64_general_operand" "")))
6813               (clobber (reg:CC FLAGS_REG))])]
6814   ""
6815   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6816
6817 (define_insn "*subdi3_1"
6818   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6819         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6820                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6821    (clobber (reg:CC FLAGS_REG))]
6822   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6823   "#")
6824
6825 (define_split
6826   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6827         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6828                   (match_operand:DI 2 "general_operand" "")))
6829    (clobber (reg:CC FLAGS_REG))]
6830   "!TARGET_64BIT && reload_completed"
6831   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6832               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6833    (parallel [(set (match_dup 3)
6834                    (minus:SI (match_dup 4)
6835                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6836                                       (match_dup 5))))
6837               (clobber (reg:CC FLAGS_REG))])]
6838   "split_di (operands+0, 1, operands+0, operands+3);
6839    split_di (operands+1, 1, operands+1, operands+4);
6840    split_di (operands+2, 1, operands+2, operands+5);")
6841
6842 (define_insn "subdi3_carry_rex64"
6843   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6844           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6845             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6846                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6847    (clobber (reg:CC FLAGS_REG))]
6848   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6849   "sbb{q}\t{%2, %0|%0, %2}"
6850   [(set_attr "type" "alu")
6851    (set_attr "pent_pair" "pu")
6852    (set_attr "mode" "DI")])
6853
6854 (define_insn "*subdi_1_rex64"
6855   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6856         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6857                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6858    (clobber (reg:CC FLAGS_REG))]
6859   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6860   "sub{q}\t{%2, %0|%0, %2}"
6861   [(set_attr "type" "alu")
6862    (set_attr "mode" "DI")])
6863
6864 (define_insn "*subdi_2_rex64"
6865   [(set (reg FLAGS_REG)
6866         (compare
6867           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6868                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6869           (const_int 0)))
6870    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6871         (minus:DI (match_dup 1) (match_dup 2)))]
6872   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6873    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6874   "sub{q}\t{%2, %0|%0, %2}"
6875   [(set_attr "type" "alu")
6876    (set_attr "mode" "DI")])
6877
6878 (define_insn "*subdi_3_rex63"
6879   [(set (reg FLAGS_REG)
6880         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6881                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6882    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6883         (minus:DI (match_dup 1) (match_dup 2)))]
6884   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6885    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6886   "sub{q}\t{%2, %0|%0, %2}"
6887   [(set_attr "type" "alu")
6888    (set_attr "mode" "DI")])
6889
6890 (define_insn "subqi3_carry"
6891   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6892           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6893             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6894                (match_operand:QI 2 "general_operand" "qi,qm"))))
6895    (clobber (reg:CC FLAGS_REG))]
6896   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6897   "sbb{b}\t{%2, %0|%0, %2}"
6898   [(set_attr "type" "alu")
6899    (set_attr "pent_pair" "pu")
6900    (set_attr "mode" "QI")])
6901
6902 (define_insn "subhi3_carry"
6903   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6904           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6905             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6906                (match_operand:HI 2 "general_operand" "ri,rm"))))
6907    (clobber (reg:CC FLAGS_REG))]
6908   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6909   "sbb{w}\t{%2, %0|%0, %2}"
6910   [(set_attr "type" "alu")
6911    (set_attr "pent_pair" "pu")
6912    (set_attr "mode" "HI")])
6913
6914 (define_insn "subsi3_carry"
6915   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6916           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6917             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6918                (match_operand:SI 2 "general_operand" "ri,rm"))))
6919    (clobber (reg:CC FLAGS_REG))]
6920   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6921   "sbb{l}\t{%2, %0|%0, %2}"
6922   [(set_attr "type" "alu")
6923    (set_attr "pent_pair" "pu")
6924    (set_attr "mode" "SI")])
6925
6926 (define_insn "subsi3_carry_zext"
6927   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6928           (zero_extend:DI
6929             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6930               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6931                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6932    (clobber (reg:CC FLAGS_REG))]
6933   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6934   "sbb{l}\t{%2, %k0|%k0, %2}"
6935   [(set_attr "type" "alu")
6936    (set_attr "pent_pair" "pu")
6937    (set_attr "mode" "SI")])
6938
6939 (define_expand "subsi3"
6940   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6941                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6942                              (match_operand:SI 2 "general_operand" "")))
6943               (clobber (reg:CC FLAGS_REG))])]
6944   ""
6945   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6946
6947 (define_insn "*subsi_1"
6948   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6949         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6950                   (match_operand:SI 2 "general_operand" "ri,rm")))
6951    (clobber (reg:CC FLAGS_REG))]
6952   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6953   "sub{l}\t{%2, %0|%0, %2}"
6954   [(set_attr "type" "alu")
6955    (set_attr "mode" "SI")])
6956
6957 (define_insn "*subsi_1_zext"
6958   [(set (match_operand:DI 0 "register_operand" "=r")
6959         (zero_extend:DI
6960           (minus:SI (match_operand:SI 1 "register_operand" "0")
6961                     (match_operand:SI 2 "general_operand" "rim"))))
6962    (clobber (reg:CC FLAGS_REG))]
6963   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6964   "sub{l}\t{%2, %k0|%k0, %2}"
6965   [(set_attr "type" "alu")
6966    (set_attr "mode" "SI")])
6967
6968 (define_insn "*subsi_2"
6969   [(set (reg FLAGS_REG)
6970         (compare
6971           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6972                     (match_operand:SI 2 "general_operand" "ri,rm"))
6973           (const_int 0)))
6974    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6975         (minus:SI (match_dup 1) (match_dup 2)))]
6976   "ix86_match_ccmode (insn, CCGOCmode)
6977    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6978   "sub{l}\t{%2, %0|%0, %2}"
6979   [(set_attr "type" "alu")
6980    (set_attr "mode" "SI")])
6981
6982 (define_insn "*subsi_2_zext"
6983   [(set (reg FLAGS_REG)
6984         (compare
6985           (minus:SI (match_operand:SI 1 "register_operand" "0")
6986                     (match_operand:SI 2 "general_operand" "rim"))
6987           (const_int 0)))
6988    (set (match_operand:DI 0 "register_operand" "=r")
6989         (zero_extend:DI
6990           (minus:SI (match_dup 1)
6991                     (match_dup 2))))]
6992   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6993    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6994   "sub{l}\t{%2, %k0|%k0, %2}"
6995   [(set_attr "type" "alu")
6996    (set_attr "mode" "SI")])
6997
6998 (define_insn "*subsi_3"
6999   [(set (reg FLAGS_REG)
7000         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7001                  (match_operand:SI 2 "general_operand" "ri,rm")))
7002    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7003         (minus:SI (match_dup 1) (match_dup 2)))]
7004   "ix86_match_ccmode (insn, CCmode)
7005    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7006   "sub{l}\t{%2, %0|%0, %2}"
7007   [(set_attr "type" "alu")
7008    (set_attr "mode" "SI")])
7009
7010 (define_insn "*subsi_3_zext"
7011   [(set (reg FLAGS_REG)
7012         (compare (match_operand:SI 1 "register_operand" "0")
7013                  (match_operand:SI 2 "general_operand" "rim")))
7014    (set (match_operand:DI 0 "register_operand" "=r")
7015         (zero_extend:DI
7016           (minus:SI (match_dup 1)
7017                     (match_dup 2))))]
7018   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7019    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7020   "sub{l}\t{%2, %1|%1, %2}"
7021   [(set_attr "type" "alu")
7022    (set_attr "mode" "DI")])
7023
7024 (define_expand "subhi3"
7025   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7026                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7027                              (match_operand:HI 2 "general_operand" "")))
7028               (clobber (reg:CC FLAGS_REG))])]
7029   "TARGET_HIMODE_MATH"
7030   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7031
7032 (define_insn "*subhi_1"
7033   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7034         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7035                   (match_operand:HI 2 "general_operand" "ri,rm")))
7036    (clobber (reg:CC FLAGS_REG))]
7037   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7038   "sub{w}\t{%2, %0|%0, %2}"
7039   [(set_attr "type" "alu")
7040    (set_attr "mode" "HI")])
7041
7042 (define_insn "*subhi_2"
7043   [(set (reg FLAGS_REG)
7044         (compare
7045           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7046                     (match_operand:HI 2 "general_operand" "ri,rm"))
7047           (const_int 0)))
7048    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7049         (minus:HI (match_dup 1) (match_dup 2)))]
7050   "ix86_match_ccmode (insn, CCGOCmode)
7051    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7052   "sub{w}\t{%2, %0|%0, %2}"
7053   [(set_attr "type" "alu")
7054    (set_attr "mode" "HI")])
7055
7056 (define_insn "*subhi_3"
7057   [(set (reg FLAGS_REG)
7058         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7059                  (match_operand:HI 2 "general_operand" "ri,rm")))
7060    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7061         (minus:HI (match_dup 1) (match_dup 2)))]
7062   "ix86_match_ccmode (insn, CCmode)
7063    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7064   "sub{w}\t{%2, %0|%0, %2}"
7065   [(set_attr "type" "alu")
7066    (set_attr "mode" "HI")])
7067
7068 (define_expand "subqi3"
7069   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7070                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7071                              (match_operand:QI 2 "general_operand" "")))
7072               (clobber (reg:CC FLAGS_REG))])]
7073   "TARGET_QIMODE_MATH"
7074   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7075
7076 (define_insn "*subqi_1"
7077   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7078         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7079                   (match_operand:QI 2 "general_operand" "qn,qmn")))
7080    (clobber (reg:CC FLAGS_REG))]
7081   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7082   "sub{b}\t{%2, %0|%0, %2}"
7083   [(set_attr "type" "alu")
7084    (set_attr "mode" "QI")])
7085
7086 (define_insn "*subqi_1_slp"
7087   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7088         (minus:QI (match_dup 0)
7089                   (match_operand:QI 1 "general_operand" "qn,qmn")))
7090    (clobber (reg:CC FLAGS_REG))]
7091   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7092    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7093   "sub{b}\t{%1, %0|%0, %1}"
7094   [(set_attr "type" "alu1")
7095    (set_attr "mode" "QI")])
7096
7097 (define_insn "*subqi_2"
7098   [(set (reg FLAGS_REG)
7099         (compare
7100           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7101                     (match_operand:QI 2 "general_operand" "qi,qm"))
7102           (const_int 0)))
7103    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7104         (minus:HI (match_dup 1) (match_dup 2)))]
7105   "ix86_match_ccmode (insn, CCGOCmode)
7106    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7107   "sub{b}\t{%2, %0|%0, %2}"
7108   [(set_attr "type" "alu")
7109    (set_attr "mode" "QI")])
7110
7111 (define_insn "*subqi_3"
7112   [(set (reg FLAGS_REG)
7113         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7114                  (match_operand:QI 2 "general_operand" "qi,qm")))
7115    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7116         (minus:HI (match_dup 1) (match_dup 2)))]
7117   "ix86_match_ccmode (insn, CCmode)
7118    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7119   "sub{b}\t{%2, %0|%0, %2}"
7120   [(set_attr "type" "alu")
7121    (set_attr "mode" "QI")])
7122
7123 ;; The patterns that match these are at the end of this file.
7124
7125 (define_expand "subxf3"
7126   [(set (match_operand:XF 0 "register_operand" "")
7127         (minus:XF (match_operand:XF 1 "register_operand" "")
7128                   (match_operand:XF 2 "register_operand" "")))]
7129   "TARGET_80387"
7130   "")
7131
7132 (define_expand "subdf3"
7133   [(set (match_operand:DF 0 "register_operand" "")
7134         (minus:DF (match_operand:DF 1 "register_operand" "")
7135                   (match_operand:DF 2 "nonimmediate_operand" "")))]
7136   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7137   "")
7138
7139 (define_expand "subsf3"
7140   [(set (match_operand:SF 0 "register_operand" "")
7141         (minus:SF (match_operand:SF 1 "register_operand" "")
7142                   (match_operand:SF 2 "nonimmediate_operand" "")))]
7143   "TARGET_80387 || TARGET_SSE_MATH"
7144   "")
7145 \f
7146 ;; Multiply instructions
7147
7148 (define_expand "muldi3"
7149   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7150                    (mult:DI (match_operand:DI 1 "register_operand" "")
7151                             (match_operand:DI 2 "x86_64_general_operand" "")))
7152               (clobber (reg:CC FLAGS_REG))])]
7153   "TARGET_64BIT"
7154   "")
7155
7156 ;; On AMDFAM10 
7157 ;; IMUL reg64, reg64, imm8      Direct
7158 ;; IMUL reg64, mem64, imm8      VectorPath
7159 ;; IMUL reg64, reg64, imm32     Direct
7160 ;; IMUL reg64, mem64, imm32     VectorPath 
7161 ;; IMUL reg64, reg64            Direct
7162 ;; IMUL reg64, mem64            Direct
7163
7164 (define_insn "*muldi3_1_rex64"
7165   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7166         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7167                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7168    (clobber (reg:CC FLAGS_REG))]
7169   "TARGET_64BIT
7170    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7171   "@
7172    imul{q}\t{%2, %1, %0|%0, %1, %2}
7173    imul{q}\t{%2, %1, %0|%0, %1, %2}
7174    imul{q}\t{%2, %0|%0, %2}"
7175   [(set_attr "type" "imul")
7176    (set_attr "prefix_0f" "0,0,1")
7177    (set (attr "athlon_decode")
7178         (cond [(eq_attr "cpu" "athlon")
7179                   (const_string "vector")
7180                (eq_attr "alternative" "1")
7181                   (const_string "vector")
7182                (and (eq_attr "alternative" "2")
7183                     (match_operand 1 "memory_operand" ""))
7184                   (const_string "vector")]
7185               (const_string "direct")))
7186    (set (attr "amdfam10_decode")
7187         (cond [(and (eq_attr "alternative" "0,1")
7188                     (match_operand 1 "memory_operand" ""))
7189                   (const_string "vector")]
7190               (const_string "direct")))       
7191    (set_attr "mode" "DI")])
7192
7193 (define_expand "mulsi3"
7194   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7195                    (mult:SI (match_operand:SI 1 "register_operand" "")
7196                             (match_operand:SI 2 "general_operand" "")))
7197               (clobber (reg:CC FLAGS_REG))])]
7198   ""
7199   "")
7200
7201 ;; On AMDFAM10 
7202 ;; IMUL reg32, reg32, imm8      Direct
7203 ;; IMUL reg32, mem32, imm8      VectorPath
7204 ;; IMUL reg32, reg32, imm32     Direct
7205 ;; IMUL reg32, mem32, imm32     VectorPath
7206 ;; IMUL reg32, reg32            Direct
7207 ;; IMUL reg32, mem32            Direct
7208
7209 (define_insn "*mulsi3_1"
7210   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7211         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7212                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7213    (clobber (reg:CC FLAGS_REG))]
7214   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7215   "@
7216    imul{l}\t{%2, %1, %0|%0, %1, %2}
7217    imul{l}\t{%2, %1, %0|%0, %1, %2}
7218    imul{l}\t{%2, %0|%0, %2}"
7219   [(set_attr "type" "imul")
7220    (set_attr "prefix_0f" "0,0,1")
7221    (set (attr "athlon_decode")
7222         (cond [(eq_attr "cpu" "athlon")
7223                   (const_string "vector")
7224                (eq_attr "alternative" "1")
7225                   (const_string "vector")
7226                (and (eq_attr "alternative" "2")
7227                     (match_operand 1 "memory_operand" ""))
7228                   (const_string "vector")]
7229               (const_string "direct")))
7230    (set (attr "amdfam10_decode")
7231         (cond [(and (eq_attr "alternative" "0,1")
7232                     (match_operand 1 "memory_operand" ""))
7233                   (const_string "vector")]
7234               (const_string "direct")))       
7235    (set_attr "mode" "SI")])
7236
7237 (define_insn "*mulsi3_1_zext"
7238   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7239         (zero_extend:DI
7240           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7241                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7242    (clobber (reg:CC FLAGS_REG))]
7243   "TARGET_64BIT
7244    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7245   "@
7246    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7247    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7248    imul{l}\t{%2, %k0|%k0, %2}"
7249   [(set_attr "type" "imul")
7250    (set_attr "prefix_0f" "0,0,1")
7251    (set (attr "athlon_decode")
7252         (cond [(eq_attr "cpu" "athlon")
7253                   (const_string "vector")
7254                (eq_attr "alternative" "1")
7255                   (const_string "vector")
7256                (and (eq_attr "alternative" "2")
7257                     (match_operand 1 "memory_operand" ""))
7258                   (const_string "vector")]
7259               (const_string "direct")))
7260    (set (attr "amdfam10_decode")
7261         (cond [(and (eq_attr "alternative" "0,1")
7262                     (match_operand 1 "memory_operand" ""))
7263                   (const_string "vector")]
7264               (const_string "direct")))       
7265    (set_attr "mode" "SI")])
7266
7267 (define_expand "mulhi3"
7268   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7269                    (mult:HI (match_operand:HI 1 "register_operand" "")
7270                             (match_operand:HI 2 "general_operand" "")))
7271               (clobber (reg:CC FLAGS_REG))])]
7272   "TARGET_HIMODE_MATH"
7273   "")
7274
7275 ;; On AMDFAM10
7276 ;; IMUL reg16, reg16, imm8      VectorPath
7277 ;; IMUL reg16, mem16, imm8      VectorPath
7278 ;; IMUL reg16, reg16, imm16     VectorPath
7279 ;; IMUL reg16, mem16, imm16     VectorPath
7280 ;; IMUL reg16, reg16            Direct
7281 ;; IMUL reg16, mem16            Direct
7282 (define_insn "*mulhi3_1"
7283   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7284         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7285                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7286    (clobber (reg:CC FLAGS_REG))]
7287   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7288   "@
7289    imul{w}\t{%2, %1, %0|%0, %1, %2}
7290    imul{w}\t{%2, %1, %0|%0, %1, %2}
7291    imul{w}\t{%2, %0|%0, %2}"
7292   [(set_attr "type" "imul")
7293    (set_attr "prefix_0f" "0,0,1")
7294    (set (attr "athlon_decode")
7295         (cond [(eq_attr "cpu" "athlon")
7296                   (const_string "vector")
7297                (eq_attr "alternative" "1,2")
7298                   (const_string "vector")]
7299               (const_string "direct")))
7300    (set (attr "amdfam10_decode")
7301         (cond [(eq_attr "alternative" "0,1")
7302                   (const_string "vector")]
7303               (const_string "direct")))
7304    (set_attr "mode" "HI")])
7305
7306 (define_expand "mulqi3"
7307   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7308                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7309                             (match_operand:QI 2 "register_operand" "")))
7310               (clobber (reg:CC FLAGS_REG))])]
7311   "TARGET_QIMODE_MATH"
7312   "")
7313
7314 ;;On AMDFAM10
7315 ;; MUL reg8     Direct
7316 ;; MUL mem8     Direct
7317
7318 (define_insn "*mulqi3_1"
7319   [(set (match_operand:QI 0 "register_operand" "=a")
7320         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7321                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7322    (clobber (reg:CC FLAGS_REG))]
7323   "TARGET_QIMODE_MATH
7324    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7325   "mul{b}\t%2"
7326   [(set_attr "type" "imul")
7327    (set_attr "length_immediate" "0")
7328    (set (attr "athlon_decode")
7329      (if_then_else (eq_attr "cpu" "athlon")
7330         (const_string "vector")
7331         (const_string "direct")))
7332    (set_attr "amdfam10_decode" "direct")        
7333    (set_attr "mode" "QI")])
7334
7335 (define_expand "umulqihi3"
7336   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7337                    (mult:HI (zero_extend:HI
7338                               (match_operand:QI 1 "nonimmediate_operand" ""))
7339                             (zero_extend:HI
7340                               (match_operand:QI 2 "register_operand" ""))))
7341               (clobber (reg:CC FLAGS_REG))])]
7342   "TARGET_QIMODE_MATH"
7343   "")
7344
7345 (define_insn "*umulqihi3_1"
7346   [(set (match_operand:HI 0 "register_operand" "=a")
7347         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7348                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7349    (clobber (reg:CC FLAGS_REG))]
7350   "TARGET_QIMODE_MATH
7351    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7352   "mul{b}\t%2"
7353   [(set_attr "type" "imul")
7354    (set_attr "length_immediate" "0")
7355    (set (attr "athlon_decode")
7356      (if_then_else (eq_attr "cpu" "athlon")
7357         (const_string "vector")
7358         (const_string "direct")))
7359    (set_attr "amdfam10_decode" "direct")        
7360    (set_attr "mode" "QI")])
7361
7362 (define_expand "mulqihi3"
7363   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7364                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7365                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7366               (clobber (reg:CC FLAGS_REG))])]
7367   "TARGET_QIMODE_MATH"
7368   "")
7369
7370 (define_insn "*mulqihi3_insn"
7371   [(set (match_operand:HI 0 "register_operand" "=a")
7372         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7373                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7374    (clobber (reg:CC FLAGS_REG))]
7375   "TARGET_QIMODE_MATH
7376    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7377   "imul{b}\t%2"
7378   [(set_attr "type" "imul")
7379    (set_attr "length_immediate" "0")
7380    (set (attr "athlon_decode")
7381      (if_then_else (eq_attr "cpu" "athlon")
7382         (const_string "vector")
7383         (const_string "direct")))
7384    (set_attr "amdfam10_decode" "direct")        
7385    (set_attr "mode" "QI")])
7386
7387 (define_expand "umulditi3"
7388   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7389                    (mult:TI (zero_extend:TI
7390                               (match_operand:DI 1 "nonimmediate_operand" ""))
7391                             (zero_extend:TI
7392                               (match_operand:DI 2 "register_operand" ""))))
7393               (clobber (reg:CC FLAGS_REG))])]
7394   "TARGET_64BIT"
7395   "")
7396
7397 (define_insn "*umulditi3_insn"
7398   [(set (match_operand:TI 0 "register_operand" "=A")
7399         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7400                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7401    (clobber (reg:CC FLAGS_REG))]
7402   "TARGET_64BIT
7403    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7404   "mul{q}\t%2"
7405   [(set_attr "type" "imul")
7406    (set_attr "length_immediate" "0")
7407    (set (attr "athlon_decode")
7408      (if_then_else (eq_attr "cpu" "athlon")
7409         (const_string "vector")
7410         (const_string "double")))
7411    (set_attr "amdfam10_decode" "double")        
7412    (set_attr "mode" "DI")])
7413
7414 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7415 (define_expand "umulsidi3"
7416   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7417                    (mult:DI (zero_extend:DI
7418                               (match_operand:SI 1 "nonimmediate_operand" ""))
7419                             (zero_extend:DI
7420                               (match_operand:SI 2 "register_operand" ""))))
7421               (clobber (reg:CC FLAGS_REG))])]
7422   "!TARGET_64BIT"
7423   "")
7424
7425 (define_insn "*umulsidi3_insn"
7426   [(set (match_operand:DI 0 "register_operand" "=A")
7427         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7428                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7429    (clobber (reg:CC FLAGS_REG))]
7430   "!TARGET_64BIT
7431    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7432   "mul{l}\t%2"
7433   [(set_attr "type" "imul")
7434    (set_attr "length_immediate" "0")
7435    (set (attr "athlon_decode")
7436      (if_then_else (eq_attr "cpu" "athlon")
7437         (const_string "vector")
7438         (const_string "double")))
7439    (set_attr "amdfam10_decode" "double")        
7440    (set_attr "mode" "SI")])
7441
7442 (define_expand "mulditi3"
7443   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7444                    (mult:TI (sign_extend:TI
7445                               (match_operand:DI 1 "nonimmediate_operand" ""))
7446                             (sign_extend:TI
7447                               (match_operand:DI 2 "register_operand" ""))))
7448               (clobber (reg:CC FLAGS_REG))])]
7449   "TARGET_64BIT"
7450   "")
7451
7452 (define_insn "*mulditi3_insn"
7453   [(set (match_operand:TI 0 "register_operand" "=A")
7454         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7455                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7456    (clobber (reg:CC FLAGS_REG))]
7457   "TARGET_64BIT
7458    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7459   "imul{q}\t%2"
7460   [(set_attr "type" "imul")
7461    (set_attr "length_immediate" "0")
7462    (set (attr "athlon_decode")
7463      (if_then_else (eq_attr "cpu" "athlon")
7464         (const_string "vector")
7465         (const_string "double")))
7466    (set_attr "amdfam10_decode" "double")
7467    (set_attr "mode" "DI")])
7468
7469 (define_expand "mulsidi3"
7470   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7471                    (mult:DI (sign_extend:DI
7472                               (match_operand:SI 1 "nonimmediate_operand" ""))
7473                             (sign_extend:DI
7474                               (match_operand:SI 2 "register_operand" ""))))
7475               (clobber (reg:CC FLAGS_REG))])]
7476   "!TARGET_64BIT"
7477   "")
7478
7479 (define_insn "*mulsidi3_insn"
7480   [(set (match_operand:DI 0 "register_operand" "=A")
7481         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7482                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7483    (clobber (reg:CC FLAGS_REG))]
7484   "!TARGET_64BIT
7485    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7486   "imul{l}\t%2"
7487   [(set_attr "type" "imul")
7488    (set_attr "length_immediate" "0")
7489    (set (attr "athlon_decode")
7490      (if_then_else (eq_attr "cpu" "athlon")
7491         (const_string "vector")
7492         (const_string "double")))
7493    (set_attr "amdfam10_decode" "double")        
7494    (set_attr "mode" "SI")])
7495
7496 (define_expand "umuldi3_highpart"
7497   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7498                    (truncate:DI
7499                      (lshiftrt:TI
7500                        (mult:TI (zero_extend:TI
7501                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7502                                 (zero_extend:TI
7503                                   (match_operand:DI 2 "register_operand" "")))
7504                        (const_int 64))))
7505               (clobber (match_scratch:DI 3 ""))
7506               (clobber (reg:CC FLAGS_REG))])]
7507   "TARGET_64BIT"
7508   "")
7509
7510 (define_insn "*umuldi3_highpart_rex64"
7511   [(set (match_operand:DI 0 "register_operand" "=d")
7512         (truncate:DI
7513           (lshiftrt:TI
7514             (mult:TI (zero_extend:TI
7515                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7516                      (zero_extend:TI
7517                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7518             (const_int 64))))
7519    (clobber (match_scratch:DI 3 "=1"))
7520    (clobber (reg:CC FLAGS_REG))]
7521   "TARGET_64BIT
7522    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7523   "mul{q}\t%2"
7524   [(set_attr "type" "imul")
7525    (set_attr "length_immediate" "0")
7526    (set (attr "athlon_decode")
7527      (if_then_else (eq_attr "cpu" "athlon")
7528         (const_string "vector")
7529         (const_string "double")))
7530    (set_attr "amdfam10_decode" "double")        
7531    (set_attr "mode" "DI")])
7532
7533 (define_expand "umulsi3_highpart"
7534   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7535                    (truncate:SI
7536                      (lshiftrt:DI
7537                        (mult:DI (zero_extend:DI
7538                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7539                                 (zero_extend:DI
7540                                   (match_operand:SI 2 "register_operand" "")))
7541                        (const_int 32))))
7542               (clobber (match_scratch:SI 3 ""))
7543               (clobber (reg:CC FLAGS_REG))])]
7544   ""
7545   "")
7546
7547 (define_insn "*umulsi3_highpart_insn"
7548   [(set (match_operand:SI 0 "register_operand" "=d")
7549         (truncate:SI
7550           (lshiftrt:DI
7551             (mult:DI (zero_extend:DI
7552                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7553                      (zero_extend:DI
7554                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7555             (const_int 32))))
7556    (clobber (match_scratch:SI 3 "=1"))
7557    (clobber (reg:CC FLAGS_REG))]
7558   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7559   "mul{l}\t%2"
7560   [(set_attr "type" "imul")
7561    (set_attr "length_immediate" "0")
7562    (set (attr "athlon_decode")
7563      (if_then_else (eq_attr "cpu" "athlon")
7564         (const_string "vector")
7565         (const_string "double")))
7566    (set_attr "amdfam10_decode" "double")
7567    (set_attr "mode" "SI")])
7568
7569 (define_insn "*umulsi3_highpart_zext"
7570   [(set (match_operand:DI 0 "register_operand" "=d")
7571         (zero_extend:DI (truncate:SI
7572           (lshiftrt:DI
7573             (mult:DI (zero_extend:DI
7574                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7575                      (zero_extend:DI
7576                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7577             (const_int 32)))))
7578    (clobber (match_scratch:SI 3 "=1"))
7579    (clobber (reg:CC FLAGS_REG))]
7580   "TARGET_64BIT
7581    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7582   "mul{l}\t%2"
7583   [(set_attr "type" "imul")
7584    (set_attr "length_immediate" "0")
7585    (set (attr "athlon_decode")
7586      (if_then_else (eq_attr "cpu" "athlon")
7587         (const_string "vector")
7588         (const_string "double")))
7589    (set_attr "amdfam10_decode" "double")
7590    (set_attr "mode" "SI")])
7591
7592 (define_expand "smuldi3_highpart"
7593   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7594                    (truncate:DI
7595                      (lshiftrt:TI
7596                        (mult:TI (sign_extend:TI
7597                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7598                                 (sign_extend:TI
7599                                   (match_operand:DI 2 "register_operand" "")))
7600                        (const_int 64))))
7601               (clobber (match_scratch:DI 3 ""))
7602               (clobber (reg:CC FLAGS_REG))])]
7603   "TARGET_64BIT"
7604   "")
7605
7606 (define_insn "*smuldi3_highpart_rex64"
7607   [(set (match_operand:DI 0 "register_operand" "=d")
7608         (truncate:DI
7609           (lshiftrt:TI
7610             (mult:TI (sign_extend:TI
7611                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7612                      (sign_extend:TI
7613                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7614             (const_int 64))))
7615    (clobber (match_scratch:DI 3 "=1"))
7616    (clobber (reg:CC FLAGS_REG))]
7617   "TARGET_64BIT
7618    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7619   "imul{q}\t%2"
7620   [(set_attr "type" "imul")
7621    (set (attr "athlon_decode")
7622      (if_then_else (eq_attr "cpu" "athlon")
7623         (const_string "vector")
7624         (const_string "double")))
7625    (set_attr "amdfam10_decode" "double")
7626    (set_attr "mode" "DI")])
7627
7628 (define_expand "smulsi3_highpart"
7629   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7630                    (truncate:SI
7631                      (lshiftrt:DI
7632                        (mult:DI (sign_extend:DI
7633                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7634                                 (sign_extend:DI
7635                                   (match_operand:SI 2 "register_operand" "")))
7636                        (const_int 32))))
7637               (clobber (match_scratch:SI 3 ""))
7638               (clobber (reg:CC FLAGS_REG))])]
7639   ""
7640   "")
7641
7642 (define_insn "*smulsi3_highpart_insn"
7643   [(set (match_operand:SI 0 "register_operand" "=d")
7644         (truncate:SI
7645           (lshiftrt:DI
7646             (mult:DI (sign_extend:DI
7647                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7648                      (sign_extend:DI
7649                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7650             (const_int 32))))
7651    (clobber (match_scratch:SI 3 "=1"))
7652    (clobber (reg:CC FLAGS_REG))]
7653   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7654   "imul{l}\t%2"
7655   [(set_attr "type" "imul")
7656    (set (attr "athlon_decode")
7657      (if_then_else (eq_attr "cpu" "athlon")
7658         (const_string "vector")
7659         (const_string "double")))
7660    (set_attr "amdfam10_decode" "double")
7661    (set_attr "mode" "SI")])
7662
7663 (define_insn "*smulsi3_highpart_zext"
7664   [(set (match_operand:DI 0 "register_operand" "=d")
7665         (zero_extend:DI (truncate:SI
7666           (lshiftrt:DI
7667             (mult:DI (sign_extend:DI
7668                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7669                      (sign_extend:DI
7670                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7671             (const_int 32)))))
7672    (clobber (match_scratch:SI 3 "=1"))
7673    (clobber (reg:CC FLAGS_REG))]
7674   "TARGET_64BIT
7675    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7676   "imul{l}\t%2"
7677   [(set_attr "type" "imul")
7678    (set (attr "athlon_decode")
7679      (if_then_else (eq_attr "cpu" "athlon")
7680         (const_string "vector")
7681         (const_string "double")))
7682    (set_attr "amdfam10_decode" "double")
7683    (set_attr "mode" "SI")])
7684
7685 ;; The patterns that match these are at the end of this file.
7686
7687 (define_expand "mulxf3"
7688   [(set (match_operand:XF 0 "register_operand" "")
7689         (mult:XF (match_operand:XF 1 "register_operand" "")
7690                  (match_operand:XF 2 "register_operand" "")))]
7691   "TARGET_80387"
7692   "")
7693
7694 (define_expand "muldf3"
7695   [(set (match_operand:DF 0 "register_operand" "")
7696         (mult:DF (match_operand:DF 1 "register_operand" "")
7697                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7698   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7699   "")
7700
7701 (define_expand "mulsf3"
7702   [(set (match_operand:SF 0 "register_operand" "")
7703         (mult:SF (match_operand:SF 1 "register_operand" "")
7704                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7705   "TARGET_80387 || TARGET_SSE_MATH"
7706   "")
7707 \f
7708 ;; Divide instructions
7709
7710 (define_insn "divqi3"
7711   [(set (match_operand:QI 0 "register_operand" "=a")
7712         (div:QI (match_operand:HI 1 "register_operand" "0")
7713                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7714    (clobber (reg:CC FLAGS_REG))]
7715   "TARGET_QIMODE_MATH"
7716   "idiv{b}\t%2"
7717   [(set_attr "type" "idiv")
7718    (set_attr "mode" "QI")])
7719
7720 (define_insn "udivqi3"
7721   [(set (match_operand:QI 0 "register_operand" "=a")
7722         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7723                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7724    (clobber (reg:CC FLAGS_REG))]
7725   "TARGET_QIMODE_MATH"
7726   "div{b}\t%2"
7727   [(set_attr "type" "idiv")
7728    (set_attr "mode" "QI")])
7729
7730 ;; The patterns that match these are at the end of this file.
7731
7732 (define_expand "divxf3"
7733   [(set (match_operand:XF 0 "register_operand" "")
7734         (div:XF (match_operand:XF 1 "register_operand" "")
7735                 (match_operand:XF 2 "register_operand" "")))]
7736   "TARGET_80387"
7737   "")
7738
7739 (define_expand "divdf3"
7740   [(set (match_operand:DF 0 "register_operand" "")
7741         (div:DF (match_operand:DF 1 "register_operand" "")
7742                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7743    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7744    "")
7745
7746 (define_expand "divsf3"
7747   [(set (match_operand:SF 0 "register_operand" "")
7748         (div:SF (match_operand:SF 1 "register_operand" "")
7749                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7750   "TARGET_80387 || TARGET_SSE_MATH"
7751   "")
7752 \f
7753 ;; Remainder instructions.
7754
7755 (define_expand "divmoddi4"
7756   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7757                    (div:DI (match_operand:DI 1 "register_operand" "")
7758                            (match_operand:DI 2 "nonimmediate_operand" "")))
7759               (set (match_operand:DI 3 "register_operand" "")
7760                    (mod:DI (match_dup 1) (match_dup 2)))
7761               (clobber (reg:CC FLAGS_REG))])]
7762   "TARGET_64BIT"
7763   "")
7764
7765 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7766 ;; Penalize eax case slightly because it results in worse scheduling
7767 ;; of code.
7768 (define_insn "*divmoddi4_nocltd_rex64"
7769   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7770         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7771                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7772    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7773         (mod:DI (match_dup 2) (match_dup 3)))
7774    (clobber (reg:CC FLAGS_REG))]
7775   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7776   "#"
7777   [(set_attr "type" "multi")])
7778
7779 (define_insn "*divmoddi4_cltd_rex64"
7780   [(set (match_operand:DI 0 "register_operand" "=a")
7781         (div:DI (match_operand:DI 2 "register_operand" "a")
7782                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7783    (set (match_operand:DI 1 "register_operand" "=&d")
7784         (mod:DI (match_dup 2) (match_dup 3)))
7785    (clobber (reg:CC FLAGS_REG))]
7786   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7787   "#"
7788   [(set_attr "type" "multi")])
7789
7790 (define_insn "*divmoddi_noext_rex64"
7791   [(set (match_operand:DI 0 "register_operand" "=a")
7792         (div:DI (match_operand:DI 1 "register_operand" "0")
7793                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7794    (set (match_operand:DI 3 "register_operand" "=d")
7795         (mod:DI (match_dup 1) (match_dup 2)))
7796    (use (match_operand:DI 4 "register_operand" "3"))
7797    (clobber (reg:CC FLAGS_REG))]
7798   "TARGET_64BIT"
7799   "idiv{q}\t%2"
7800   [(set_attr "type" "idiv")
7801    (set_attr "mode" "DI")])
7802
7803 (define_split
7804   [(set (match_operand:DI 0 "register_operand" "")
7805         (div:DI (match_operand:DI 1 "register_operand" "")
7806                 (match_operand:DI 2 "nonimmediate_operand" "")))
7807    (set (match_operand:DI 3 "register_operand" "")
7808         (mod:DI (match_dup 1) (match_dup 2)))
7809    (clobber (reg:CC FLAGS_REG))]
7810   "TARGET_64BIT && reload_completed"
7811   [(parallel [(set (match_dup 3)
7812                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7813               (clobber (reg:CC FLAGS_REG))])
7814    (parallel [(set (match_dup 0)
7815                    (div:DI (reg:DI 0) (match_dup 2)))
7816               (set (match_dup 3)
7817                    (mod:DI (reg:DI 0) (match_dup 2)))
7818               (use (match_dup 3))
7819               (clobber (reg:CC FLAGS_REG))])]
7820 {
7821   /* Avoid use of cltd in favor of a mov+shift.  */
7822   if (!TARGET_USE_CLTD && !optimize_size)
7823     {
7824       if (true_regnum (operands[1]))
7825         emit_move_insn (operands[0], operands[1]);
7826       else
7827         emit_move_insn (operands[3], operands[1]);
7828       operands[4] = operands[3];
7829     }
7830   else
7831     {
7832       gcc_assert (!true_regnum (operands[1]));
7833       operands[4] = operands[1];
7834     }
7835 })
7836
7837
7838 (define_expand "divmodsi4"
7839   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7840                    (div:SI (match_operand:SI 1 "register_operand" "")
7841                            (match_operand:SI 2 "nonimmediate_operand" "")))
7842               (set (match_operand:SI 3 "register_operand" "")
7843                    (mod:SI (match_dup 1) (match_dup 2)))
7844               (clobber (reg:CC FLAGS_REG))])]
7845   ""
7846   "")
7847
7848 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7849 ;; Penalize eax case slightly because it results in worse scheduling
7850 ;; of code.
7851 (define_insn "*divmodsi4_nocltd"
7852   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7853         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7854                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7855    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7856         (mod:SI (match_dup 2) (match_dup 3)))
7857    (clobber (reg:CC FLAGS_REG))]
7858   "!optimize_size && !TARGET_USE_CLTD"
7859   "#"
7860   [(set_attr "type" "multi")])
7861
7862 (define_insn "*divmodsi4_cltd"
7863   [(set (match_operand:SI 0 "register_operand" "=a")
7864         (div:SI (match_operand:SI 2 "register_operand" "a")
7865                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7866    (set (match_operand:SI 1 "register_operand" "=&d")
7867         (mod:SI (match_dup 2) (match_dup 3)))
7868    (clobber (reg:CC FLAGS_REG))]
7869   "optimize_size || TARGET_USE_CLTD"
7870   "#"
7871   [(set_attr "type" "multi")])
7872
7873 (define_insn "*divmodsi_noext"
7874   [(set (match_operand:SI 0 "register_operand" "=a")
7875         (div:SI (match_operand:SI 1 "register_operand" "0")
7876                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7877    (set (match_operand:SI 3 "register_operand" "=d")
7878         (mod:SI (match_dup 1) (match_dup 2)))
7879    (use (match_operand:SI 4 "register_operand" "3"))
7880    (clobber (reg:CC FLAGS_REG))]
7881   ""
7882   "idiv{l}\t%2"
7883   [(set_attr "type" "idiv")
7884    (set_attr "mode" "SI")])
7885
7886 (define_split
7887   [(set (match_operand:SI 0 "register_operand" "")
7888         (div:SI (match_operand:SI 1 "register_operand" "")
7889                 (match_operand:SI 2 "nonimmediate_operand" "")))
7890    (set (match_operand:SI 3 "register_operand" "")
7891         (mod:SI (match_dup 1) (match_dup 2)))
7892    (clobber (reg:CC FLAGS_REG))]
7893   "reload_completed"
7894   [(parallel [(set (match_dup 3)
7895                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7896               (clobber (reg:CC FLAGS_REG))])
7897    (parallel [(set (match_dup 0)
7898                    (div:SI (reg:SI 0) (match_dup 2)))
7899               (set (match_dup 3)
7900                    (mod:SI (reg:SI 0) (match_dup 2)))
7901               (use (match_dup 3))
7902               (clobber (reg:CC FLAGS_REG))])]
7903 {
7904   /* Avoid use of cltd in favor of a mov+shift.  */
7905   if (!TARGET_USE_CLTD && !optimize_size)
7906     {
7907       if (true_regnum (operands[1]))
7908         emit_move_insn (operands[0], operands[1]);
7909       else
7910         emit_move_insn (operands[3], operands[1]);
7911       operands[4] = operands[3];
7912     }
7913   else
7914     {
7915       gcc_assert (!true_regnum (operands[1]));
7916       operands[4] = operands[1];
7917     }
7918 })
7919 ;; %%% Split me.
7920 (define_insn "divmodhi4"
7921   [(set (match_operand:HI 0 "register_operand" "=a")
7922         (div:HI (match_operand:HI 1 "register_operand" "0")
7923                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7924    (set (match_operand:HI 3 "register_operand" "=&d")
7925         (mod:HI (match_dup 1) (match_dup 2)))
7926    (clobber (reg:CC FLAGS_REG))]
7927   "TARGET_HIMODE_MATH"
7928   "cwtd\;idiv{w}\t%2"
7929   [(set_attr "type" "multi")
7930    (set_attr "length_immediate" "0")
7931    (set_attr "mode" "SI")])
7932
7933 (define_insn "udivmoddi4"
7934   [(set (match_operand:DI 0 "register_operand" "=a")
7935         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7936                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7937    (set (match_operand:DI 3 "register_operand" "=&d")
7938         (umod:DI (match_dup 1) (match_dup 2)))
7939    (clobber (reg:CC FLAGS_REG))]
7940   "TARGET_64BIT"
7941   "xor{q}\t%3, %3\;div{q}\t%2"
7942   [(set_attr "type" "multi")
7943    (set_attr "length_immediate" "0")
7944    (set_attr "mode" "DI")])
7945
7946 (define_insn "*udivmoddi4_noext"
7947   [(set (match_operand:DI 0 "register_operand" "=a")
7948         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7949                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7950    (set (match_operand:DI 3 "register_operand" "=d")
7951         (umod:DI (match_dup 1) (match_dup 2)))
7952    (use (match_dup 3))
7953    (clobber (reg:CC FLAGS_REG))]
7954   "TARGET_64BIT"
7955   "div{q}\t%2"
7956   [(set_attr "type" "idiv")
7957    (set_attr "mode" "DI")])
7958
7959 (define_split
7960   [(set (match_operand:DI 0 "register_operand" "")
7961         (udiv:DI (match_operand:DI 1 "register_operand" "")
7962                  (match_operand:DI 2 "nonimmediate_operand" "")))
7963    (set (match_operand:DI 3 "register_operand" "")
7964         (umod:DI (match_dup 1) (match_dup 2)))
7965    (clobber (reg:CC FLAGS_REG))]
7966   "TARGET_64BIT && reload_completed"
7967   [(set (match_dup 3) (const_int 0))
7968    (parallel [(set (match_dup 0)
7969                    (udiv:DI (match_dup 1) (match_dup 2)))
7970               (set (match_dup 3)
7971                    (umod:DI (match_dup 1) (match_dup 2)))
7972               (use (match_dup 3))
7973               (clobber (reg:CC FLAGS_REG))])]
7974   "")
7975
7976 (define_insn "udivmodsi4"
7977   [(set (match_operand:SI 0 "register_operand" "=a")
7978         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7979                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7980    (set (match_operand:SI 3 "register_operand" "=&d")
7981         (umod:SI (match_dup 1) (match_dup 2)))
7982    (clobber (reg:CC FLAGS_REG))]
7983   ""
7984   "xor{l}\t%3, %3\;div{l}\t%2"
7985   [(set_attr "type" "multi")
7986    (set_attr "length_immediate" "0")
7987    (set_attr "mode" "SI")])
7988
7989 (define_insn "*udivmodsi4_noext"
7990   [(set (match_operand:SI 0 "register_operand" "=a")
7991         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7992                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7993    (set (match_operand:SI 3 "register_operand" "=d")
7994         (umod:SI (match_dup 1) (match_dup 2)))
7995    (use (match_dup 3))
7996    (clobber (reg:CC FLAGS_REG))]
7997   ""
7998   "div{l}\t%2"
7999   [(set_attr "type" "idiv")
8000    (set_attr "mode" "SI")])
8001
8002 (define_split
8003   [(set (match_operand:SI 0 "register_operand" "")
8004         (udiv:SI (match_operand:SI 1 "register_operand" "")
8005                  (match_operand:SI 2 "nonimmediate_operand" "")))
8006    (set (match_operand:SI 3 "register_operand" "")
8007         (umod:SI (match_dup 1) (match_dup 2)))
8008    (clobber (reg:CC FLAGS_REG))]
8009   "reload_completed"
8010   [(set (match_dup 3) (const_int 0))
8011    (parallel [(set (match_dup 0)
8012                    (udiv:SI (match_dup 1) (match_dup 2)))
8013               (set (match_dup 3)
8014                    (umod:SI (match_dup 1) (match_dup 2)))
8015               (use (match_dup 3))
8016               (clobber (reg:CC FLAGS_REG))])]
8017   "")
8018
8019 (define_expand "udivmodhi4"
8020   [(set (match_dup 4) (const_int 0))
8021    (parallel [(set (match_operand:HI 0 "register_operand" "")
8022                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8023                             (match_operand:HI 2 "nonimmediate_operand" "")))
8024               (set (match_operand:HI 3 "register_operand" "")
8025                    (umod:HI (match_dup 1) (match_dup 2)))
8026               (use (match_dup 4))
8027               (clobber (reg:CC FLAGS_REG))])]
8028   "TARGET_HIMODE_MATH"
8029   "operands[4] = gen_reg_rtx (HImode);")
8030
8031 (define_insn "*udivmodhi_noext"
8032   [(set (match_operand:HI 0 "register_operand" "=a")
8033         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8034                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8035    (set (match_operand:HI 3 "register_operand" "=d")
8036         (umod:HI (match_dup 1) (match_dup 2)))
8037    (use (match_operand:HI 4 "register_operand" "3"))
8038    (clobber (reg:CC FLAGS_REG))]
8039   ""
8040   "div{w}\t%2"
8041   [(set_attr "type" "idiv")
8042    (set_attr "mode" "HI")])
8043
8044 ;; We cannot use div/idiv for double division, because it causes
8045 ;; "division by zero" on the overflow and that's not what we expect
8046 ;; from truncate.  Because true (non truncating) double division is
8047 ;; never generated, we can't create this insn anyway.
8048 ;
8049 ;(define_insn ""
8050 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8051 ;       (truncate:SI
8052 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8053 ;                  (zero_extend:DI
8054 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8055 ;   (set (match_operand:SI 3 "register_operand" "=d")
8056 ;       (truncate:SI
8057 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8058 ;   (clobber (reg:CC FLAGS_REG))]
8059 ;  ""
8060 ;  "div{l}\t{%2, %0|%0, %2}"
8061 ;  [(set_attr "type" "idiv")])
8062 \f
8063 ;;- Logical AND instructions
8064
8065 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8066 ;; Note that this excludes ah.
8067
8068 (define_insn "*testdi_1_rex64"
8069   [(set (reg FLAGS_REG)
8070         (compare
8071           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8072                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8073           (const_int 0)))]
8074   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8075    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8076   "@
8077    test{l}\t{%k1, %k0|%k0, %k1}
8078    test{l}\t{%k1, %k0|%k0, %k1}
8079    test{q}\t{%1, %0|%0, %1}
8080    test{q}\t{%1, %0|%0, %1}
8081    test{q}\t{%1, %0|%0, %1}"
8082   [(set_attr "type" "test")
8083    (set_attr "modrm" "0,1,0,1,1")
8084    (set_attr "mode" "SI,SI,DI,DI,DI")
8085    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8086
8087 (define_insn "testsi_1"
8088   [(set (reg FLAGS_REG)
8089         (compare
8090           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8091                   (match_operand:SI 1 "general_operand" "in,in,rin"))
8092           (const_int 0)))]
8093   "ix86_match_ccmode (insn, CCNOmode)
8094    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8095   "test{l}\t{%1, %0|%0, %1}"
8096   [(set_attr "type" "test")
8097    (set_attr "modrm" "0,1,1")
8098    (set_attr "mode" "SI")
8099    (set_attr "pent_pair" "uv,np,uv")])
8100
8101 (define_expand "testsi_ccno_1"
8102   [(set (reg:CCNO FLAGS_REG)
8103         (compare:CCNO
8104           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8105                   (match_operand:SI 1 "nonmemory_operand" ""))
8106           (const_int 0)))]
8107   ""
8108   "")
8109
8110 (define_insn "*testhi_1"
8111   [(set (reg FLAGS_REG)
8112         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8113                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8114                  (const_int 0)))]
8115   "ix86_match_ccmode (insn, CCNOmode)
8116    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8117   "test{w}\t{%1, %0|%0, %1}"
8118   [(set_attr "type" "test")
8119    (set_attr "modrm" "0,1,1")
8120    (set_attr "mode" "HI")
8121    (set_attr "pent_pair" "uv,np,uv")])
8122
8123 (define_expand "testqi_ccz_1"
8124   [(set (reg:CCZ FLAGS_REG)
8125         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8126                              (match_operand:QI 1 "nonmemory_operand" ""))
8127                  (const_int 0)))]
8128   ""
8129   "")
8130
8131 (define_insn "*testqi_1_maybe_si"
8132   [(set (reg FLAGS_REG)
8133         (compare
8134           (and:QI
8135             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8136             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8137           (const_int 0)))]
8138    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8139     && ix86_match_ccmode (insn,
8140                          CONST_INT_P (operands[1])
8141                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8142 {
8143   if (which_alternative == 3)
8144     {
8145       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8146         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8147       return "test{l}\t{%1, %k0|%k0, %1}";
8148     }
8149   return "test{b}\t{%1, %0|%0, %1}";
8150 }
8151   [(set_attr "type" "test")
8152    (set_attr "modrm" "0,1,1,1")
8153    (set_attr "mode" "QI,QI,QI,SI")
8154    (set_attr "pent_pair" "uv,np,uv,np")])
8155
8156 (define_insn "*testqi_1"
8157   [(set (reg FLAGS_REG)
8158         (compare
8159           (and:QI
8160             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8161             (match_operand:QI 1 "general_operand" "n,n,qn"))
8162           (const_int 0)))]
8163   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8164    && ix86_match_ccmode (insn, CCNOmode)"
8165   "test{b}\t{%1, %0|%0, %1}"
8166   [(set_attr "type" "test")
8167    (set_attr "modrm" "0,1,1")
8168    (set_attr "mode" "QI")
8169    (set_attr "pent_pair" "uv,np,uv")])
8170
8171 (define_expand "testqi_ext_ccno_0"
8172   [(set (reg:CCNO FLAGS_REG)
8173         (compare:CCNO
8174           (and:SI
8175             (zero_extract:SI
8176               (match_operand 0 "ext_register_operand" "")
8177               (const_int 8)
8178               (const_int 8))
8179             (match_operand 1 "const_int_operand" ""))
8180           (const_int 0)))]
8181   ""
8182   "")
8183
8184 (define_insn "*testqi_ext_0"
8185   [(set (reg FLAGS_REG)
8186         (compare
8187           (and:SI
8188             (zero_extract:SI
8189               (match_operand 0 "ext_register_operand" "Q")
8190               (const_int 8)
8191               (const_int 8))
8192             (match_operand 1 "const_int_operand" "n"))
8193           (const_int 0)))]
8194   "ix86_match_ccmode (insn, CCNOmode)"
8195   "test{b}\t{%1, %h0|%h0, %1}"
8196   [(set_attr "type" "test")
8197    (set_attr "mode" "QI")
8198    (set_attr "length_immediate" "1")
8199    (set_attr "pent_pair" "np")])
8200
8201 (define_insn "*testqi_ext_1"
8202   [(set (reg FLAGS_REG)
8203         (compare
8204           (and:SI
8205             (zero_extract:SI
8206               (match_operand 0 "ext_register_operand" "Q")
8207               (const_int 8)
8208               (const_int 8))
8209             (zero_extend:SI
8210               (match_operand:QI 1 "general_operand" "Qm")))
8211           (const_int 0)))]
8212   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8213    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8214   "test{b}\t{%1, %h0|%h0, %1}"
8215   [(set_attr "type" "test")
8216    (set_attr "mode" "QI")])
8217
8218 (define_insn "*testqi_ext_1_rex64"
8219   [(set (reg FLAGS_REG)
8220         (compare
8221           (and:SI
8222             (zero_extract:SI
8223               (match_operand 0 "ext_register_operand" "Q")
8224               (const_int 8)
8225               (const_int 8))
8226             (zero_extend:SI
8227               (match_operand:QI 1 "register_operand" "Q")))
8228           (const_int 0)))]
8229   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8230   "test{b}\t{%1, %h0|%h0, %1}"
8231   [(set_attr "type" "test")
8232    (set_attr "mode" "QI")])
8233
8234 (define_insn "*testqi_ext_2"
8235   [(set (reg FLAGS_REG)
8236         (compare
8237           (and:SI
8238             (zero_extract:SI
8239               (match_operand 0 "ext_register_operand" "Q")
8240               (const_int 8)
8241               (const_int 8))
8242             (zero_extract:SI
8243               (match_operand 1 "ext_register_operand" "Q")
8244               (const_int 8)
8245               (const_int 8)))
8246           (const_int 0)))]
8247   "ix86_match_ccmode (insn, CCNOmode)"
8248   "test{b}\t{%h1, %h0|%h0, %h1}"
8249   [(set_attr "type" "test")
8250    (set_attr "mode" "QI")])
8251
8252 ;; Combine likes to form bit extractions for some tests.  Humor it.
8253 (define_insn "*testqi_ext_3"
8254   [(set (reg FLAGS_REG)
8255         (compare (zero_extract:SI
8256                    (match_operand 0 "nonimmediate_operand" "rm")
8257                    (match_operand:SI 1 "const_int_operand" "")
8258                    (match_operand:SI 2 "const_int_operand" ""))
8259                  (const_int 0)))]
8260   "ix86_match_ccmode (insn, CCNOmode)
8261    && INTVAL (operands[1]) > 0
8262    && INTVAL (operands[2]) >= 0
8263    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8264    && (GET_MODE (operands[0]) == SImode
8265        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8266        || GET_MODE (operands[0]) == HImode
8267        || GET_MODE (operands[0]) == QImode)"
8268   "#")
8269
8270 (define_insn "*testqi_ext_3_rex64"
8271   [(set (reg FLAGS_REG)
8272         (compare (zero_extract:DI
8273                    (match_operand 0 "nonimmediate_operand" "rm")
8274                    (match_operand:DI 1 "const_int_operand" "")
8275                    (match_operand:DI 2 "const_int_operand" ""))
8276                  (const_int 0)))]
8277   "TARGET_64BIT
8278    && ix86_match_ccmode (insn, CCNOmode)
8279    && INTVAL (operands[1]) > 0
8280    && INTVAL (operands[2]) >= 0
8281    /* Ensure that resulting mask is zero or sign extended operand.  */
8282    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8283        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8284            && INTVAL (operands[1]) > 32))
8285    && (GET_MODE (operands[0]) == SImode
8286        || GET_MODE (operands[0]) == DImode
8287        || GET_MODE (operands[0]) == HImode
8288        || GET_MODE (operands[0]) == QImode)"
8289   "#")
8290
8291 (define_split
8292   [(set (match_operand 0 "flags_reg_operand" "")
8293         (match_operator 1 "compare_operator"
8294           [(zero_extract
8295              (match_operand 2 "nonimmediate_operand" "")
8296              (match_operand 3 "const_int_operand" "")
8297              (match_operand 4 "const_int_operand" ""))
8298            (const_int 0)]))]
8299   "ix86_match_ccmode (insn, CCNOmode)"
8300   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8301 {
8302   rtx val = operands[2];
8303   HOST_WIDE_INT len = INTVAL (operands[3]);
8304   HOST_WIDE_INT pos = INTVAL (operands[4]);
8305   HOST_WIDE_INT mask;
8306   enum machine_mode mode, submode;
8307
8308   mode = GET_MODE (val);
8309   if (MEM_P (val))
8310     {
8311       /* ??? Combine likes to put non-volatile mem extractions in QImode
8312          no matter the size of the test.  So find a mode that works.  */
8313       if (! MEM_VOLATILE_P (val))
8314         {
8315           mode = smallest_mode_for_size (pos + len, MODE_INT);
8316           val = adjust_address (val, mode, 0);
8317         }
8318     }
8319   else if (GET_CODE (val) == SUBREG
8320            && (submode = GET_MODE (SUBREG_REG (val)),
8321                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8322            && pos + len <= GET_MODE_BITSIZE (submode))
8323     {
8324       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8325       mode = submode;
8326       val = SUBREG_REG (val);
8327     }
8328   else if (mode == HImode && pos + len <= 8)
8329     {
8330       /* Small HImode tests can be converted to QImode.  */
8331       mode = QImode;
8332       val = gen_lowpart (QImode, val);
8333     }
8334
8335   if (len == HOST_BITS_PER_WIDE_INT)
8336     mask = -1;
8337   else
8338     mask = ((HOST_WIDE_INT)1 << len) - 1;
8339   mask <<= pos;
8340
8341   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8342 })
8343
8344 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8345 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8346 ;; this is relatively important trick.
8347 ;; Do the conversion only post-reload to avoid limiting of the register class
8348 ;; to QI regs.
8349 (define_split
8350   [(set (match_operand 0 "flags_reg_operand" "")
8351         (match_operator 1 "compare_operator"
8352           [(and (match_operand 2 "register_operand" "")
8353                 (match_operand 3 "const_int_operand" ""))
8354            (const_int 0)]))]
8355    "reload_completed
8356     && QI_REG_P (operands[2])
8357     && GET_MODE (operands[2]) != QImode
8358     && ((ix86_match_ccmode (insn, CCZmode)
8359          && !(INTVAL (operands[3]) & ~(255 << 8)))
8360         || (ix86_match_ccmode (insn, CCNOmode)
8361             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8362   [(set (match_dup 0)
8363         (match_op_dup 1
8364           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8365                    (match_dup 3))
8366            (const_int 0)]))]
8367   "operands[2] = gen_lowpart (SImode, operands[2]);
8368    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8369
8370 (define_split
8371   [(set (match_operand 0 "flags_reg_operand" "")
8372         (match_operator 1 "compare_operator"
8373           [(and (match_operand 2 "nonimmediate_operand" "")
8374                 (match_operand 3 "const_int_operand" ""))
8375            (const_int 0)]))]
8376    "reload_completed
8377     && GET_MODE (operands[2]) != QImode
8378     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8379     && ((ix86_match_ccmode (insn, CCZmode)
8380          && !(INTVAL (operands[3]) & ~255))
8381         || (ix86_match_ccmode (insn, CCNOmode)
8382             && !(INTVAL (operands[3]) & ~127)))"
8383   [(set (match_dup 0)
8384         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8385                          (const_int 0)]))]
8386   "operands[2] = gen_lowpart (QImode, operands[2]);
8387    operands[3] = gen_lowpart (QImode, operands[3]);")
8388
8389
8390 ;; %%% This used to optimize known byte-wide and operations to memory,
8391 ;; and sometimes to QImode registers.  If this is considered useful,
8392 ;; it should be done with splitters.
8393
8394 (define_expand "anddi3"
8395   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8396         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8397                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8398    (clobber (reg:CC FLAGS_REG))]
8399   "TARGET_64BIT"
8400   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8401
8402 (define_insn "*anddi_1_rex64"
8403   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8404         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8405                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8406    (clobber (reg:CC FLAGS_REG))]
8407   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8408 {
8409   switch (get_attr_type (insn))
8410     {
8411     case TYPE_IMOVX:
8412       {
8413         enum machine_mode mode;
8414
8415         gcc_assert (CONST_INT_P (operands[2]));
8416         if (INTVAL (operands[2]) == 0xff)
8417           mode = QImode;
8418         else
8419           {
8420             gcc_assert (INTVAL (operands[2]) == 0xffff);
8421             mode = HImode;
8422           }
8423
8424         operands[1] = gen_lowpart (mode, operands[1]);
8425         if (mode == QImode)
8426           return "movz{bq|x}\t{%1,%0|%0, %1}";
8427         else
8428           return "movz{wq|x}\t{%1,%0|%0, %1}";
8429       }
8430
8431     default:
8432       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8433       if (get_attr_mode (insn) == MODE_SI)
8434         return "and{l}\t{%k2, %k0|%k0, %k2}";
8435       else
8436         return "and{q}\t{%2, %0|%0, %2}";
8437     }
8438 }
8439   [(set_attr "type" "alu,alu,alu,imovx")
8440    (set_attr "length_immediate" "*,*,*,0")
8441    (set_attr "mode" "SI,DI,DI,DI")])
8442
8443 (define_insn "*anddi_2"
8444   [(set (reg FLAGS_REG)
8445         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8446                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8447                  (const_int 0)))
8448    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8449         (and:DI (match_dup 1) (match_dup 2)))]
8450   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8451    && ix86_binary_operator_ok (AND, DImode, operands)"
8452   "@
8453    and{l}\t{%k2, %k0|%k0, %k2}
8454    and{q}\t{%2, %0|%0, %2}
8455    and{q}\t{%2, %0|%0, %2}"
8456   [(set_attr "type" "alu")
8457    (set_attr "mode" "SI,DI,DI")])
8458
8459 (define_expand "andsi3"
8460   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8461         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8462                 (match_operand:SI 2 "general_operand" "")))
8463    (clobber (reg:CC FLAGS_REG))]
8464   ""
8465   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8466
8467 (define_insn "*andsi_1"
8468   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8469         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8470                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8471    (clobber (reg:CC FLAGS_REG))]
8472   "ix86_binary_operator_ok (AND, SImode, operands)"
8473 {
8474   switch (get_attr_type (insn))
8475     {
8476     case TYPE_IMOVX:
8477       {
8478         enum machine_mode mode;
8479
8480         gcc_assert (CONST_INT_P (operands[2]));
8481         if (INTVAL (operands[2]) == 0xff)
8482           mode = QImode;
8483         else
8484           {
8485             gcc_assert (INTVAL (operands[2]) == 0xffff);
8486             mode = HImode;
8487           }
8488
8489         operands[1] = gen_lowpart (mode, operands[1]);
8490         if (mode == QImode)
8491           return "movz{bl|x}\t{%1,%0|%0, %1}";
8492         else
8493           return "movz{wl|x}\t{%1,%0|%0, %1}";
8494       }
8495
8496     default:
8497       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8498       return "and{l}\t{%2, %0|%0, %2}";
8499     }
8500 }
8501   [(set_attr "type" "alu,alu,imovx")
8502    (set_attr "length_immediate" "*,*,0")
8503    (set_attr "mode" "SI")])
8504
8505 (define_split
8506   [(set (match_operand 0 "register_operand" "")
8507         (and (match_dup 0)
8508              (const_int -65536)))
8509    (clobber (reg:CC FLAGS_REG))]
8510   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8511   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8512   "operands[1] = gen_lowpart (HImode, operands[0]);")
8513
8514 (define_split
8515   [(set (match_operand 0 "ext_register_operand" "")
8516         (and (match_dup 0)
8517              (const_int -256)))
8518    (clobber (reg:CC FLAGS_REG))]
8519   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8520   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8521   "operands[1] = gen_lowpart (QImode, operands[0]);")
8522
8523 (define_split
8524   [(set (match_operand 0 "ext_register_operand" "")
8525         (and (match_dup 0)
8526              (const_int -65281)))
8527    (clobber (reg:CC FLAGS_REG))]
8528   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8529   [(parallel [(set (zero_extract:SI (match_dup 0)
8530                                     (const_int 8)
8531                                     (const_int 8))
8532                    (xor:SI
8533                      (zero_extract:SI (match_dup 0)
8534                                       (const_int 8)
8535                                       (const_int 8))
8536                      (zero_extract:SI (match_dup 0)
8537                                       (const_int 8)
8538                                       (const_int 8))))
8539               (clobber (reg:CC FLAGS_REG))])]
8540   "operands[0] = gen_lowpart (SImode, operands[0]);")
8541
8542 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8543 (define_insn "*andsi_1_zext"
8544   [(set (match_operand:DI 0 "register_operand" "=r")
8545         (zero_extend:DI
8546           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8547                   (match_operand:SI 2 "general_operand" "rim"))))
8548    (clobber (reg:CC FLAGS_REG))]
8549   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8550   "and{l}\t{%2, %k0|%k0, %2}"
8551   [(set_attr "type" "alu")
8552    (set_attr "mode" "SI")])
8553
8554 (define_insn "*andsi_2"
8555   [(set (reg FLAGS_REG)
8556         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8557                          (match_operand:SI 2 "general_operand" "rim,ri"))
8558                  (const_int 0)))
8559    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8560         (and:SI (match_dup 1) (match_dup 2)))]
8561   "ix86_match_ccmode (insn, CCNOmode)
8562    && ix86_binary_operator_ok (AND, SImode, operands)"
8563   "and{l}\t{%2, %0|%0, %2}"
8564   [(set_attr "type" "alu")
8565    (set_attr "mode" "SI")])
8566
8567 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8568 (define_insn "*andsi_2_zext"
8569   [(set (reg FLAGS_REG)
8570         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8571                          (match_operand:SI 2 "general_operand" "rim"))
8572                  (const_int 0)))
8573    (set (match_operand:DI 0 "register_operand" "=r")
8574         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8575   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8576    && ix86_binary_operator_ok (AND, SImode, operands)"
8577   "and{l}\t{%2, %k0|%k0, %2}"
8578   [(set_attr "type" "alu")
8579    (set_attr "mode" "SI")])
8580
8581 (define_expand "andhi3"
8582   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8583         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8584                 (match_operand:HI 2 "general_operand" "")))
8585    (clobber (reg:CC FLAGS_REG))]
8586   "TARGET_HIMODE_MATH"
8587   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8588
8589 (define_insn "*andhi_1"
8590   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8591         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8592                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8593    (clobber (reg:CC FLAGS_REG))]
8594   "ix86_binary_operator_ok (AND, HImode, operands)"
8595 {
8596   switch (get_attr_type (insn))
8597     {
8598     case TYPE_IMOVX:
8599       gcc_assert (CONST_INT_P (operands[2]));
8600       gcc_assert (INTVAL (operands[2]) == 0xff);
8601       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8602
8603     default:
8604       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8605
8606       return "and{w}\t{%2, %0|%0, %2}";
8607     }
8608 }
8609   [(set_attr "type" "alu,alu,imovx")
8610    (set_attr "length_immediate" "*,*,0")
8611    (set_attr "mode" "HI,HI,SI")])
8612
8613 (define_insn "*andhi_2"
8614   [(set (reg FLAGS_REG)
8615         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8616                          (match_operand:HI 2 "general_operand" "rim,ri"))
8617                  (const_int 0)))
8618    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8619         (and:HI (match_dup 1) (match_dup 2)))]
8620   "ix86_match_ccmode (insn, CCNOmode)
8621    && ix86_binary_operator_ok (AND, HImode, operands)"
8622   "and{w}\t{%2, %0|%0, %2}"
8623   [(set_attr "type" "alu")
8624    (set_attr "mode" "HI")])
8625
8626 (define_expand "andqi3"
8627   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8628         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8629                 (match_operand:QI 2 "general_operand" "")))
8630    (clobber (reg:CC FLAGS_REG))]
8631   "TARGET_QIMODE_MATH"
8632   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8633
8634 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8635 (define_insn "*andqi_1"
8636   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8637         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8638                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8639    (clobber (reg:CC FLAGS_REG))]
8640   "ix86_binary_operator_ok (AND, QImode, operands)"
8641   "@
8642    and{b}\t{%2, %0|%0, %2}
8643    and{b}\t{%2, %0|%0, %2}
8644    and{l}\t{%k2, %k0|%k0, %k2}"
8645   [(set_attr "type" "alu")
8646    (set_attr "mode" "QI,QI,SI")])
8647
8648 (define_insn "*andqi_1_slp"
8649   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8650         (and:QI (match_dup 0)
8651                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8652    (clobber (reg:CC FLAGS_REG))]
8653   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8654    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8655   "and{b}\t{%1, %0|%0, %1}"
8656   [(set_attr "type" "alu1")
8657    (set_attr "mode" "QI")])
8658
8659 (define_insn "*andqi_2_maybe_si"
8660   [(set (reg FLAGS_REG)
8661         (compare (and:QI
8662                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8663                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8664                  (const_int 0)))
8665    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8666         (and:QI (match_dup 1) (match_dup 2)))]
8667   "ix86_binary_operator_ok (AND, QImode, operands)
8668    && ix86_match_ccmode (insn,
8669                          CONST_INT_P (operands[2])
8670                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8671 {
8672   if (which_alternative == 2)
8673     {
8674       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8675         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8676       return "and{l}\t{%2, %k0|%k0, %2}";
8677     }
8678   return "and{b}\t{%2, %0|%0, %2}";
8679 }
8680   [(set_attr "type" "alu")
8681    (set_attr "mode" "QI,QI,SI")])
8682
8683 (define_insn "*andqi_2"
8684   [(set (reg FLAGS_REG)
8685         (compare (and:QI
8686                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8687                    (match_operand:QI 2 "general_operand" "qim,qi"))
8688                  (const_int 0)))
8689    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8690         (and:QI (match_dup 1) (match_dup 2)))]
8691   "ix86_match_ccmode (insn, CCNOmode)
8692    && ix86_binary_operator_ok (AND, QImode, operands)"
8693   "and{b}\t{%2, %0|%0, %2}"
8694   [(set_attr "type" "alu")
8695    (set_attr "mode" "QI")])
8696
8697 (define_insn "*andqi_2_slp"
8698   [(set (reg FLAGS_REG)
8699         (compare (and:QI
8700                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8701                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8702                  (const_int 0)))
8703    (set (strict_low_part (match_dup 0))
8704         (and:QI (match_dup 0) (match_dup 1)))]
8705   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8706    && ix86_match_ccmode (insn, CCNOmode)
8707    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8708   "and{b}\t{%1, %0|%0, %1}"
8709   [(set_attr "type" "alu1")
8710    (set_attr "mode" "QI")])
8711
8712 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8713 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8714 ;; for a QImode operand, which of course failed.
8715
8716 (define_insn "andqi_ext_0"
8717   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8718                          (const_int 8)
8719                          (const_int 8))
8720         (and:SI
8721           (zero_extract:SI
8722             (match_operand 1 "ext_register_operand" "0")
8723             (const_int 8)
8724             (const_int 8))
8725           (match_operand 2 "const_int_operand" "n")))
8726    (clobber (reg:CC FLAGS_REG))]
8727   ""
8728   "and{b}\t{%2, %h0|%h0, %2}"
8729   [(set_attr "type" "alu")
8730    (set_attr "length_immediate" "1")
8731    (set_attr "mode" "QI")])
8732
8733 ;; Generated by peephole translating test to and.  This shows up
8734 ;; often in fp comparisons.
8735
8736 (define_insn "*andqi_ext_0_cc"
8737   [(set (reg FLAGS_REG)
8738         (compare
8739           (and:SI
8740             (zero_extract:SI
8741               (match_operand 1 "ext_register_operand" "0")
8742               (const_int 8)
8743               (const_int 8))
8744             (match_operand 2 "const_int_operand" "n"))
8745           (const_int 0)))
8746    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8747                          (const_int 8)
8748                          (const_int 8))
8749         (and:SI
8750           (zero_extract:SI
8751             (match_dup 1)
8752             (const_int 8)
8753             (const_int 8))
8754           (match_dup 2)))]
8755   "ix86_match_ccmode (insn, CCNOmode)"
8756   "and{b}\t{%2, %h0|%h0, %2}"
8757   [(set_attr "type" "alu")
8758    (set_attr "length_immediate" "1")
8759    (set_attr "mode" "QI")])
8760
8761 (define_insn "*andqi_ext_1"
8762   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8763                          (const_int 8)
8764                          (const_int 8))
8765         (and:SI
8766           (zero_extract:SI
8767             (match_operand 1 "ext_register_operand" "0")
8768             (const_int 8)
8769             (const_int 8))
8770           (zero_extend:SI
8771             (match_operand:QI 2 "general_operand" "Qm"))))
8772    (clobber (reg:CC FLAGS_REG))]
8773   "!TARGET_64BIT"
8774   "and{b}\t{%2, %h0|%h0, %2}"
8775   [(set_attr "type" "alu")
8776    (set_attr "length_immediate" "0")
8777    (set_attr "mode" "QI")])
8778
8779 (define_insn "*andqi_ext_1_rex64"
8780   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8781                          (const_int 8)
8782                          (const_int 8))
8783         (and:SI
8784           (zero_extract:SI
8785             (match_operand 1 "ext_register_operand" "0")
8786             (const_int 8)
8787             (const_int 8))
8788           (zero_extend:SI
8789             (match_operand 2 "ext_register_operand" "Q"))))
8790    (clobber (reg:CC FLAGS_REG))]
8791   "TARGET_64BIT"
8792   "and{b}\t{%2, %h0|%h0, %2}"
8793   [(set_attr "type" "alu")
8794    (set_attr "length_immediate" "0")
8795    (set_attr "mode" "QI")])
8796
8797 (define_insn "*andqi_ext_2"
8798   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8799                          (const_int 8)
8800                          (const_int 8))
8801         (and:SI
8802           (zero_extract:SI
8803             (match_operand 1 "ext_register_operand" "%0")
8804             (const_int 8)
8805             (const_int 8))
8806           (zero_extract:SI
8807             (match_operand 2 "ext_register_operand" "Q")
8808             (const_int 8)
8809             (const_int 8))))
8810    (clobber (reg:CC FLAGS_REG))]
8811   ""
8812   "and{b}\t{%h2, %h0|%h0, %h2}"
8813   [(set_attr "type" "alu")
8814    (set_attr "length_immediate" "0")
8815    (set_attr "mode" "QI")])
8816
8817 ;; Convert wide AND instructions with immediate operand to shorter QImode
8818 ;; equivalents when possible.
8819 ;; Don't do the splitting with memory operands, since it introduces risk
8820 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8821 ;; for size, but that can (should?) be handled by generic code instead.
8822 (define_split
8823   [(set (match_operand 0 "register_operand" "")
8824         (and (match_operand 1 "register_operand" "")
8825              (match_operand 2 "const_int_operand" "")))
8826    (clobber (reg:CC FLAGS_REG))]
8827    "reload_completed
8828     && QI_REG_P (operands[0])
8829     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8830     && !(~INTVAL (operands[2]) & ~(255 << 8))
8831     && GET_MODE (operands[0]) != QImode"
8832   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8833                    (and:SI (zero_extract:SI (match_dup 1)
8834                                             (const_int 8) (const_int 8))
8835                            (match_dup 2)))
8836               (clobber (reg:CC FLAGS_REG))])]
8837   "operands[0] = gen_lowpart (SImode, operands[0]);
8838    operands[1] = gen_lowpart (SImode, operands[1]);
8839    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8840
8841 ;; Since AND can be encoded with sign extended immediate, this is only
8842 ;; profitable when 7th bit is not set.
8843 (define_split
8844   [(set (match_operand 0 "register_operand" "")
8845         (and (match_operand 1 "general_operand" "")
8846              (match_operand 2 "const_int_operand" "")))
8847    (clobber (reg:CC FLAGS_REG))]
8848    "reload_completed
8849     && ANY_QI_REG_P (operands[0])
8850     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8851     && !(~INTVAL (operands[2]) & ~255)
8852     && !(INTVAL (operands[2]) & 128)
8853     && GET_MODE (operands[0]) != QImode"
8854   [(parallel [(set (strict_low_part (match_dup 0))
8855                    (and:QI (match_dup 1)
8856                            (match_dup 2)))
8857               (clobber (reg:CC FLAGS_REG))])]
8858   "operands[0] = gen_lowpart (QImode, operands[0]);
8859    operands[1] = gen_lowpart (QImode, operands[1]);
8860    operands[2] = gen_lowpart (QImode, operands[2]);")
8861 \f
8862 ;; Logical inclusive OR instructions
8863
8864 ;; %%% This used to optimize known byte-wide and operations to memory.
8865 ;; If this is considered useful, it should be done with splitters.
8866
8867 (define_expand "iordi3"
8868   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8869         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8870                 (match_operand:DI 2 "x86_64_general_operand" "")))
8871    (clobber (reg:CC FLAGS_REG))]
8872   "TARGET_64BIT"
8873   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8874
8875 (define_insn "*iordi_1_rex64"
8876   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8877         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8878                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8879    (clobber (reg:CC FLAGS_REG))]
8880   "TARGET_64BIT
8881    && ix86_binary_operator_ok (IOR, DImode, operands)"
8882   "or{q}\t{%2, %0|%0, %2}"
8883   [(set_attr "type" "alu")
8884    (set_attr "mode" "DI")])
8885
8886 (define_insn "*iordi_2_rex64"
8887   [(set (reg FLAGS_REG)
8888         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8889                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8890                  (const_int 0)))
8891    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8892         (ior:DI (match_dup 1) (match_dup 2)))]
8893   "TARGET_64BIT
8894    && ix86_match_ccmode (insn, CCNOmode)
8895    && ix86_binary_operator_ok (IOR, DImode, operands)"
8896   "or{q}\t{%2, %0|%0, %2}"
8897   [(set_attr "type" "alu")
8898    (set_attr "mode" "DI")])
8899
8900 (define_insn "*iordi_3_rex64"
8901   [(set (reg FLAGS_REG)
8902         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8903                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8904                  (const_int 0)))
8905    (clobber (match_scratch:DI 0 "=r"))]
8906   "TARGET_64BIT
8907    && ix86_match_ccmode (insn, CCNOmode)
8908    && ix86_binary_operator_ok (IOR, DImode, operands)"
8909   "or{q}\t{%2, %0|%0, %2}"
8910   [(set_attr "type" "alu")
8911    (set_attr "mode" "DI")])
8912
8913
8914 (define_expand "iorsi3"
8915   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8916         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8917                 (match_operand:SI 2 "general_operand" "")))
8918    (clobber (reg:CC FLAGS_REG))]
8919   ""
8920   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8921
8922 (define_insn "*iorsi_1"
8923   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8924         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8925                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8926    (clobber (reg:CC FLAGS_REG))]
8927   "ix86_binary_operator_ok (IOR, SImode, operands)"
8928   "or{l}\t{%2, %0|%0, %2}"
8929   [(set_attr "type" "alu")
8930    (set_attr "mode" "SI")])
8931
8932 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8933 (define_insn "*iorsi_1_zext"
8934   [(set (match_operand:DI 0 "register_operand" "=rm")
8935         (zero_extend:DI
8936           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8937                   (match_operand:SI 2 "general_operand" "rim"))))
8938    (clobber (reg:CC FLAGS_REG))]
8939   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8940   "or{l}\t{%2, %k0|%k0, %2}"
8941   [(set_attr "type" "alu")
8942    (set_attr "mode" "SI")])
8943
8944 (define_insn "*iorsi_1_zext_imm"
8945   [(set (match_operand:DI 0 "register_operand" "=rm")
8946         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8947                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8948    (clobber (reg:CC FLAGS_REG))]
8949   "TARGET_64BIT"
8950   "or{l}\t{%2, %k0|%k0, %2}"
8951   [(set_attr "type" "alu")
8952    (set_attr "mode" "SI")])
8953
8954 (define_insn "*iorsi_2"
8955   [(set (reg FLAGS_REG)
8956         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8957                          (match_operand:SI 2 "general_operand" "rim,ri"))
8958                  (const_int 0)))
8959    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8960         (ior:SI (match_dup 1) (match_dup 2)))]
8961   "ix86_match_ccmode (insn, CCNOmode)
8962    && ix86_binary_operator_ok (IOR, SImode, operands)"
8963   "or{l}\t{%2, %0|%0, %2}"
8964   [(set_attr "type" "alu")
8965    (set_attr "mode" "SI")])
8966
8967 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8968 ;; ??? Special case for immediate operand is missing - it is tricky.
8969 (define_insn "*iorsi_2_zext"
8970   [(set (reg FLAGS_REG)
8971         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8972                          (match_operand:SI 2 "general_operand" "rim"))
8973                  (const_int 0)))
8974    (set (match_operand:DI 0 "register_operand" "=r")
8975         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8976   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8977    && ix86_binary_operator_ok (IOR, SImode, operands)"
8978   "or{l}\t{%2, %k0|%k0, %2}"
8979   [(set_attr "type" "alu")
8980    (set_attr "mode" "SI")])
8981
8982 (define_insn "*iorsi_2_zext_imm"
8983   [(set (reg FLAGS_REG)
8984         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8985                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8986                  (const_int 0)))
8987    (set (match_operand:DI 0 "register_operand" "=r")
8988         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8989   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8990    && ix86_binary_operator_ok (IOR, SImode, operands)"
8991   "or{l}\t{%2, %k0|%k0, %2}"
8992   [(set_attr "type" "alu")
8993    (set_attr "mode" "SI")])
8994
8995 (define_insn "*iorsi_3"
8996   [(set (reg FLAGS_REG)
8997         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8998                          (match_operand:SI 2 "general_operand" "rim"))
8999                  (const_int 0)))
9000    (clobber (match_scratch:SI 0 "=r"))]
9001   "ix86_match_ccmode (insn, CCNOmode)
9002    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9003   "or{l}\t{%2, %0|%0, %2}"
9004   [(set_attr "type" "alu")
9005    (set_attr "mode" "SI")])
9006
9007 (define_expand "iorhi3"
9008   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9009         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9010                 (match_operand:HI 2 "general_operand" "")))
9011    (clobber (reg:CC FLAGS_REG))]
9012   "TARGET_HIMODE_MATH"
9013   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9014
9015 (define_insn "*iorhi_1"
9016   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9017         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9018                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9019    (clobber (reg:CC FLAGS_REG))]
9020   "ix86_binary_operator_ok (IOR, HImode, operands)"
9021   "or{w}\t{%2, %0|%0, %2}"
9022   [(set_attr "type" "alu")
9023    (set_attr "mode" "HI")])
9024
9025 (define_insn "*iorhi_2"
9026   [(set (reg FLAGS_REG)
9027         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9028                          (match_operand:HI 2 "general_operand" "rim,ri"))
9029                  (const_int 0)))
9030    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9031         (ior:HI (match_dup 1) (match_dup 2)))]
9032   "ix86_match_ccmode (insn, CCNOmode)
9033    && ix86_binary_operator_ok (IOR, HImode, operands)"
9034   "or{w}\t{%2, %0|%0, %2}"
9035   [(set_attr "type" "alu")
9036    (set_attr "mode" "HI")])
9037
9038 (define_insn "*iorhi_3"
9039   [(set (reg FLAGS_REG)
9040         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9041                          (match_operand:HI 2 "general_operand" "rim"))
9042                  (const_int 0)))
9043    (clobber (match_scratch:HI 0 "=r"))]
9044   "ix86_match_ccmode (insn, CCNOmode)
9045    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9046   "or{w}\t{%2, %0|%0, %2}"
9047   [(set_attr "type" "alu")
9048    (set_attr "mode" "HI")])
9049
9050 (define_expand "iorqi3"
9051   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9052         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9053                 (match_operand:QI 2 "general_operand" "")))
9054    (clobber (reg:CC FLAGS_REG))]
9055   "TARGET_QIMODE_MATH"
9056   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9057
9058 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9059 (define_insn "*iorqi_1"
9060   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9061         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9062                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9063    (clobber (reg:CC FLAGS_REG))]
9064   "ix86_binary_operator_ok (IOR, QImode, operands)"
9065   "@
9066    or{b}\t{%2, %0|%0, %2}
9067    or{b}\t{%2, %0|%0, %2}
9068    or{l}\t{%k2, %k0|%k0, %k2}"
9069   [(set_attr "type" "alu")
9070    (set_attr "mode" "QI,QI,SI")])
9071
9072 (define_insn "*iorqi_1_slp"
9073   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9074         (ior:QI (match_dup 0)
9075                 (match_operand:QI 1 "general_operand" "qmi,qi")))
9076    (clobber (reg:CC FLAGS_REG))]
9077   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9078    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9079   "or{b}\t{%1, %0|%0, %1}"
9080   [(set_attr "type" "alu1")
9081    (set_attr "mode" "QI")])
9082
9083 (define_insn "*iorqi_2"
9084   [(set (reg FLAGS_REG)
9085         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9086                          (match_operand:QI 2 "general_operand" "qim,qi"))
9087                  (const_int 0)))
9088    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9089         (ior:QI (match_dup 1) (match_dup 2)))]
9090   "ix86_match_ccmode (insn, CCNOmode)
9091    && ix86_binary_operator_ok (IOR, QImode, operands)"
9092   "or{b}\t{%2, %0|%0, %2}"
9093   [(set_attr "type" "alu")
9094    (set_attr "mode" "QI")])
9095
9096 (define_insn "*iorqi_2_slp"
9097   [(set (reg FLAGS_REG)
9098         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9099                          (match_operand:QI 1 "general_operand" "qim,qi"))
9100                  (const_int 0)))
9101    (set (strict_low_part (match_dup 0))
9102         (ior:QI (match_dup 0) (match_dup 1)))]
9103   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9104    && ix86_match_ccmode (insn, CCNOmode)
9105    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9106   "or{b}\t{%1, %0|%0, %1}"
9107   [(set_attr "type" "alu1")
9108    (set_attr "mode" "QI")])
9109
9110 (define_insn "*iorqi_3"
9111   [(set (reg FLAGS_REG)
9112         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9113                          (match_operand:QI 2 "general_operand" "qim"))
9114                  (const_int 0)))
9115    (clobber (match_scratch:QI 0 "=q"))]
9116   "ix86_match_ccmode (insn, CCNOmode)
9117    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9118   "or{b}\t{%2, %0|%0, %2}"
9119   [(set_attr "type" "alu")
9120    (set_attr "mode" "QI")])
9121
9122 (define_insn "iorqi_ext_0"
9123   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9124                          (const_int 8)
9125                          (const_int 8))
9126         (ior:SI
9127           (zero_extract:SI
9128             (match_operand 1 "ext_register_operand" "0")
9129             (const_int 8)
9130             (const_int 8))
9131           (match_operand 2 "const_int_operand" "n")))
9132    (clobber (reg:CC FLAGS_REG))]
9133   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9134   "or{b}\t{%2, %h0|%h0, %2}"
9135   [(set_attr "type" "alu")
9136    (set_attr "length_immediate" "1")
9137    (set_attr "mode" "QI")])
9138
9139 (define_insn "*iorqi_ext_1"
9140   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9141                          (const_int 8)
9142                          (const_int 8))
9143         (ior:SI
9144           (zero_extract:SI
9145             (match_operand 1 "ext_register_operand" "0")
9146             (const_int 8)
9147             (const_int 8))
9148           (zero_extend:SI
9149             (match_operand:QI 2 "general_operand" "Qm"))))
9150    (clobber (reg:CC FLAGS_REG))]
9151   "!TARGET_64BIT
9152    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9153   "or{b}\t{%2, %h0|%h0, %2}"
9154   [(set_attr "type" "alu")
9155    (set_attr "length_immediate" "0")
9156    (set_attr "mode" "QI")])
9157
9158 (define_insn "*iorqi_ext_1_rex64"
9159   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9160                          (const_int 8)
9161                          (const_int 8))
9162         (ior:SI
9163           (zero_extract:SI
9164             (match_operand 1 "ext_register_operand" "0")
9165             (const_int 8)
9166             (const_int 8))
9167           (zero_extend:SI
9168             (match_operand 2 "ext_register_operand" "Q"))))
9169    (clobber (reg:CC FLAGS_REG))]
9170   "TARGET_64BIT
9171    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9172   "or{b}\t{%2, %h0|%h0, %2}"
9173   [(set_attr "type" "alu")
9174    (set_attr "length_immediate" "0")
9175    (set_attr "mode" "QI")])
9176
9177 (define_insn "*iorqi_ext_2"
9178   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9179                          (const_int 8)
9180                          (const_int 8))
9181         (ior:SI
9182           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9183                            (const_int 8)
9184                            (const_int 8))
9185           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9186                            (const_int 8)
9187                            (const_int 8))))
9188    (clobber (reg:CC FLAGS_REG))]
9189   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9190   "ior{b}\t{%h2, %h0|%h0, %h2}"
9191   [(set_attr "type" "alu")
9192    (set_attr "length_immediate" "0")
9193    (set_attr "mode" "QI")])
9194
9195 (define_split
9196   [(set (match_operand 0 "register_operand" "")
9197         (ior (match_operand 1 "register_operand" "")
9198              (match_operand 2 "const_int_operand" "")))
9199    (clobber (reg:CC FLAGS_REG))]
9200    "reload_completed
9201     && QI_REG_P (operands[0])
9202     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9203     && !(INTVAL (operands[2]) & ~(255 << 8))
9204     && GET_MODE (operands[0]) != QImode"
9205   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9206                    (ior:SI (zero_extract:SI (match_dup 1)
9207                                             (const_int 8) (const_int 8))
9208                            (match_dup 2)))
9209               (clobber (reg:CC FLAGS_REG))])]
9210   "operands[0] = gen_lowpart (SImode, operands[0]);
9211    operands[1] = gen_lowpart (SImode, operands[1]);
9212    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9213
9214 ;; Since OR can be encoded with sign extended immediate, this is only
9215 ;; profitable when 7th bit is set.
9216 (define_split
9217   [(set (match_operand 0 "register_operand" "")
9218         (ior (match_operand 1 "general_operand" "")
9219              (match_operand 2 "const_int_operand" "")))
9220    (clobber (reg:CC FLAGS_REG))]
9221    "reload_completed
9222     && ANY_QI_REG_P (operands[0])
9223     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9224     && !(INTVAL (operands[2]) & ~255)
9225     && (INTVAL (operands[2]) & 128)
9226     && GET_MODE (operands[0]) != QImode"
9227   [(parallel [(set (strict_low_part (match_dup 0))
9228                    (ior:QI (match_dup 1)
9229                            (match_dup 2)))
9230               (clobber (reg:CC FLAGS_REG))])]
9231   "operands[0] = gen_lowpart (QImode, operands[0]);
9232    operands[1] = gen_lowpart (QImode, operands[1]);
9233    operands[2] = gen_lowpart (QImode, operands[2]);")
9234 \f
9235 ;; Logical XOR instructions
9236
9237 ;; %%% This used to optimize known byte-wide and operations to memory.
9238 ;; If this is considered useful, it should be done with splitters.
9239
9240 (define_expand "xordi3"
9241   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9242         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9243                 (match_operand:DI 2 "x86_64_general_operand" "")))
9244    (clobber (reg:CC FLAGS_REG))]
9245   "TARGET_64BIT"
9246   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9247
9248 (define_insn "*xordi_1_rex64"
9249   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9250         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9251                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9252    (clobber (reg:CC FLAGS_REG))]
9253   "TARGET_64BIT
9254    && ix86_binary_operator_ok (XOR, DImode, operands)"
9255   "@
9256    xor{q}\t{%2, %0|%0, %2}
9257    xor{q}\t{%2, %0|%0, %2}"
9258   [(set_attr "type" "alu")
9259    (set_attr "mode" "DI,DI")])
9260
9261 (define_insn "*xordi_2_rex64"
9262   [(set (reg FLAGS_REG)
9263         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9264                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9265                  (const_int 0)))
9266    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9267         (xor:DI (match_dup 1) (match_dup 2)))]
9268   "TARGET_64BIT
9269    && ix86_match_ccmode (insn, CCNOmode)
9270    && ix86_binary_operator_ok (XOR, DImode, operands)"
9271   "@
9272    xor{q}\t{%2, %0|%0, %2}
9273    xor{q}\t{%2, %0|%0, %2}"
9274   [(set_attr "type" "alu")
9275    (set_attr "mode" "DI,DI")])
9276
9277 (define_insn "*xordi_3_rex64"
9278   [(set (reg FLAGS_REG)
9279         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9280                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9281                  (const_int 0)))
9282    (clobber (match_scratch:DI 0 "=r"))]
9283   "TARGET_64BIT
9284    && ix86_match_ccmode (insn, CCNOmode)
9285    && ix86_binary_operator_ok (XOR, DImode, operands)"
9286   "xor{q}\t{%2, %0|%0, %2}"
9287   [(set_attr "type" "alu")
9288    (set_attr "mode" "DI")])
9289
9290 (define_expand "xorsi3"
9291   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9292         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9293                 (match_operand:SI 2 "general_operand" "")))
9294    (clobber (reg:CC FLAGS_REG))]
9295   ""
9296   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9297
9298 (define_insn "*xorsi_1"
9299   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9300         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9301                 (match_operand:SI 2 "general_operand" "ri,rm")))
9302    (clobber (reg:CC FLAGS_REG))]
9303   "ix86_binary_operator_ok (XOR, SImode, operands)"
9304   "xor{l}\t{%2, %0|%0, %2}"
9305   [(set_attr "type" "alu")
9306    (set_attr "mode" "SI")])
9307
9308 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9309 ;; Add speccase for immediates
9310 (define_insn "*xorsi_1_zext"
9311   [(set (match_operand:DI 0 "register_operand" "=r")
9312         (zero_extend:DI
9313           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9314                   (match_operand:SI 2 "general_operand" "rim"))))
9315    (clobber (reg:CC FLAGS_REG))]
9316   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9317   "xor{l}\t{%2, %k0|%k0, %2}"
9318   [(set_attr "type" "alu")
9319    (set_attr "mode" "SI")])
9320
9321 (define_insn "*xorsi_1_zext_imm"
9322   [(set (match_operand:DI 0 "register_operand" "=r")
9323         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9324                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9325    (clobber (reg:CC FLAGS_REG))]
9326   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9327   "xor{l}\t{%2, %k0|%k0, %2}"
9328   [(set_attr "type" "alu")
9329    (set_attr "mode" "SI")])
9330
9331 (define_insn "*xorsi_2"
9332   [(set (reg FLAGS_REG)
9333         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9334                          (match_operand:SI 2 "general_operand" "rim,ri"))
9335                  (const_int 0)))
9336    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9337         (xor:SI (match_dup 1) (match_dup 2)))]
9338   "ix86_match_ccmode (insn, CCNOmode)
9339    && ix86_binary_operator_ok (XOR, SImode, operands)"
9340   "xor{l}\t{%2, %0|%0, %2}"
9341   [(set_attr "type" "alu")
9342    (set_attr "mode" "SI")])
9343
9344 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9345 ;; ??? Special case for immediate operand is missing - it is tricky.
9346 (define_insn "*xorsi_2_zext"
9347   [(set (reg FLAGS_REG)
9348         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9349                          (match_operand:SI 2 "general_operand" "rim"))
9350                  (const_int 0)))
9351    (set (match_operand:DI 0 "register_operand" "=r")
9352         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9353   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9354    && ix86_binary_operator_ok (XOR, SImode, operands)"
9355   "xor{l}\t{%2, %k0|%k0, %2}"
9356   [(set_attr "type" "alu")
9357    (set_attr "mode" "SI")])
9358
9359 (define_insn "*xorsi_2_zext_imm"
9360   [(set (reg FLAGS_REG)
9361         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9362                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9363                  (const_int 0)))
9364    (set (match_operand:DI 0 "register_operand" "=r")
9365         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9366   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9367    && ix86_binary_operator_ok (XOR, SImode, operands)"
9368   "xor{l}\t{%2, %k0|%k0, %2}"
9369   [(set_attr "type" "alu")
9370    (set_attr "mode" "SI")])
9371
9372 (define_insn "*xorsi_3"
9373   [(set (reg FLAGS_REG)
9374         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9375                          (match_operand:SI 2 "general_operand" "rim"))
9376                  (const_int 0)))
9377    (clobber (match_scratch:SI 0 "=r"))]
9378   "ix86_match_ccmode (insn, CCNOmode)
9379    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9380   "xor{l}\t{%2, %0|%0, %2}"
9381   [(set_attr "type" "alu")
9382    (set_attr "mode" "SI")])
9383
9384 (define_expand "xorhi3"
9385   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9386         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9387                 (match_operand:HI 2 "general_operand" "")))
9388    (clobber (reg:CC FLAGS_REG))]
9389   "TARGET_HIMODE_MATH"
9390   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9391
9392 (define_insn "*xorhi_1"
9393   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9394         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9395                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9396    (clobber (reg:CC FLAGS_REG))]
9397   "ix86_binary_operator_ok (XOR, HImode, operands)"
9398   "xor{w}\t{%2, %0|%0, %2}"
9399   [(set_attr "type" "alu")
9400    (set_attr "mode" "HI")])
9401
9402 (define_insn "*xorhi_2"
9403   [(set (reg FLAGS_REG)
9404         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9405                          (match_operand:HI 2 "general_operand" "rim,ri"))
9406                  (const_int 0)))
9407    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9408         (xor:HI (match_dup 1) (match_dup 2)))]
9409   "ix86_match_ccmode (insn, CCNOmode)
9410    && ix86_binary_operator_ok (XOR, HImode, operands)"
9411   "xor{w}\t{%2, %0|%0, %2}"
9412   [(set_attr "type" "alu")
9413    (set_attr "mode" "HI")])
9414
9415 (define_insn "*xorhi_3"
9416   [(set (reg FLAGS_REG)
9417         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9418                          (match_operand:HI 2 "general_operand" "rim"))
9419                  (const_int 0)))
9420    (clobber (match_scratch:HI 0 "=r"))]
9421   "ix86_match_ccmode (insn, CCNOmode)
9422    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9423   "xor{w}\t{%2, %0|%0, %2}"
9424   [(set_attr "type" "alu")
9425    (set_attr "mode" "HI")])
9426
9427 (define_expand "xorqi3"
9428   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9429         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9430                 (match_operand:QI 2 "general_operand" "")))
9431    (clobber (reg:CC FLAGS_REG))]
9432   "TARGET_QIMODE_MATH"
9433   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9434
9435 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9436 (define_insn "*xorqi_1"
9437   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9438         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9439                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9440    (clobber (reg:CC FLAGS_REG))]
9441   "ix86_binary_operator_ok (XOR, QImode, operands)"
9442   "@
9443    xor{b}\t{%2, %0|%0, %2}
9444    xor{b}\t{%2, %0|%0, %2}
9445    xor{l}\t{%k2, %k0|%k0, %k2}"
9446   [(set_attr "type" "alu")
9447    (set_attr "mode" "QI,QI,SI")])
9448
9449 (define_insn "*xorqi_1_slp"
9450   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9451         (xor:QI (match_dup 0)
9452                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9453    (clobber (reg:CC FLAGS_REG))]
9454   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9455    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9456   "xor{b}\t{%1, %0|%0, %1}"
9457   [(set_attr "type" "alu1")
9458    (set_attr "mode" "QI")])
9459
9460 (define_insn "xorqi_ext_0"
9461   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9462                          (const_int 8)
9463                          (const_int 8))
9464         (xor:SI
9465           (zero_extract:SI
9466             (match_operand 1 "ext_register_operand" "0")
9467             (const_int 8)
9468             (const_int 8))
9469           (match_operand 2 "const_int_operand" "n")))
9470    (clobber (reg:CC FLAGS_REG))]
9471   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9472   "xor{b}\t{%2, %h0|%h0, %2}"
9473   [(set_attr "type" "alu")
9474    (set_attr "length_immediate" "1")
9475    (set_attr "mode" "QI")])
9476
9477 (define_insn "*xorqi_ext_1"
9478   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9479                          (const_int 8)
9480                          (const_int 8))
9481         (xor:SI
9482           (zero_extract:SI
9483             (match_operand 1 "ext_register_operand" "0")
9484             (const_int 8)
9485             (const_int 8))
9486           (zero_extend:SI
9487             (match_operand:QI 2 "general_operand" "Qm"))))
9488    (clobber (reg:CC FLAGS_REG))]
9489   "!TARGET_64BIT
9490    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9491   "xor{b}\t{%2, %h0|%h0, %2}"
9492   [(set_attr "type" "alu")
9493    (set_attr "length_immediate" "0")
9494    (set_attr "mode" "QI")])
9495
9496 (define_insn "*xorqi_ext_1_rex64"
9497   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9498                          (const_int 8)
9499                          (const_int 8))
9500         (xor:SI
9501           (zero_extract:SI
9502             (match_operand 1 "ext_register_operand" "0")
9503             (const_int 8)
9504             (const_int 8))
9505           (zero_extend:SI
9506             (match_operand 2 "ext_register_operand" "Q"))))
9507    (clobber (reg:CC FLAGS_REG))]
9508   "TARGET_64BIT
9509    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9510   "xor{b}\t{%2, %h0|%h0, %2}"
9511   [(set_attr "type" "alu")
9512    (set_attr "length_immediate" "0")
9513    (set_attr "mode" "QI")])
9514
9515 (define_insn "*xorqi_ext_2"
9516   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9517                          (const_int 8)
9518                          (const_int 8))
9519         (xor:SI
9520           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9521                            (const_int 8)
9522                            (const_int 8))
9523           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9524                            (const_int 8)
9525                            (const_int 8))))
9526    (clobber (reg:CC FLAGS_REG))]
9527   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9528   "xor{b}\t{%h2, %h0|%h0, %h2}"
9529   [(set_attr "type" "alu")
9530    (set_attr "length_immediate" "0")
9531    (set_attr "mode" "QI")])
9532
9533 (define_insn "*xorqi_cc_1"
9534   [(set (reg FLAGS_REG)
9535         (compare
9536           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9537                   (match_operand:QI 2 "general_operand" "qim,qi"))
9538           (const_int 0)))
9539    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9540         (xor:QI (match_dup 1) (match_dup 2)))]
9541   "ix86_match_ccmode (insn, CCNOmode)
9542    && ix86_binary_operator_ok (XOR, QImode, operands)"
9543   "xor{b}\t{%2, %0|%0, %2}"
9544   [(set_attr "type" "alu")
9545    (set_attr "mode" "QI")])
9546
9547 (define_insn "*xorqi_2_slp"
9548   [(set (reg FLAGS_REG)
9549         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9550                          (match_operand:QI 1 "general_operand" "qim,qi"))
9551                  (const_int 0)))
9552    (set (strict_low_part (match_dup 0))
9553         (xor:QI (match_dup 0) (match_dup 1)))]
9554   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9555    && ix86_match_ccmode (insn, CCNOmode)
9556    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9557   "xor{b}\t{%1, %0|%0, %1}"
9558   [(set_attr "type" "alu1")
9559    (set_attr "mode" "QI")])
9560
9561 (define_insn "*xorqi_cc_2"
9562   [(set (reg FLAGS_REG)
9563         (compare
9564           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9565                   (match_operand:QI 2 "general_operand" "qim"))
9566           (const_int 0)))
9567    (clobber (match_scratch:QI 0 "=q"))]
9568   "ix86_match_ccmode (insn, CCNOmode)
9569    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9570   "xor{b}\t{%2, %0|%0, %2}"
9571   [(set_attr "type" "alu")
9572    (set_attr "mode" "QI")])
9573
9574 (define_insn "*xorqi_cc_ext_1"
9575   [(set (reg FLAGS_REG)
9576         (compare
9577           (xor:SI
9578             (zero_extract:SI
9579               (match_operand 1 "ext_register_operand" "0")
9580               (const_int 8)
9581               (const_int 8))
9582             (match_operand:QI 2 "general_operand" "qmn"))
9583           (const_int 0)))
9584    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9585                          (const_int 8)
9586                          (const_int 8))
9587         (xor:SI
9588           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9589           (match_dup 2)))]
9590   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9591   "xor{b}\t{%2, %h0|%h0, %2}"
9592   [(set_attr "type" "alu")
9593    (set_attr "mode" "QI")])
9594
9595 (define_insn "*xorqi_cc_ext_1_rex64"
9596   [(set (reg FLAGS_REG)
9597         (compare
9598           (xor:SI
9599             (zero_extract:SI
9600               (match_operand 1 "ext_register_operand" "0")
9601               (const_int 8)
9602               (const_int 8))
9603             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9604           (const_int 0)))
9605    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9606                          (const_int 8)
9607                          (const_int 8))
9608         (xor:SI
9609           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9610           (match_dup 2)))]
9611   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9612   "xor{b}\t{%2, %h0|%h0, %2}"
9613   [(set_attr "type" "alu")
9614    (set_attr "mode" "QI")])
9615
9616 (define_expand "xorqi_cc_ext_1"
9617   [(parallel [
9618      (set (reg:CCNO FLAGS_REG)
9619           (compare:CCNO
9620             (xor:SI
9621               (zero_extract:SI
9622                 (match_operand 1 "ext_register_operand" "")
9623                 (const_int 8)
9624                 (const_int 8))
9625               (match_operand:QI 2 "general_operand" ""))
9626             (const_int 0)))
9627      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9628                            (const_int 8)
9629                            (const_int 8))
9630           (xor:SI
9631             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9632             (match_dup 2)))])]
9633   ""
9634   "")
9635
9636 (define_split
9637   [(set (match_operand 0 "register_operand" "")
9638         (xor (match_operand 1 "register_operand" "")
9639              (match_operand 2 "const_int_operand" "")))
9640    (clobber (reg:CC FLAGS_REG))]
9641    "reload_completed
9642     && QI_REG_P (operands[0])
9643     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9644     && !(INTVAL (operands[2]) & ~(255 << 8))
9645     && GET_MODE (operands[0]) != QImode"
9646   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9647                    (xor:SI (zero_extract:SI (match_dup 1)
9648                                             (const_int 8) (const_int 8))
9649                            (match_dup 2)))
9650               (clobber (reg:CC FLAGS_REG))])]
9651   "operands[0] = gen_lowpart (SImode, operands[0]);
9652    operands[1] = gen_lowpart (SImode, operands[1]);
9653    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9654
9655 ;; Since XOR can be encoded with sign extended immediate, this is only
9656 ;; profitable when 7th bit is set.
9657 (define_split
9658   [(set (match_operand 0 "register_operand" "")
9659         (xor (match_operand 1 "general_operand" "")
9660              (match_operand 2 "const_int_operand" "")))
9661    (clobber (reg:CC FLAGS_REG))]
9662    "reload_completed
9663     && ANY_QI_REG_P (operands[0])
9664     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9665     && !(INTVAL (operands[2]) & ~255)
9666     && (INTVAL (operands[2]) & 128)
9667     && GET_MODE (operands[0]) != QImode"
9668   [(parallel [(set (strict_low_part (match_dup 0))
9669                    (xor:QI (match_dup 1)
9670                            (match_dup 2)))
9671               (clobber (reg:CC FLAGS_REG))])]
9672   "operands[0] = gen_lowpart (QImode, operands[0]);
9673    operands[1] = gen_lowpart (QImode, operands[1]);
9674    operands[2] = gen_lowpart (QImode, operands[2]);")
9675 \f
9676 ;; Negation instructions
9677
9678 (define_expand "negti2"
9679   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9680                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9681               (clobber (reg:CC FLAGS_REG))])]
9682   "TARGET_64BIT"
9683   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9684
9685 (define_insn "*negti2_1"
9686   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9687         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9688    (clobber (reg:CC FLAGS_REG))]
9689   "TARGET_64BIT
9690    && ix86_unary_operator_ok (NEG, TImode, operands)"
9691   "#")
9692
9693 (define_split
9694   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9695         (neg:TI (match_operand:TI 1 "general_operand" "")))
9696    (clobber (reg:CC FLAGS_REG))]
9697   "TARGET_64BIT && reload_completed"
9698   [(parallel
9699     [(set (reg:CCZ FLAGS_REG)
9700           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9701      (set (match_dup 0) (neg:DI (match_dup 2)))])
9702    (parallel
9703     [(set (match_dup 1)
9704           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9705                             (match_dup 3))
9706                    (const_int 0)))
9707      (clobber (reg:CC FLAGS_REG))])
9708    (parallel
9709     [(set (match_dup 1)
9710           (neg:DI (match_dup 1)))
9711      (clobber (reg:CC FLAGS_REG))])]
9712   "split_ti (operands+1, 1, operands+2, operands+3);
9713    split_ti (operands+0, 1, operands+0, operands+1);")
9714
9715 (define_expand "negdi2"
9716   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9717                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9718               (clobber (reg:CC FLAGS_REG))])]
9719   ""
9720   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9721
9722 (define_insn "*negdi2_1"
9723   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9724         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9725    (clobber (reg:CC FLAGS_REG))]
9726   "!TARGET_64BIT
9727    && ix86_unary_operator_ok (NEG, DImode, operands)"
9728   "#")
9729
9730 (define_split
9731   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9732         (neg:DI (match_operand:DI 1 "general_operand" "")))
9733    (clobber (reg:CC FLAGS_REG))]
9734   "!TARGET_64BIT && reload_completed"
9735   [(parallel
9736     [(set (reg:CCZ FLAGS_REG)
9737           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9738      (set (match_dup 0) (neg:SI (match_dup 2)))])
9739    (parallel
9740     [(set (match_dup 1)
9741           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9742                             (match_dup 3))
9743                    (const_int 0)))
9744      (clobber (reg:CC FLAGS_REG))])
9745    (parallel
9746     [(set (match_dup 1)
9747           (neg:SI (match_dup 1)))
9748      (clobber (reg:CC FLAGS_REG))])]
9749   "split_di (operands+1, 1, operands+2, operands+3);
9750    split_di (operands+0, 1, operands+0, operands+1);")
9751
9752 (define_insn "*negdi2_1_rex64"
9753   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9754         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9755    (clobber (reg:CC FLAGS_REG))]
9756   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9757   "neg{q}\t%0"
9758   [(set_attr "type" "negnot")
9759    (set_attr "mode" "DI")])
9760
9761 ;; The problem with neg is that it does not perform (compare x 0),
9762 ;; it really performs (compare 0 x), which leaves us with the zero
9763 ;; flag being the only useful item.
9764
9765 (define_insn "*negdi2_cmpz_rex64"
9766   [(set (reg:CCZ FLAGS_REG)
9767         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9768                      (const_int 0)))
9769    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9770         (neg:DI (match_dup 1)))]
9771   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9772   "neg{q}\t%0"
9773   [(set_attr "type" "negnot")
9774    (set_attr "mode" "DI")])
9775
9776
9777 (define_expand "negsi2"
9778   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9779                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9780               (clobber (reg:CC FLAGS_REG))])]
9781   ""
9782   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9783
9784 (define_insn "*negsi2_1"
9785   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9786         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9787    (clobber (reg:CC FLAGS_REG))]
9788   "ix86_unary_operator_ok (NEG, SImode, operands)"
9789   "neg{l}\t%0"
9790   [(set_attr "type" "negnot")
9791    (set_attr "mode" "SI")])
9792
9793 ;; Combine is quite creative about this pattern.
9794 (define_insn "*negsi2_1_zext"
9795   [(set (match_operand:DI 0 "register_operand" "=r")
9796         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9797                                         (const_int 32)))
9798                      (const_int 32)))
9799    (clobber (reg:CC FLAGS_REG))]
9800   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9801   "neg{l}\t%k0"
9802   [(set_attr "type" "negnot")
9803    (set_attr "mode" "SI")])
9804
9805 ;; The problem with neg is that it does not perform (compare x 0),
9806 ;; it really performs (compare 0 x), which leaves us with the zero
9807 ;; flag being the only useful item.
9808
9809 (define_insn "*negsi2_cmpz"
9810   [(set (reg:CCZ FLAGS_REG)
9811         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9812                      (const_int 0)))
9813    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9814         (neg:SI (match_dup 1)))]
9815   "ix86_unary_operator_ok (NEG, SImode, operands)"
9816   "neg{l}\t%0"
9817   [(set_attr "type" "negnot")
9818    (set_attr "mode" "SI")])
9819
9820 (define_insn "*negsi2_cmpz_zext"
9821   [(set (reg:CCZ FLAGS_REG)
9822         (compare:CCZ (lshiftrt:DI
9823                        (neg:DI (ashift:DI
9824                                  (match_operand:DI 1 "register_operand" "0")
9825                                  (const_int 32)))
9826                        (const_int 32))
9827                      (const_int 0)))
9828    (set (match_operand:DI 0 "register_operand" "=r")
9829         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9830                                         (const_int 32)))
9831                      (const_int 32)))]
9832   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9833   "neg{l}\t%k0"
9834   [(set_attr "type" "negnot")
9835    (set_attr "mode" "SI")])
9836
9837 (define_expand "neghi2"
9838   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9839                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9840               (clobber (reg:CC FLAGS_REG))])]
9841   "TARGET_HIMODE_MATH"
9842   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9843
9844 (define_insn "*neghi2_1"
9845   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9846         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9847    (clobber (reg:CC FLAGS_REG))]
9848   "ix86_unary_operator_ok (NEG, HImode, operands)"
9849   "neg{w}\t%0"
9850   [(set_attr "type" "negnot")
9851    (set_attr "mode" "HI")])
9852
9853 (define_insn "*neghi2_cmpz"
9854   [(set (reg:CCZ FLAGS_REG)
9855         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9856                      (const_int 0)))
9857    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9858         (neg:HI (match_dup 1)))]
9859   "ix86_unary_operator_ok (NEG, HImode, operands)"
9860   "neg{w}\t%0"
9861   [(set_attr "type" "negnot")
9862    (set_attr "mode" "HI")])
9863
9864 (define_expand "negqi2"
9865   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9866                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9867               (clobber (reg:CC FLAGS_REG))])]
9868   "TARGET_QIMODE_MATH"
9869   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9870
9871 (define_insn "*negqi2_1"
9872   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9873         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9874    (clobber (reg:CC FLAGS_REG))]
9875   "ix86_unary_operator_ok (NEG, QImode, operands)"
9876   "neg{b}\t%0"
9877   [(set_attr "type" "negnot")
9878    (set_attr "mode" "QI")])
9879
9880 (define_insn "*negqi2_cmpz"
9881   [(set (reg:CCZ FLAGS_REG)
9882         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9883                      (const_int 0)))
9884    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9885         (neg:QI (match_dup 1)))]
9886   "ix86_unary_operator_ok (NEG, QImode, operands)"
9887   "neg{b}\t%0"
9888   [(set_attr "type" "negnot")
9889    (set_attr "mode" "QI")])
9890
9891 ;; Changing of sign for FP values is doable using integer unit too.
9892
9893 (define_expand "negsf2"
9894   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9895         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9896   "TARGET_80387 || TARGET_SSE_MATH"
9897   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9898
9899 (define_expand "abssf2"
9900   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9901         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9902   "TARGET_80387 || TARGET_SSE_MATH"
9903   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9904
9905 (define_insn "*absnegsf2_mixed"
9906   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9907         (match_operator:SF 3 "absneg_operator"
9908           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9909    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9910    (clobber (reg:CC FLAGS_REG))]
9911   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9912    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9913   "#")
9914
9915 (define_insn "*absnegsf2_sse"
9916   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9917         (match_operator:SF 3 "absneg_operator"
9918           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9919    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9920    (clobber (reg:CC FLAGS_REG))]
9921   "TARGET_SSE_MATH
9922    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9923   "#")
9924
9925 (define_insn "*absnegsf2_i387"
9926   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9927         (match_operator:SF 3 "absneg_operator"
9928           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9929    (use (match_operand 2 "" ""))
9930    (clobber (reg:CC FLAGS_REG))]
9931   "TARGET_80387 && !TARGET_SSE_MATH
9932    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9933   "#")
9934
9935 (define_expand "copysignsf3"
9936   [(match_operand:SF 0 "register_operand" "")
9937    (match_operand:SF 1 "nonmemory_operand" "")
9938    (match_operand:SF 2 "register_operand" "")]
9939   "TARGET_SSE_MATH"
9940 {
9941   ix86_expand_copysign (operands);
9942   DONE;
9943 })
9944
9945 (define_insn_and_split "copysignsf3_const"
9946   [(set (match_operand:SF 0 "register_operand"          "=x")
9947         (unspec:SF
9948           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9949            (match_operand:SF 2 "register_operand"       "0")
9950            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9951           UNSPEC_COPYSIGN))]
9952   "TARGET_SSE_MATH"
9953   "#"
9954   "&& reload_completed"
9955   [(const_int 0)]
9956 {
9957   ix86_split_copysign_const (operands);
9958   DONE;
9959 })
9960
9961 (define_insn "copysignsf3_var"
9962   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9963         (unspec:SF
9964           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9965            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9966            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9967            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9968           UNSPEC_COPYSIGN))
9969    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9970   "TARGET_SSE_MATH"
9971   "#")
9972
9973 (define_split
9974   [(set (match_operand:SF 0 "register_operand" "")
9975         (unspec:SF
9976           [(match_operand:SF 2 "register_operand" "")
9977            (match_operand:SF 3 "register_operand" "")
9978            (match_operand:V4SF 4 "" "")
9979            (match_operand:V4SF 5 "" "")]
9980           UNSPEC_COPYSIGN))
9981    (clobber (match_scratch:V4SF 1 ""))]
9982   "TARGET_SSE_MATH && reload_completed"
9983   [(const_int 0)]
9984 {
9985   ix86_split_copysign_var (operands);
9986   DONE;
9987 })
9988
9989 (define_expand "negdf2"
9990   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9991         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9992   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9993   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9994
9995 (define_expand "absdf2"
9996   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9997         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9998   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9999   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
10000
10001 (define_insn "*absnegdf2_mixed"
10002   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,f,rm")
10003         (match_operator:DF 3 "absneg_operator"
10004           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
10005    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X,X"))
10006    (clobber (reg:CC FLAGS_REG))]
10007   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
10008    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10009   "#")
10010
10011 (define_insn "*absnegdf2_sse"
10012   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,rm")
10013         (match_operator:DF 3 "absneg_operator"
10014           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
10015    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X "))
10016    (clobber (reg:CC FLAGS_REG))]
10017   "TARGET_SSE2 && TARGET_SSE_MATH
10018    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10019   "#")
10020
10021 (define_insn "*absnegdf2_i387"
10022   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
10023         (match_operator:DF 3 "absneg_operator"
10024           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
10025    (use (match_operand 2 "" ""))
10026    (clobber (reg:CC FLAGS_REG))]
10027   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
10028    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10029   "#")
10030
10031 (define_expand "copysigndf3"
10032   [(match_operand:DF 0 "register_operand" "")
10033    (match_operand:DF 1 "nonmemory_operand" "")
10034    (match_operand:DF 2 "register_operand" "")]
10035   "TARGET_SSE2 && TARGET_SSE_MATH"
10036 {
10037   ix86_expand_copysign (operands);
10038   DONE;
10039 })
10040
10041 (define_insn_and_split "copysigndf3_const"
10042   [(set (match_operand:DF 0 "register_operand"          "=x")
10043         (unspec:DF
10044           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
10045            (match_operand:DF 2 "register_operand"       "0")
10046            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
10047           UNSPEC_COPYSIGN))]
10048   "TARGET_SSE2 && TARGET_SSE_MATH"
10049   "#"
10050   "&& reload_completed"
10051   [(const_int 0)]
10052 {
10053   ix86_split_copysign_const (operands);
10054   DONE;
10055 })
10056
10057 (define_insn "copysigndf3_var"
10058   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
10059         (unspec:DF
10060           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
10061            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
10062            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
10063            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
10064           UNSPEC_COPYSIGN))
10065    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
10066   "TARGET_SSE2 && TARGET_SSE_MATH"
10067   "#")
10068
10069 (define_split
10070   [(set (match_operand:DF 0 "register_operand" "")
10071         (unspec:DF
10072           [(match_operand:DF 2 "register_operand" "")
10073            (match_operand:DF 3 "register_operand" "")
10074            (match_operand:V2DF 4 "" "")
10075            (match_operand:V2DF 5 "" "")]
10076           UNSPEC_COPYSIGN))
10077    (clobber (match_scratch:V2DF 1 ""))]
10078   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
10079   [(const_int 0)]
10080 {
10081   ix86_split_copysign_var (operands);
10082   DONE;
10083 })
10084
10085 (define_expand "negxf2"
10086   [(set (match_operand:XF 0 "nonimmediate_operand" "")
10087         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10088   "TARGET_80387"
10089   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
10090
10091 (define_expand "absxf2"
10092   [(set (match_operand:XF 0 "nonimmediate_operand" "")
10093         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10094   "TARGET_80387"
10095   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
10096
10097 (define_insn "*absnegxf2_i387"
10098   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
10099         (match_operator:XF 3 "absneg_operator"
10100           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
10101    (use (match_operand 2 "" ""))
10102    (clobber (reg:CC FLAGS_REG))]
10103   "TARGET_80387
10104    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
10105   "#")
10106
10107 ;; Splitters for fp abs and neg.
10108
10109 (define_split
10110   [(set (match_operand 0 "fp_register_operand" "")
10111         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10112    (use (match_operand 2 "" ""))
10113    (clobber (reg:CC FLAGS_REG))]
10114   "reload_completed"
10115   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10116
10117 (define_split
10118   [(set (match_operand 0 "register_operand" "")
10119         (match_operator 3 "absneg_operator"
10120           [(match_operand 1 "register_operand" "")]))
10121    (use (match_operand 2 "nonimmediate_operand" ""))
10122    (clobber (reg:CC FLAGS_REG))]
10123   "reload_completed && SSE_REG_P (operands[0])"
10124   [(set (match_dup 0) (match_dup 3))]
10125 {
10126   enum machine_mode mode = GET_MODE (operands[0]);
10127   enum machine_mode vmode = GET_MODE (operands[2]);
10128   rtx tmp;
10129
10130   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10131   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10132   if (operands_match_p (operands[0], operands[2]))
10133     {
10134       tmp = operands[1];
10135       operands[1] = operands[2];
10136       operands[2] = tmp;
10137     }
10138   if (GET_CODE (operands[3]) == ABS)
10139     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10140   else
10141     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10142   operands[3] = tmp;
10143 })
10144
10145 (define_split
10146   [(set (match_operand:SF 0 "register_operand" "")
10147         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10148    (use (match_operand:V4SF 2 "" ""))
10149    (clobber (reg:CC FLAGS_REG))]
10150   "reload_completed"
10151   [(parallel [(set (match_dup 0) (match_dup 1))
10152               (clobber (reg:CC FLAGS_REG))])]
10153 {
10154   rtx tmp;
10155   operands[0] = gen_lowpart (SImode, operands[0]);
10156   if (GET_CODE (operands[1]) == ABS)
10157     {
10158       tmp = gen_int_mode (0x7fffffff, SImode);
10159       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10160     }
10161   else
10162     {
10163       tmp = gen_int_mode (0x80000000, SImode);
10164       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10165     }
10166   operands[1] = tmp;
10167 })
10168
10169 (define_split
10170   [(set (match_operand:DF 0 "register_operand" "")
10171         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10172    (use (match_operand 2 "" ""))
10173    (clobber (reg:CC FLAGS_REG))]
10174   "reload_completed"
10175   [(parallel [(set (match_dup 0) (match_dup 1))
10176               (clobber (reg:CC FLAGS_REG))])]
10177 {
10178   rtx tmp;
10179   if (TARGET_64BIT)
10180     {
10181       tmp = gen_lowpart (DImode, operands[0]);
10182       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10183       operands[0] = tmp;
10184
10185       if (GET_CODE (operands[1]) == ABS)
10186         tmp = const0_rtx;
10187       else
10188         tmp = gen_rtx_NOT (DImode, tmp);
10189     }
10190   else
10191     {
10192       operands[0] = gen_highpart (SImode, operands[0]);
10193       if (GET_CODE (operands[1]) == ABS)
10194         {
10195           tmp = gen_int_mode (0x7fffffff, SImode);
10196           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10197         }
10198       else
10199         {
10200           tmp = gen_int_mode (0x80000000, SImode);
10201           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10202         }
10203     }
10204   operands[1] = tmp;
10205 })
10206
10207 (define_split
10208   [(set (match_operand:XF 0 "register_operand" "")
10209         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10210    (use (match_operand 2 "" ""))
10211    (clobber (reg:CC FLAGS_REG))]
10212   "reload_completed"
10213   [(parallel [(set (match_dup 0) (match_dup 1))
10214               (clobber (reg:CC FLAGS_REG))])]
10215 {
10216   rtx tmp;
10217   operands[0] = gen_rtx_REG (SImode,
10218                              true_regnum (operands[0])
10219                              + (TARGET_64BIT ? 1 : 2));
10220   if (GET_CODE (operands[1]) == ABS)
10221     {
10222       tmp = GEN_INT (0x7fff);
10223       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10224     }
10225   else
10226     {
10227       tmp = GEN_INT (0x8000);
10228       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10229     }
10230   operands[1] = tmp;
10231 })
10232
10233 (define_split
10234   [(set (match_operand 0 "memory_operand" "")
10235         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10236    (use (match_operand 2 "" ""))
10237    (clobber (reg:CC FLAGS_REG))]
10238   "reload_completed"
10239   [(parallel [(set (match_dup 0) (match_dup 1))
10240               (clobber (reg:CC FLAGS_REG))])]
10241 {
10242   enum machine_mode mode = GET_MODE (operands[0]);
10243   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
10244   rtx tmp;
10245
10246   operands[0] = adjust_address (operands[0], QImode, size - 1);
10247   if (GET_CODE (operands[1]) == ABS)
10248     {
10249       tmp = gen_int_mode (0x7f, QImode);
10250       tmp = gen_rtx_AND (QImode, operands[0], tmp);
10251     }
10252   else
10253     {
10254       tmp = gen_int_mode (0x80, QImode);
10255       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
10256     }
10257   operands[1] = tmp;
10258 })
10259
10260 ;; Conditionalize these after reload. If they match before reload, we
10261 ;; lose the clobber and ability to use integer instructions.
10262
10263 (define_insn "*negsf2_1"
10264   [(set (match_operand:SF 0 "register_operand" "=f")
10265         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10266   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10267   "fchs"
10268   [(set_attr "type" "fsgn")
10269    (set_attr "mode" "SF")])
10270
10271 (define_insn "*negdf2_1"
10272   [(set (match_operand:DF 0 "register_operand" "=f")
10273         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10274   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10275   "fchs"
10276   [(set_attr "type" "fsgn")
10277    (set_attr "mode" "DF")])
10278
10279 (define_insn "*negxf2_1"
10280   [(set (match_operand:XF 0 "register_operand" "=f")
10281         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10282   "TARGET_80387"
10283   "fchs"
10284   [(set_attr "type" "fsgn")
10285    (set_attr "mode" "XF")])
10286
10287 (define_insn "*abssf2_1"
10288   [(set (match_operand:SF 0 "register_operand" "=f")
10289         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10290   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10291   "fabs"
10292   [(set_attr "type" "fsgn")
10293    (set_attr "mode" "SF")])
10294
10295 (define_insn "*absdf2_1"
10296   [(set (match_operand:DF 0 "register_operand" "=f")
10297         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10298   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10299   "fabs"
10300   [(set_attr "type" "fsgn")
10301    (set_attr "mode" "DF")])
10302
10303 (define_insn "*absxf2_1"
10304   [(set (match_operand:XF 0 "register_operand" "=f")
10305         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10306   "TARGET_80387"
10307   "fabs"
10308   [(set_attr "type" "fsgn")
10309    (set_attr "mode" "DF")])
10310
10311 (define_insn "*negextendsfdf2"
10312   [(set (match_operand:DF 0 "register_operand" "=f")
10313         (neg:DF (float_extend:DF
10314                   (match_operand:SF 1 "register_operand" "0"))))]
10315   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10316   "fchs"
10317   [(set_attr "type" "fsgn")
10318    (set_attr "mode" "DF")])
10319
10320 (define_insn "*negextenddfxf2"
10321   [(set (match_operand:XF 0 "register_operand" "=f")
10322         (neg:XF (float_extend:XF
10323                   (match_operand:DF 1 "register_operand" "0"))))]
10324   "TARGET_80387"
10325   "fchs"
10326   [(set_attr "type" "fsgn")
10327    (set_attr "mode" "XF")])
10328
10329 (define_insn "*negextendsfxf2"
10330   [(set (match_operand:XF 0 "register_operand" "=f")
10331         (neg:XF (float_extend:XF
10332                   (match_operand:SF 1 "register_operand" "0"))))]
10333   "TARGET_80387"
10334   "fchs"
10335   [(set_attr "type" "fsgn")
10336    (set_attr "mode" "XF")])
10337
10338 (define_insn "*absextendsfdf2"
10339   [(set (match_operand:DF 0 "register_operand" "=f")
10340         (abs:DF (float_extend:DF
10341                   (match_operand:SF 1 "register_operand" "0"))))]
10342   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10343   "fabs"
10344   [(set_attr "type" "fsgn")
10345    (set_attr "mode" "DF")])
10346
10347 (define_insn "*absextenddfxf2"
10348   [(set (match_operand:XF 0 "register_operand" "=f")
10349         (abs:XF (float_extend:XF
10350           (match_operand:DF 1 "register_operand" "0"))))]
10351   "TARGET_80387"
10352   "fabs"
10353   [(set_attr "type" "fsgn")
10354    (set_attr "mode" "XF")])
10355
10356 (define_insn "*absextendsfxf2"
10357   [(set (match_operand:XF 0 "register_operand" "=f")
10358         (abs:XF (float_extend:XF
10359           (match_operand:SF 1 "register_operand" "0"))))]
10360   "TARGET_80387"
10361   "fabs"
10362   [(set_attr "type" "fsgn")
10363    (set_attr "mode" "XF")])
10364 \f
10365 ;; One complement instructions
10366
10367 (define_expand "one_cmpldi2"
10368   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10369         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10370   "TARGET_64BIT"
10371   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10372
10373 (define_insn "*one_cmpldi2_1_rex64"
10374   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10375         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10376   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10377   "not{q}\t%0"
10378   [(set_attr "type" "negnot")
10379    (set_attr "mode" "DI")])
10380
10381 (define_insn "*one_cmpldi2_2_rex64"
10382   [(set (reg FLAGS_REG)
10383         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10384                  (const_int 0)))
10385    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10386         (not:DI (match_dup 1)))]
10387   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10388    && ix86_unary_operator_ok (NOT, DImode, operands)"
10389   "#"
10390   [(set_attr "type" "alu1")
10391    (set_attr "mode" "DI")])
10392
10393 (define_split
10394   [(set (match_operand 0 "flags_reg_operand" "")
10395         (match_operator 2 "compare_operator"
10396           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10397            (const_int 0)]))
10398    (set (match_operand:DI 1 "nonimmediate_operand" "")
10399         (not:DI (match_dup 3)))]
10400   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10401   [(parallel [(set (match_dup 0)
10402                    (match_op_dup 2
10403                      [(xor:DI (match_dup 3) (const_int -1))
10404                       (const_int 0)]))
10405               (set (match_dup 1)
10406                    (xor:DI (match_dup 3) (const_int -1)))])]
10407   "")
10408
10409 (define_expand "one_cmplsi2"
10410   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10411         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10412   ""
10413   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10414
10415 (define_insn "*one_cmplsi2_1"
10416   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10417         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10418   "ix86_unary_operator_ok (NOT, SImode, operands)"
10419   "not{l}\t%0"
10420   [(set_attr "type" "negnot")
10421    (set_attr "mode" "SI")])
10422
10423 ;; ??? Currently never generated - xor is used instead.
10424 (define_insn "*one_cmplsi2_1_zext"
10425   [(set (match_operand:DI 0 "register_operand" "=r")
10426         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10427   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10428   "not{l}\t%k0"
10429   [(set_attr "type" "negnot")
10430    (set_attr "mode" "SI")])
10431
10432 (define_insn "*one_cmplsi2_2"
10433   [(set (reg FLAGS_REG)
10434         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10435                  (const_int 0)))
10436    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10437         (not:SI (match_dup 1)))]
10438   "ix86_match_ccmode (insn, CCNOmode)
10439    && ix86_unary_operator_ok (NOT, SImode, operands)"
10440   "#"
10441   [(set_attr "type" "alu1")
10442    (set_attr "mode" "SI")])
10443
10444 (define_split
10445   [(set (match_operand 0 "flags_reg_operand" "")
10446         (match_operator 2 "compare_operator"
10447           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10448            (const_int 0)]))
10449    (set (match_operand:SI 1 "nonimmediate_operand" "")
10450         (not:SI (match_dup 3)))]
10451   "ix86_match_ccmode (insn, CCNOmode)"
10452   [(parallel [(set (match_dup 0)
10453                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10454                                     (const_int 0)]))
10455               (set (match_dup 1)
10456                    (xor:SI (match_dup 3) (const_int -1)))])]
10457   "")
10458
10459 ;; ??? Currently never generated - xor is used instead.
10460 (define_insn "*one_cmplsi2_2_zext"
10461   [(set (reg FLAGS_REG)
10462         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10463                  (const_int 0)))
10464    (set (match_operand:DI 0 "register_operand" "=r")
10465         (zero_extend:DI (not:SI (match_dup 1))))]
10466   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10467    && ix86_unary_operator_ok (NOT, SImode, operands)"
10468   "#"
10469   [(set_attr "type" "alu1")
10470    (set_attr "mode" "SI")])
10471
10472 (define_split
10473   [(set (match_operand 0 "flags_reg_operand" "")
10474         (match_operator 2 "compare_operator"
10475           [(not:SI (match_operand:SI 3 "register_operand" ""))
10476            (const_int 0)]))
10477    (set (match_operand:DI 1 "register_operand" "")
10478         (zero_extend:DI (not:SI (match_dup 3))))]
10479   "ix86_match_ccmode (insn, CCNOmode)"
10480   [(parallel [(set (match_dup 0)
10481                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10482                                     (const_int 0)]))
10483               (set (match_dup 1)
10484                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10485   "")
10486
10487 (define_expand "one_cmplhi2"
10488   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10489         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10490   "TARGET_HIMODE_MATH"
10491   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10492
10493 (define_insn "*one_cmplhi2_1"
10494   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10495         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10496   "ix86_unary_operator_ok (NOT, HImode, operands)"
10497   "not{w}\t%0"
10498   [(set_attr "type" "negnot")
10499    (set_attr "mode" "HI")])
10500
10501 (define_insn "*one_cmplhi2_2"
10502   [(set (reg FLAGS_REG)
10503         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10504                  (const_int 0)))
10505    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10506         (not:HI (match_dup 1)))]
10507   "ix86_match_ccmode (insn, CCNOmode)
10508    && ix86_unary_operator_ok (NEG, HImode, operands)"
10509   "#"
10510   [(set_attr "type" "alu1")
10511    (set_attr "mode" "HI")])
10512
10513 (define_split
10514   [(set (match_operand 0 "flags_reg_operand" "")
10515         (match_operator 2 "compare_operator"
10516           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10517            (const_int 0)]))
10518    (set (match_operand:HI 1 "nonimmediate_operand" "")
10519         (not:HI (match_dup 3)))]
10520   "ix86_match_ccmode (insn, CCNOmode)"
10521   [(parallel [(set (match_dup 0)
10522                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10523                                     (const_int 0)]))
10524               (set (match_dup 1)
10525                    (xor:HI (match_dup 3) (const_int -1)))])]
10526   "")
10527
10528 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10529 (define_expand "one_cmplqi2"
10530   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10531         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10532   "TARGET_QIMODE_MATH"
10533   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10534
10535 (define_insn "*one_cmplqi2_1"
10536   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10537         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10538   "ix86_unary_operator_ok (NOT, QImode, operands)"
10539   "@
10540    not{b}\t%0
10541    not{l}\t%k0"
10542   [(set_attr "type" "negnot")
10543    (set_attr "mode" "QI,SI")])
10544
10545 (define_insn "*one_cmplqi2_2"
10546   [(set (reg FLAGS_REG)
10547         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10548                  (const_int 0)))
10549    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10550         (not:QI (match_dup 1)))]
10551   "ix86_match_ccmode (insn, CCNOmode)
10552    && ix86_unary_operator_ok (NOT, QImode, operands)"
10553   "#"
10554   [(set_attr "type" "alu1")
10555    (set_attr "mode" "QI")])
10556
10557 (define_split
10558   [(set (match_operand 0 "flags_reg_operand" "")
10559         (match_operator 2 "compare_operator"
10560           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10561            (const_int 0)]))
10562    (set (match_operand:QI 1 "nonimmediate_operand" "")
10563         (not:QI (match_dup 3)))]
10564   "ix86_match_ccmode (insn, CCNOmode)"
10565   [(parallel [(set (match_dup 0)
10566                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10567                                     (const_int 0)]))
10568               (set (match_dup 1)
10569                    (xor:QI (match_dup 3) (const_int -1)))])]
10570   "")
10571 \f
10572 ;; Arithmetic shift instructions
10573
10574 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10575 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10576 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10577 ;; from the assembler input.
10578 ;;
10579 ;; This instruction shifts the target reg/mem as usual, but instead of
10580 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10581 ;; is a left shift double, bits are taken from the high order bits of
10582 ;; reg, else if the insn is a shift right double, bits are taken from the
10583 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10584 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10585 ;;
10586 ;; Since sh[lr]d does not change the `reg' operand, that is done
10587 ;; separately, making all shifts emit pairs of shift double and normal
10588 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10589 ;; support a 63 bit shift, each shift where the count is in a reg expands
10590 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10591 ;;
10592 ;; If the shift count is a constant, we need never emit more than one
10593 ;; shift pair, instead using moves and sign extension for counts greater
10594 ;; than 31.
10595
10596 (define_expand "ashlti3"
10597   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10598                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10599                               (match_operand:QI 2 "nonmemory_operand" "")))
10600               (clobber (reg:CC FLAGS_REG))])]
10601   "TARGET_64BIT"
10602 {
10603   if (! immediate_operand (operands[2], QImode))
10604     {
10605       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10606       DONE;
10607     }
10608   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10609   DONE;
10610 })
10611
10612 (define_insn "ashlti3_1"
10613   [(set (match_operand:TI 0 "register_operand" "=r")
10614         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10615                    (match_operand:QI 2 "register_operand" "c")))
10616    (clobber (match_scratch:DI 3 "=&r"))
10617    (clobber (reg:CC FLAGS_REG))]
10618   "TARGET_64BIT"
10619   "#"
10620   [(set_attr "type" "multi")])
10621
10622 (define_insn "*ashlti3_2"
10623   [(set (match_operand:TI 0 "register_operand" "=r")
10624         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10625                    (match_operand:QI 2 "immediate_operand" "O")))
10626    (clobber (reg:CC FLAGS_REG))]
10627   "TARGET_64BIT"
10628   "#"
10629   [(set_attr "type" "multi")])
10630
10631 (define_split
10632   [(set (match_operand:TI 0 "register_operand" "")
10633         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10634                    (match_operand:QI 2 "register_operand" "")))
10635    (clobber (match_scratch:DI 3 ""))
10636    (clobber (reg:CC FLAGS_REG))]
10637   "TARGET_64BIT && reload_completed"
10638   [(const_int 0)]
10639   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10640
10641 (define_split
10642   [(set (match_operand:TI 0 "register_operand" "")
10643         (ashift:TI (match_operand:TI 1 "register_operand" "")
10644                    (match_operand:QI 2 "immediate_operand" "")))
10645    (clobber (reg:CC FLAGS_REG))]
10646   "TARGET_64BIT && reload_completed"
10647   [(const_int 0)]
10648   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10649
10650 (define_insn "x86_64_shld"
10651   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10652         (ior:DI (ashift:DI (match_dup 0)
10653                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10654                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10655                   (minus:QI (const_int 64) (match_dup 2)))))
10656    (clobber (reg:CC FLAGS_REG))]
10657   "TARGET_64BIT"
10658   "@
10659    shld{q}\t{%2, %1, %0|%0, %1, %2}
10660    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10661   [(set_attr "type" "ishift")
10662    (set_attr "prefix_0f" "1")
10663    (set_attr "mode" "DI")
10664    (set_attr "athlon_decode" "vector")
10665    (set_attr "amdfam10_decode" "vector")])   
10666
10667 (define_expand "x86_64_shift_adj"
10668   [(set (reg:CCZ FLAGS_REG)
10669         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10670                              (const_int 64))
10671                      (const_int 0)))
10672    (set (match_operand:DI 0 "register_operand" "")
10673         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10674                          (match_operand:DI 1 "register_operand" "")
10675                          (match_dup 0)))
10676    (set (match_dup 1)
10677         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10678                          (match_operand:DI 3 "register_operand" "r")
10679                          (match_dup 1)))]
10680   "TARGET_64BIT"
10681   "")
10682
10683 (define_expand "ashldi3"
10684   [(set (match_operand:DI 0 "shiftdi_operand" "")
10685         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10686                    (match_operand:QI 2 "nonmemory_operand" "")))]
10687   ""
10688   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10689
10690 (define_insn "*ashldi3_1_rex64"
10691   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10692         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10693                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10694    (clobber (reg:CC FLAGS_REG))]
10695   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10696 {
10697   switch (get_attr_type (insn))
10698     {
10699     case TYPE_ALU:
10700       gcc_assert (operands[2] == const1_rtx);
10701       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10702       return "add{q}\t%0, %0";
10703
10704     case TYPE_LEA:
10705       gcc_assert (CONST_INT_P (operands[2]));
10706       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10707       operands[1] = gen_rtx_MULT (DImode, operands[1],
10708                                   GEN_INT (1 << INTVAL (operands[2])));
10709       return "lea{q}\t{%a1, %0|%0, %a1}";
10710
10711     default:
10712       if (REG_P (operands[2]))
10713         return "sal{q}\t{%b2, %0|%0, %b2}";
10714       else if (operands[2] == const1_rtx
10715                && (TARGET_SHIFT1 || optimize_size))
10716         return "sal{q}\t%0";
10717       else
10718         return "sal{q}\t{%2, %0|%0, %2}";
10719     }
10720 }
10721   [(set (attr "type")
10722      (cond [(eq_attr "alternative" "1")
10723               (const_string "lea")
10724             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10725                           (const_int 0))
10726                       (match_operand 0 "register_operand" ""))
10727                  (match_operand 2 "const1_operand" ""))
10728               (const_string "alu")
10729            ]
10730            (const_string "ishift")))
10731    (set_attr "mode" "DI")])
10732
10733 ;; Convert lea to the lea pattern to avoid flags dependency.
10734 (define_split
10735   [(set (match_operand:DI 0 "register_operand" "")
10736         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10737                    (match_operand:QI 2 "immediate_operand" "")))
10738    (clobber (reg:CC FLAGS_REG))]
10739   "TARGET_64BIT && reload_completed
10740    && true_regnum (operands[0]) != true_regnum (operands[1])"
10741   [(set (match_dup 0)
10742         (mult:DI (match_dup 1)
10743                  (match_dup 2)))]
10744   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10745
10746 ;; This pattern can't accept a variable shift count, since shifts by
10747 ;; zero don't affect the flags.  We assume that shifts by constant
10748 ;; zero are optimized away.
10749 (define_insn "*ashldi3_cmp_rex64"
10750   [(set (reg FLAGS_REG)
10751         (compare
10752           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10753                      (match_operand:QI 2 "immediate_operand" "e"))
10754           (const_int 0)))
10755    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10756         (ashift:DI (match_dup 1) (match_dup 2)))]
10757   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10758    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10759    && (optimize_size
10760        || !TARGET_PARTIAL_FLAG_REG_STALL
10761        || (operands[2] == const1_rtx
10762            && (TARGET_SHIFT1
10763                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10764 {
10765   switch (get_attr_type (insn))
10766     {
10767     case TYPE_ALU:
10768       gcc_assert (operands[2] == const1_rtx);
10769       return "add{q}\t%0, %0";
10770
10771     default:
10772       if (REG_P (operands[2]))
10773         return "sal{q}\t{%b2, %0|%0, %b2}";
10774       else if (operands[2] == const1_rtx
10775                && (TARGET_SHIFT1 || optimize_size))
10776         return "sal{q}\t%0";
10777       else
10778         return "sal{q}\t{%2, %0|%0, %2}";
10779     }
10780 }
10781   [(set (attr "type")
10782      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10783                           (const_int 0))
10784                       (match_operand 0 "register_operand" ""))
10785                  (match_operand 2 "const1_operand" ""))
10786               (const_string "alu")
10787            ]
10788            (const_string "ishift")))
10789    (set_attr "mode" "DI")])
10790
10791 (define_insn "*ashldi3_cconly_rex64"
10792   [(set (reg FLAGS_REG)
10793         (compare
10794           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10795                      (match_operand:QI 2 "immediate_operand" "e"))
10796           (const_int 0)))
10797    (clobber (match_scratch:DI 0 "=r"))]
10798   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10799    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10800    && (optimize_size
10801        || !TARGET_PARTIAL_FLAG_REG_STALL
10802        || (operands[2] == const1_rtx
10803            && (TARGET_SHIFT1
10804                || TARGET_DOUBLE_WITH_ADD)))"
10805 {
10806   switch (get_attr_type (insn))
10807     {
10808     case TYPE_ALU:
10809       gcc_assert (operands[2] == const1_rtx);
10810       return "add{q}\t%0, %0";
10811
10812     default:
10813       if (REG_P (operands[2]))
10814         return "sal{q}\t{%b2, %0|%0, %b2}";
10815       else if (operands[2] == const1_rtx
10816                && (TARGET_SHIFT1 || optimize_size))
10817         return "sal{q}\t%0";
10818       else
10819         return "sal{q}\t{%2, %0|%0, %2}";
10820     }
10821 }
10822   [(set (attr "type")
10823      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10824                           (const_int 0))
10825                       (match_operand 0 "register_operand" ""))
10826                  (match_operand 2 "const1_operand" ""))
10827               (const_string "alu")
10828            ]
10829            (const_string "ishift")))
10830    (set_attr "mode" "DI")])
10831
10832 (define_insn "*ashldi3_1"
10833   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10834         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10835                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10836    (clobber (reg:CC FLAGS_REG))]
10837   "!TARGET_64BIT"
10838   "#"
10839   [(set_attr "type" "multi")])
10840
10841 ;; By default we don't ask for a scratch register, because when DImode
10842 ;; values are manipulated, registers are already at a premium.  But if
10843 ;; we have one handy, we won't turn it away.
10844 (define_peephole2
10845   [(match_scratch:SI 3 "r")
10846    (parallel [(set (match_operand:DI 0 "register_operand" "")
10847                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10848                               (match_operand:QI 2 "nonmemory_operand" "")))
10849               (clobber (reg:CC FLAGS_REG))])
10850    (match_dup 3)]
10851   "!TARGET_64BIT && TARGET_CMOVE"
10852   [(const_int 0)]
10853   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10854
10855 (define_split
10856   [(set (match_operand:DI 0 "register_operand" "")
10857         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10858                    (match_operand:QI 2 "nonmemory_operand" "")))
10859    (clobber (reg:CC FLAGS_REG))]
10860   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10861                      ? flow2_completed : reload_completed)"
10862   [(const_int 0)]
10863   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10864
10865 (define_insn "x86_shld_1"
10866   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10867         (ior:SI (ashift:SI (match_dup 0)
10868                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10869                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10870                   (minus:QI (const_int 32) (match_dup 2)))))
10871    (clobber (reg:CC FLAGS_REG))]
10872   ""
10873   "@
10874    shld{l}\t{%2, %1, %0|%0, %1, %2}
10875    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10876   [(set_attr "type" "ishift")
10877    (set_attr "prefix_0f" "1")
10878    (set_attr "mode" "SI")
10879    (set_attr "pent_pair" "np")
10880    (set_attr "athlon_decode" "vector")
10881    (set_attr "amdfam10_decode" "vector")])   
10882
10883 (define_expand "x86_shift_adj_1"
10884   [(set (reg:CCZ FLAGS_REG)
10885         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10886                              (const_int 32))
10887                      (const_int 0)))
10888    (set (match_operand:SI 0 "register_operand" "")
10889         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10890                          (match_operand:SI 1 "register_operand" "")
10891                          (match_dup 0)))
10892    (set (match_dup 1)
10893         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10894                          (match_operand:SI 3 "register_operand" "r")
10895                          (match_dup 1)))]
10896   "TARGET_CMOVE"
10897   "")
10898
10899 (define_expand "x86_shift_adj_2"
10900   [(use (match_operand:SI 0 "register_operand" ""))
10901    (use (match_operand:SI 1 "register_operand" ""))
10902    (use (match_operand:QI 2 "register_operand" ""))]
10903   ""
10904 {
10905   rtx label = gen_label_rtx ();
10906   rtx tmp;
10907
10908   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10909
10910   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10911   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10912   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10913                               gen_rtx_LABEL_REF (VOIDmode, label),
10914                               pc_rtx);
10915   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10916   JUMP_LABEL (tmp) = label;
10917
10918   emit_move_insn (operands[0], operands[1]);
10919   ix86_expand_clear (operands[1]);
10920
10921   emit_label (label);
10922   LABEL_NUSES (label) = 1;
10923
10924   DONE;
10925 })
10926
10927 (define_expand "ashlsi3"
10928   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10929         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10930                    (match_operand:QI 2 "nonmemory_operand" "")))
10931    (clobber (reg:CC FLAGS_REG))]
10932   ""
10933   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10934
10935 (define_insn "*ashlsi3_1"
10936   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10937         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10938                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10939    (clobber (reg:CC FLAGS_REG))]
10940   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10941 {
10942   switch (get_attr_type (insn))
10943     {
10944     case TYPE_ALU:
10945       gcc_assert (operands[2] == const1_rtx);
10946       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10947       return "add{l}\t%0, %0";
10948
10949     case TYPE_LEA:
10950       return "#";
10951
10952     default:
10953       if (REG_P (operands[2]))
10954         return "sal{l}\t{%b2, %0|%0, %b2}";
10955       else if (operands[2] == const1_rtx
10956                && (TARGET_SHIFT1 || optimize_size))
10957         return "sal{l}\t%0";
10958       else
10959         return "sal{l}\t{%2, %0|%0, %2}";
10960     }
10961 }
10962   [(set (attr "type")
10963      (cond [(eq_attr "alternative" "1")
10964               (const_string "lea")
10965             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10966                           (const_int 0))
10967                       (match_operand 0 "register_operand" ""))
10968                  (match_operand 2 "const1_operand" ""))
10969               (const_string "alu")
10970            ]
10971            (const_string "ishift")))
10972    (set_attr "mode" "SI")])
10973
10974 ;; Convert lea to the lea pattern to avoid flags dependency.
10975 (define_split
10976   [(set (match_operand 0 "register_operand" "")
10977         (ashift (match_operand 1 "index_register_operand" "")
10978                 (match_operand:QI 2 "const_int_operand" "")))
10979    (clobber (reg:CC FLAGS_REG))]
10980   "reload_completed
10981    && true_regnum (operands[0]) != true_regnum (operands[1])
10982    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10983   [(const_int 0)]
10984 {
10985   rtx pat;
10986   enum machine_mode mode = GET_MODE (operands[0]);
10987
10988   if (GET_MODE_SIZE (mode) < 4)
10989     operands[0] = gen_lowpart (SImode, operands[0]);
10990   if (mode != Pmode)
10991     operands[1] = gen_lowpart (Pmode, operands[1]);
10992   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10993
10994   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10995   if (Pmode != SImode)
10996     pat = gen_rtx_SUBREG (SImode, pat, 0);
10997   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10998   DONE;
10999 })
11000
11001 ;; Rare case of shifting RSP is handled by generating move and shift
11002 (define_split
11003   [(set (match_operand 0 "register_operand" "")
11004         (ashift (match_operand 1 "register_operand" "")
11005                 (match_operand:QI 2 "const_int_operand" "")))
11006    (clobber (reg:CC FLAGS_REG))]
11007   "reload_completed
11008    && true_regnum (operands[0]) != true_regnum (operands[1])"
11009   [(const_int 0)]
11010 {
11011   rtx pat, clob;
11012   emit_move_insn (operands[0], operands[1]);
11013   pat = gen_rtx_SET (VOIDmode, operands[0],
11014                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11015                                      operands[0], operands[2]));
11016   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11017   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11018   DONE;
11019 })
11020
11021 (define_insn "*ashlsi3_1_zext"
11022   [(set (match_operand:DI 0 "register_operand" "=r,r")
11023         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11024                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11025    (clobber (reg:CC FLAGS_REG))]
11026   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11027 {
11028   switch (get_attr_type (insn))
11029     {
11030     case TYPE_ALU:
11031       gcc_assert (operands[2] == const1_rtx);
11032       return "add{l}\t%k0, %k0";
11033
11034     case TYPE_LEA:
11035       return "#";
11036
11037     default:
11038       if (REG_P (operands[2]))
11039         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11040       else if (operands[2] == const1_rtx
11041                && (TARGET_SHIFT1 || optimize_size))
11042         return "sal{l}\t%k0";
11043       else
11044         return "sal{l}\t{%2, %k0|%k0, %2}";
11045     }
11046 }
11047   [(set (attr "type")
11048      (cond [(eq_attr "alternative" "1")
11049               (const_string "lea")
11050             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11051                      (const_int 0))
11052                  (match_operand 2 "const1_operand" ""))
11053               (const_string "alu")
11054            ]
11055            (const_string "ishift")))
11056    (set_attr "mode" "SI")])
11057
11058 ;; Convert lea to the lea pattern to avoid flags dependency.
11059 (define_split
11060   [(set (match_operand:DI 0 "register_operand" "")
11061         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11062                                 (match_operand:QI 2 "const_int_operand" ""))))
11063    (clobber (reg:CC FLAGS_REG))]
11064   "TARGET_64BIT && reload_completed
11065    && true_regnum (operands[0]) != true_regnum (operands[1])"
11066   [(set (match_dup 0) (zero_extend:DI
11067                         (subreg:SI (mult:SI (match_dup 1)
11068                                             (match_dup 2)) 0)))]
11069 {
11070   operands[1] = gen_lowpart (Pmode, operands[1]);
11071   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11072 })
11073
11074 ;; This pattern can't accept a variable shift count, since shifts by
11075 ;; zero don't affect the flags.  We assume that shifts by constant
11076 ;; zero are optimized away.
11077 (define_insn "*ashlsi3_cmp"
11078   [(set (reg FLAGS_REG)
11079         (compare
11080           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11081                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11082           (const_int 0)))
11083    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11084         (ashift:SI (match_dup 1) (match_dup 2)))]
11085   "ix86_match_ccmode (insn, CCGOCmode)
11086    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11087    && (optimize_size
11088        || !TARGET_PARTIAL_FLAG_REG_STALL
11089        || (operands[2] == const1_rtx
11090            && (TARGET_SHIFT1
11091                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11092 {
11093   switch (get_attr_type (insn))
11094     {
11095     case TYPE_ALU:
11096       gcc_assert (operands[2] == const1_rtx);
11097       return "add{l}\t%0, %0";
11098
11099     default:
11100       if (REG_P (operands[2]))
11101         return "sal{l}\t{%b2, %0|%0, %b2}";
11102       else if (operands[2] == const1_rtx
11103                && (TARGET_SHIFT1 || optimize_size))
11104         return "sal{l}\t%0";
11105       else
11106         return "sal{l}\t{%2, %0|%0, %2}";
11107     }
11108 }
11109   [(set (attr "type")
11110      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11111                           (const_int 0))
11112                       (match_operand 0 "register_operand" ""))
11113                  (match_operand 2 "const1_operand" ""))
11114               (const_string "alu")
11115            ]
11116            (const_string "ishift")))
11117    (set_attr "mode" "SI")])
11118
11119 (define_insn "*ashlsi3_cconly"
11120   [(set (reg FLAGS_REG)
11121         (compare
11122           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11123                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11124           (const_int 0)))
11125    (clobber (match_scratch:SI 0 "=r"))]
11126   "ix86_match_ccmode (insn, CCGOCmode)
11127    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11128    && (optimize_size
11129        || !TARGET_PARTIAL_FLAG_REG_STALL
11130        || (operands[2] == const1_rtx
11131            && (TARGET_SHIFT1
11132                || TARGET_DOUBLE_WITH_ADD)))"
11133 {
11134   switch (get_attr_type (insn))
11135     {
11136     case TYPE_ALU:
11137       gcc_assert (operands[2] == const1_rtx);
11138       return "add{l}\t%0, %0";
11139
11140     default:
11141       if (REG_P (operands[2]))
11142         return "sal{l}\t{%b2, %0|%0, %b2}";
11143       else if (operands[2] == const1_rtx
11144                && (TARGET_SHIFT1 || optimize_size))
11145         return "sal{l}\t%0";
11146       else
11147         return "sal{l}\t{%2, %0|%0, %2}";
11148     }
11149 }
11150   [(set (attr "type")
11151      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11152                           (const_int 0))
11153                       (match_operand 0 "register_operand" ""))
11154                  (match_operand 2 "const1_operand" ""))
11155               (const_string "alu")
11156            ]
11157            (const_string "ishift")))
11158    (set_attr "mode" "SI")])
11159
11160 (define_insn "*ashlsi3_cmp_zext"
11161   [(set (reg FLAGS_REG)
11162         (compare
11163           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11164                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11165           (const_int 0)))
11166    (set (match_operand:DI 0 "register_operand" "=r")
11167         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11168   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11169    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11170    && (optimize_size
11171        || !TARGET_PARTIAL_FLAG_REG_STALL
11172        || (operands[2] == const1_rtx
11173            && (TARGET_SHIFT1
11174                || TARGET_DOUBLE_WITH_ADD)))"
11175 {
11176   switch (get_attr_type (insn))
11177     {
11178     case TYPE_ALU:
11179       gcc_assert (operands[2] == const1_rtx);
11180       return "add{l}\t%k0, %k0";
11181
11182     default:
11183       if (REG_P (operands[2]))
11184         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11185       else if (operands[2] == const1_rtx
11186                && (TARGET_SHIFT1 || optimize_size))
11187         return "sal{l}\t%k0";
11188       else
11189         return "sal{l}\t{%2, %k0|%k0, %2}";
11190     }
11191 }
11192   [(set (attr "type")
11193      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11194                      (const_int 0))
11195                  (match_operand 2 "const1_operand" ""))
11196               (const_string "alu")
11197            ]
11198            (const_string "ishift")))
11199    (set_attr "mode" "SI")])
11200
11201 (define_expand "ashlhi3"
11202   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11203         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11204                    (match_operand:QI 2 "nonmemory_operand" "")))
11205    (clobber (reg:CC FLAGS_REG))]
11206   "TARGET_HIMODE_MATH"
11207   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11208
11209 (define_insn "*ashlhi3_1_lea"
11210   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11211         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11212                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11213    (clobber (reg:CC FLAGS_REG))]
11214   "!TARGET_PARTIAL_REG_STALL
11215    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11216 {
11217   switch (get_attr_type (insn))
11218     {
11219     case TYPE_LEA:
11220       return "#";
11221     case TYPE_ALU:
11222       gcc_assert (operands[2] == const1_rtx);
11223       return "add{w}\t%0, %0";
11224
11225     default:
11226       if (REG_P (operands[2]))
11227         return "sal{w}\t{%b2, %0|%0, %b2}";
11228       else if (operands[2] == const1_rtx
11229                && (TARGET_SHIFT1 || optimize_size))
11230         return "sal{w}\t%0";
11231       else
11232         return "sal{w}\t{%2, %0|%0, %2}";
11233     }
11234 }
11235   [(set (attr "type")
11236      (cond [(eq_attr "alternative" "1")
11237               (const_string "lea")
11238             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11239                           (const_int 0))
11240                       (match_operand 0 "register_operand" ""))
11241                  (match_operand 2 "const1_operand" ""))
11242               (const_string "alu")
11243            ]
11244            (const_string "ishift")))
11245    (set_attr "mode" "HI,SI")])
11246
11247 (define_insn "*ashlhi3_1"
11248   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11249         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11250                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11251    (clobber (reg:CC FLAGS_REG))]
11252   "TARGET_PARTIAL_REG_STALL
11253    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11254 {
11255   switch (get_attr_type (insn))
11256     {
11257     case TYPE_ALU:
11258       gcc_assert (operands[2] == const1_rtx);
11259       return "add{w}\t%0, %0";
11260
11261     default:
11262       if (REG_P (operands[2]))
11263         return "sal{w}\t{%b2, %0|%0, %b2}";
11264       else if (operands[2] == const1_rtx
11265                && (TARGET_SHIFT1 || optimize_size))
11266         return "sal{w}\t%0";
11267       else
11268         return "sal{w}\t{%2, %0|%0, %2}";
11269     }
11270 }
11271   [(set (attr "type")
11272      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11273                           (const_int 0))
11274                       (match_operand 0 "register_operand" ""))
11275                  (match_operand 2 "const1_operand" ""))
11276               (const_string "alu")
11277            ]
11278            (const_string "ishift")))
11279    (set_attr "mode" "HI")])
11280
11281 ;; This pattern can't accept a variable shift count, since shifts by
11282 ;; zero don't affect the flags.  We assume that shifts by constant
11283 ;; zero are optimized away.
11284 (define_insn "*ashlhi3_cmp"
11285   [(set (reg FLAGS_REG)
11286         (compare
11287           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11288                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11289           (const_int 0)))
11290    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11291         (ashift:HI (match_dup 1) (match_dup 2)))]
11292   "ix86_match_ccmode (insn, CCGOCmode)
11293    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11294    && (optimize_size
11295        || !TARGET_PARTIAL_FLAG_REG_STALL
11296        || (operands[2] == const1_rtx
11297            && (TARGET_SHIFT1
11298                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11299 {
11300   switch (get_attr_type (insn))
11301     {
11302     case TYPE_ALU:
11303       gcc_assert (operands[2] == const1_rtx);
11304       return "add{w}\t%0, %0";
11305
11306     default:
11307       if (REG_P (operands[2]))
11308         return "sal{w}\t{%b2, %0|%0, %b2}";
11309       else if (operands[2] == const1_rtx
11310                && (TARGET_SHIFT1 || optimize_size))
11311         return "sal{w}\t%0";
11312       else
11313         return "sal{w}\t{%2, %0|%0, %2}";
11314     }
11315 }
11316   [(set (attr "type")
11317      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11318                           (const_int 0))
11319                       (match_operand 0 "register_operand" ""))
11320                  (match_operand 2 "const1_operand" ""))
11321               (const_string "alu")
11322            ]
11323            (const_string "ishift")))
11324    (set_attr "mode" "HI")])
11325
11326 (define_insn "*ashlhi3_cconly"
11327   [(set (reg FLAGS_REG)
11328         (compare
11329           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11330                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11331           (const_int 0)))
11332    (clobber (match_scratch:HI 0 "=r"))]
11333   "ix86_match_ccmode (insn, CCGOCmode)
11334    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11335    && (optimize_size
11336        || !TARGET_PARTIAL_FLAG_REG_STALL
11337        || (operands[2] == const1_rtx
11338            && (TARGET_SHIFT1
11339                || TARGET_DOUBLE_WITH_ADD)))"
11340 {
11341   switch (get_attr_type (insn))
11342     {
11343     case TYPE_ALU:
11344       gcc_assert (operands[2] == const1_rtx);
11345       return "add{w}\t%0, %0";
11346
11347     default:
11348       if (REG_P (operands[2]))
11349         return "sal{w}\t{%b2, %0|%0, %b2}";
11350       else if (operands[2] == const1_rtx
11351                && (TARGET_SHIFT1 || optimize_size))
11352         return "sal{w}\t%0";
11353       else
11354         return "sal{w}\t{%2, %0|%0, %2}";
11355     }
11356 }
11357   [(set (attr "type")
11358      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11359                           (const_int 0))
11360                       (match_operand 0 "register_operand" ""))
11361                  (match_operand 2 "const1_operand" ""))
11362               (const_string "alu")
11363            ]
11364            (const_string "ishift")))
11365    (set_attr "mode" "HI")])
11366
11367 (define_expand "ashlqi3"
11368   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11369         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11370                    (match_operand:QI 2 "nonmemory_operand" "")))
11371    (clobber (reg:CC FLAGS_REG))]
11372   "TARGET_QIMODE_MATH"
11373   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11374
11375 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11376
11377 (define_insn "*ashlqi3_1_lea"
11378   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11379         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11380                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11381    (clobber (reg:CC FLAGS_REG))]
11382   "!TARGET_PARTIAL_REG_STALL
11383    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11384 {
11385   switch (get_attr_type (insn))
11386     {
11387     case TYPE_LEA:
11388       return "#";
11389     case TYPE_ALU:
11390       gcc_assert (operands[2] == const1_rtx);
11391       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11392         return "add{l}\t%k0, %k0";
11393       else
11394         return "add{b}\t%0, %0";
11395
11396     default:
11397       if (REG_P (operands[2]))
11398         {
11399           if (get_attr_mode (insn) == MODE_SI)
11400             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11401           else
11402             return "sal{b}\t{%b2, %0|%0, %b2}";
11403         }
11404       else if (operands[2] == const1_rtx
11405                && (TARGET_SHIFT1 || optimize_size))
11406         {
11407           if (get_attr_mode (insn) == MODE_SI)
11408             return "sal{l}\t%0";
11409           else
11410             return "sal{b}\t%0";
11411         }
11412       else
11413         {
11414           if (get_attr_mode (insn) == MODE_SI)
11415             return "sal{l}\t{%2, %k0|%k0, %2}";
11416           else
11417             return "sal{b}\t{%2, %0|%0, %2}";
11418         }
11419     }
11420 }
11421   [(set (attr "type")
11422      (cond [(eq_attr "alternative" "2")
11423               (const_string "lea")
11424             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11425                           (const_int 0))
11426                       (match_operand 0 "register_operand" ""))
11427                  (match_operand 2 "const1_operand" ""))
11428               (const_string "alu")
11429            ]
11430            (const_string "ishift")))
11431    (set_attr "mode" "QI,SI,SI")])
11432
11433 (define_insn "*ashlqi3_1"
11434   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11435         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11436                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11437    (clobber (reg:CC FLAGS_REG))]
11438   "TARGET_PARTIAL_REG_STALL
11439    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11440 {
11441   switch (get_attr_type (insn))
11442     {
11443     case TYPE_ALU:
11444       gcc_assert (operands[2] == const1_rtx);
11445       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11446         return "add{l}\t%k0, %k0";
11447       else
11448         return "add{b}\t%0, %0";
11449
11450     default:
11451       if (REG_P (operands[2]))
11452         {
11453           if (get_attr_mode (insn) == MODE_SI)
11454             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11455           else
11456             return "sal{b}\t{%b2, %0|%0, %b2}";
11457         }
11458       else if (operands[2] == const1_rtx
11459                && (TARGET_SHIFT1 || optimize_size))
11460         {
11461           if (get_attr_mode (insn) == MODE_SI)
11462             return "sal{l}\t%0";
11463           else
11464             return "sal{b}\t%0";
11465         }
11466       else
11467         {
11468           if (get_attr_mode (insn) == MODE_SI)
11469             return "sal{l}\t{%2, %k0|%k0, %2}";
11470           else
11471             return "sal{b}\t{%2, %0|%0, %2}";
11472         }
11473     }
11474 }
11475   [(set (attr "type")
11476      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11477                           (const_int 0))
11478                       (match_operand 0 "register_operand" ""))
11479                  (match_operand 2 "const1_operand" ""))
11480               (const_string "alu")
11481            ]
11482            (const_string "ishift")))
11483    (set_attr "mode" "QI,SI")])
11484
11485 ;; This pattern can't accept a variable shift count, since shifts by
11486 ;; zero don't affect the flags.  We assume that shifts by constant
11487 ;; zero are optimized away.
11488 (define_insn "*ashlqi3_cmp"
11489   [(set (reg FLAGS_REG)
11490         (compare
11491           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11492                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11493           (const_int 0)))
11494    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11495         (ashift:QI (match_dup 1) (match_dup 2)))]
11496   "ix86_match_ccmode (insn, CCGOCmode)
11497    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11498    && (optimize_size
11499        || !TARGET_PARTIAL_FLAG_REG_STALL
11500        || (operands[2] == const1_rtx
11501            && (TARGET_SHIFT1
11502                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11503 {
11504   switch (get_attr_type (insn))
11505     {
11506     case TYPE_ALU:
11507       gcc_assert (operands[2] == const1_rtx);
11508       return "add{b}\t%0, %0";
11509
11510     default:
11511       if (REG_P (operands[2]))
11512         return "sal{b}\t{%b2, %0|%0, %b2}";
11513       else if (operands[2] == const1_rtx
11514                && (TARGET_SHIFT1 || optimize_size))
11515         return "sal{b}\t%0";
11516       else
11517         return "sal{b}\t{%2, %0|%0, %2}";
11518     }
11519 }
11520   [(set (attr "type")
11521      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11522                           (const_int 0))
11523                       (match_operand 0 "register_operand" ""))
11524                  (match_operand 2 "const1_operand" ""))
11525               (const_string "alu")
11526            ]
11527            (const_string "ishift")))
11528    (set_attr "mode" "QI")])
11529
11530 (define_insn "*ashlqi3_cconly"
11531   [(set (reg FLAGS_REG)
11532         (compare
11533           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11534                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11535           (const_int 0)))
11536    (clobber (match_scratch:QI 0 "=q"))]
11537   "ix86_match_ccmode (insn, CCGOCmode)
11538    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11539    && (optimize_size
11540        || !TARGET_PARTIAL_FLAG_REG_STALL
11541        || (operands[2] == const1_rtx
11542            && (TARGET_SHIFT1
11543                || TARGET_DOUBLE_WITH_ADD)))"
11544 {
11545   switch (get_attr_type (insn))
11546     {
11547     case TYPE_ALU:
11548       gcc_assert (operands[2] == const1_rtx);
11549       return "add{b}\t%0, %0";
11550
11551     default:
11552       if (REG_P (operands[2]))
11553         return "sal{b}\t{%b2, %0|%0, %b2}";
11554       else if (operands[2] == const1_rtx
11555                && (TARGET_SHIFT1 || optimize_size))
11556         return "sal{b}\t%0";
11557       else
11558         return "sal{b}\t{%2, %0|%0, %2}";
11559     }
11560 }
11561   [(set (attr "type")
11562      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11563                           (const_int 0))
11564                       (match_operand 0 "register_operand" ""))
11565                  (match_operand 2 "const1_operand" ""))
11566               (const_string "alu")
11567            ]
11568            (const_string "ishift")))
11569    (set_attr "mode" "QI")])
11570
11571 ;; See comment above `ashldi3' about how this works.
11572
11573 (define_expand "ashrti3"
11574   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11575                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11576                                 (match_operand:QI 2 "nonmemory_operand" "")))
11577               (clobber (reg:CC FLAGS_REG))])]
11578   "TARGET_64BIT"
11579 {
11580   if (! immediate_operand (operands[2], QImode))
11581     {
11582       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11583       DONE;
11584     }
11585   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11586   DONE;
11587 })
11588
11589 (define_insn "ashrti3_1"
11590   [(set (match_operand:TI 0 "register_operand" "=r")
11591         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11592                      (match_operand:QI 2 "register_operand" "c")))
11593    (clobber (match_scratch:DI 3 "=&r"))
11594    (clobber (reg:CC FLAGS_REG))]
11595   "TARGET_64BIT"
11596   "#"
11597   [(set_attr "type" "multi")])
11598
11599 (define_insn "*ashrti3_2"
11600   [(set (match_operand:TI 0 "register_operand" "=r")
11601         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11602                      (match_operand:QI 2 "immediate_operand" "O")))
11603    (clobber (reg:CC FLAGS_REG))]
11604   "TARGET_64BIT"
11605   "#"
11606   [(set_attr "type" "multi")])
11607
11608 (define_split
11609   [(set (match_operand:TI 0 "register_operand" "")
11610         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11611                      (match_operand:QI 2 "register_operand" "")))
11612    (clobber (match_scratch:DI 3 ""))
11613    (clobber (reg:CC FLAGS_REG))]
11614   "TARGET_64BIT && reload_completed"
11615   [(const_int 0)]
11616   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11617
11618 (define_split
11619   [(set (match_operand:TI 0 "register_operand" "")
11620         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11621                      (match_operand:QI 2 "immediate_operand" "")))
11622    (clobber (reg:CC FLAGS_REG))]
11623   "TARGET_64BIT && reload_completed"
11624   [(const_int 0)]
11625   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11626
11627 (define_insn "x86_64_shrd"
11628   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11629         (ior:DI (ashiftrt:DI (match_dup 0)
11630                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11631                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11632                   (minus:QI (const_int 64) (match_dup 2)))))
11633    (clobber (reg:CC FLAGS_REG))]
11634   "TARGET_64BIT"
11635   "@
11636    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11637    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11638   [(set_attr "type" "ishift")
11639    (set_attr "prefix_0f" "1")
11640    (set_attr "mode" "DI")
11641    (set_attr "athlon_decode" "vector")
11642    (set_attr "amdfam10_decode" "vector")])   
11643
11644 (define_expand "ashrdi3"
11645   [(set (match_operand:DI 0 "shiftdi_operand" "")
11646         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11647                      (match_operand:QI 2 "nonmemory_operand" "")))]
11648   ""
11649   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11650
11651 (define_insn "*ashrdi3_63_rex64"
11652   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11653         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11654                      (match_operand:DI 2 "const_int_operand" "i,i")))
11655    (clobber (reg:CC FLAGS_REG))]
11656   "TARGET_64BIT && INTVAL (operands[2]) == 63
11657    && (TARGET_USE_CLTD || optimize_size)
11658    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11659   "@
11660    {cqto|cqo}
11661    sar{q}\t{%2, %0|%0, %2}"
11662   [(set_attr "type" "imovx,ishift")
11663    (set_attr "prefix_0f" "0,*")
11664    (set_attr "length_immediate" "0,*")
11665    (set_attr "modrm" "0,1")
11666    (set_attr "mode" "DI")])
11667
11668 (define_insn "*ashrdi3_1_one_bit_rex64"
11669   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11670         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11671                      (match_operand:QI 2 "const1_operand" "")))
11672    (clobber (reg:CC FLAGS_REG))]
11673   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11674    && (TARGET_SHIFT1 || optimize_size)"
11675   "sar{q}\t%0"
11676   [(set_attr "type" "ishift")
11677    (set (attr "length")
11678      (if_then_else (match_operand:DI 0 "register_operand" "")
11679         (const_string "2")
11680         (const_string "*")))])
11681
11682 (define_insn "*ashrdi3_1_rex64"
11683   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11684         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11685                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11686    (clobber (reg:CC FLAGS_REG))]
11687   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11688   "@
11689    sar{q}\t{%2, %0|%0, %2}
11690    sar{q}\t{%b2, %0|%0, %b2}"
11691   [(set_attr "type" "ishift")
11692    (set_attr "mode" "DI")])
11693
11694 ;; This pattern can't accept a variable shift count, since shifts by
11695 ;; zero don't affect the flags.  We assume that shifts by constant
11696 ;; zero are optimized away.
11697 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11698   [(set (reg FLAGS_REG)
11699         (compare
11700           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11701                        (match_operand:QI 2 "const1_operand" ""))
11702           (const_int 0)))
11703    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11704         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11705   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11706    && (TARGET_SHIFT1 || optimize_size)
11707    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11708   "sar{q}\t%0"
11709   [(set_attr "type" "ishift")
11710    (set (attr "length")
11711      (if_then_else (match_operand:DI 0 "register_operand" "")
11712         (const_string "2")
11713         (const_string "*")))])
11714
11715 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11716   [(set (reg FLAGS_REG)
11717         (compare
11718           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11719                        (match_operand:QI 2 "const1_operand" ""))
11720           (const_int 0)))
11721    (clobber (match_scratch:DI 0 "=r"))]
11722   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11723    && (TARGET_SHIFT1 || optimize_size)
11724    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11725   "sar{q}\t%0"
11726   [(set_attr "type" "ishift")
11727    (set_attr "length" "2")])
11728
11729 ;; This pattern can't accept a variable shift count, since shifts by
11730 ;; zero don't affect the flags.  We assume that shifts by constant
11731 ;; zero are optimized away.
11732 (define_insn "*ashrdi3_cmp_rex64"
11733   [(set (reg FLAGS_REG)
11734         (compare
11735           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11736                        (match_operand:QI 2 "const_int_operand" "n"))
11737           (const_int 0)))
11738    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11739         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11740   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11741    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11742    && (optimize_size
11743        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11744   "sar{q}\t{%2, %0|%0, %2}"
11745   [(set_attr "type" "ishift")
11746    (set_attr "mode" "DI")])
11747
11748 (define_insn "*ashrdi3_cconly_rex64"
11749   [(set (reg FLAGS_REG)
11750         (compare
11751           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11752                        (match_operand:QI 2 "const_int_operand" "n"))
11753           (const_int 0)))
11754    (clobber (match_scratch:DI 0 "=r"))]
11755   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11756    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11757    && (optimize_size
11758        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11759   "sar{q}\t{%2, %0|%0, %2}"
11760   [(set_attr "type" "ishift")
11761    (set_attr "mode" "DI")])
11762
11763 (define_insn "*ashrdi3_1"
11764   [(set (match_operand:DI 0 "register_operand" "=r")
11765         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11766                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11767    (clobber (reg:CC FLAGS_REG))]
11768   "!TARGET_64BIT"
11769   "#"
11770   [(set_attr "type" "multi")])
11771
11772 ;; By default we don't ask for a scratch register, because when DImode
11773 ;; values are manipulated, registers are already at a premium.  But if
11774 ;; we have one handy, we won't turn it away.
11775 (define_peephole2
11776   [(match_scratch:SI 3 "r")
11777    (parallel [(set (match_operand:DI 0 "register_operand" "")
11778                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11779                                 (match_operand:QI 2 "nonmemory_operand" "")))
11780               (clobber (reg:CC FLAGS_REG))])
11781    (match_dup 3)]
11782   "!TARGET_64BIT && TARGET_CMOVE"
11783   [(const_int 0)]
11784   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11785
11786 (define_split
11787   [(set (match_operand:DI 0 "register_operand" "")
11788         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11789                      (match_operand:QI 2 "nonmemory_operand" "")))
11790    (clobber (reg:CC FLAGS_REG))]
11791   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11792                      ? flow2_completed : reload_completed)"
11793   [(const_int 0)]
11794   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11795
11796 (define_insn "x86_shrd_1"
11797   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11798         (ior:SI (ashiftrt:SI (match_dup 0)
11799                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11800                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11801                   (minus:QI (const_int 32) (match_dup 2)))))
11802    (clobber (reg:CC FLAGS_REG))]
11803   ""
11804   "@
11805    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11806    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11807   [(set_attr "type" "ishift")
11808    (set_attr "prefix_0f" "1")
11809    (set_attr "pent_pair" "np")
11810    (set_attr "mode" "SI")])
11811
11812 (define_expand "x86_shift_adj_3"
11813   [(use (match_operand:SI 0 "register_operand" ""))
11814    (use (match_operand:SI 1 "register_operand" ""))
11815    (use (match_operand:QI 2 "register_operand" ""))]
11816   ""
11817 {
11818   rtx label = gen_label_rtx ();
11819   rtx tmp;
11820
11821   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11822
11823   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11824   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11825   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11826                               gen_rtx_LABEL_REF (VOIDmode, label),
11827                               pc_rtx);
11828   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11829   JUMP_LABEL (tmp) = label;
11830
11831   emit_move_insn (operands[0], operands[1]);
11832   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11833
11834   emit_label (label);
11835   LABEL_NUSES (label) = 1;
11836
11837   DONE;
11838 })
11839
11840 (define_insn "ashrsi3_31"
11841   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11842         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11843                      (match_operand:SI 2 "const_int_operand" "i,i")))
11844    (clobber (reg:CC FLAGS_REG))]
11845   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11846    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11847   "@
11848    {cltd|cdq}
11849    sar{l}\t{%2, %0|%0, %2}"
11850   [(set_attr "type" "imovx,ishift")
11851    (set_attr "prefix_0f" "0,*")
11852    (set_attr "length_immediate" "0,*")
11853    (set_attr "modrm" "0,1")
11854    (set_attr "mode" "SI")])
11855
11856 (define_insn "*ashrsi3_31_zext"
11857   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11858         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11859                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11860    (clobber (reg:CC FLAGS_REG))]
11861   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11862    && INTVAL (operands[2]) == 31
11863    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11864   "@
11865    {cltd|cdq}
11866    sar{l}\t{%2, %k0|%k0, %2}"
11867   [(set_attr "type" "imovx,ishift")
11868    (set_attr "prefix_0f" "0,*")
11869    (set_attr "length_immediate" "0,*")
11870    (set_attr "modrm" "0,1")
11871    (set_attr "mode" "SI")])
11872
11873 (define_expand "ashrsi3"
11874   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11875         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11876                      (match_operand:QI 2 "nonmemory_operand" "")))
11877    (clobber (reg:CC FLAGS_REG))]
11878   ""
11879   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11880
11881 (define_insn "*ashrsi3_1_one_bit"
11882   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11883         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11884                      (match_operand:QI 2 "const1_operand" "")))
11885    (clobber (reg:CC FLAGS_REG))]
11886   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11887    && (TARGET_SHIFT1 || optimize_size)"
11888   "sar{l}\t%0"
11889   [(set_attr "type" "ishift")
11890    (set (attr "length")
11891      (if_then_else (match_operand:SI 0 "register_operand" "")
11892         (const_string "2")
11893         (const_string "*")))])
11894
11895 (define_insn "*ashrsi3_1_one_bit_zext"
11896   [(set (match_operand:DI 0 "register_operand" "=r")
11897         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11898                                      (match_operand:QI 2 "const1_operand" ""))))
11899    (clobber (reg:CC FLAGS_REG))]
11900   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11901    && (TARGET_SHIFT1 || optimize_size)"
11902   "sar{l}\t%k0"
11903   [(set_attr "type" "ishift")
11904    (set_attr "length" "2")])
11905
11906 (define_insn "*ashrsi3_1"
11907   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11908         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11909                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11910    (clobber (reg:CC FLAGS_REG))]
11911   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11912   "@
11913    sar{l}\t{%2, %0|%0, %2}
11914    sar{l}\t{%b2, %0|%0, %b2}"
11915   [(set_attr "type" "ishift")
11916    (set_attr "mode" "SI")])
11917
11918 (define_insn "*ashrsi3_1_zext"
11919   [(set (match_operand:DI 0 "register_operand" "=r,r")
11920         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11921                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11922    (clobber (reg:CC FLAGS_REG))]
11923   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11924   "@
11925    sar{l}\t{%2, %k0|%k0, %2}
11926    sar{l}\t{%b2, %k0|%k0, %b2}"
11927   [(set_attr "type" "ishift")
11928    (set_attr "mode" "SI")])
11929
11930 ;; This pattern can't accept a variable shift count, since shifts by
11931 ;; zero don't affect the flags.  We assume that shifts by constant
11932 ;; zero are optimized away.
11933 (define_insn "*ashrsi3_one_bit_cmp"
11934   [(set (reg FLAGS_REG)
11935         (compare
11936           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11937                        (match_operand:QI 2 "const1_operand" ""))
11938           (const_int 0)))
11939    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11940         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11941   "ix86_match_ccmode (insn, CCGOCmode)
11942    && (TARGET_SHIFT1 || optimize_size)
11943    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11944   "sar{l}\t%0"
11945   [(set_attr "type" "ishift")
11946    (set (attr "length")
11947      (if_then_else (match_operand:SI 0 "register_operand" "")
11948         (const_string "2")
11949         (const_string "*")))])
11950
11951 (define_insn "*ashrsi3_one_bit_cconly"
11952   [(set (reg FLAGS_REG)
11953         (compare
11954           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11955                        (match_operand:QI 2 "const1_operand" ""))
11956           (const_int 0)))
11957    (clobber (match_scratch:SI 0 "=r"))]
11958   "ix86_match_ccmode (insn, CCGOCmode)
11959    && (TARGET_SHIFT1 || optimize_size)
11960    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11961   "sar{l}\t%0"
11962   [(set_attr "type" "ishift")
11963    (set_attr "length" "2")])
11964
11965 (define_insn "*ashrsi3_one_bit_cmp_zext"
11966   [(set (reg FLAGS_REG)
11967         (compare
11968           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11969                        (match_operand:QI 2 "const1_operand" ""))
11970           (const_int 0)))
11971    (set (match_operand:DI 0 "register_operand" "=r")
11972         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11973   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11974    && (TARGET_SHIFT1 || optimize_size)
11975    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11976   "sar{l}\t%k0"
11977   [(set_attr "type" "ishift")
11978    (set_attr "length" "2")])
11979
11980 ;; This pattern can't accept a variable shift count, since shifts by
11981 ;; zero don't affect the flags.  We assume that shifts by constant
11982 ;; zero are optimized away.
11983 (define_insn "*ashrsi3_cmp"
11984   [(set (reg FLAGS_REG)
11985         (compare
11986           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11987                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11988           (const_int 0)))
11989    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11990         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11991   "ix86_match_ccmode (insn, CCGOCmode)
11992    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11993    && (optimize_size
11994        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11995   "sar{l}\t{%2, %0|%0, %2}"
11996   [(set_attr "type" "ishift")
11997    (set_attr "mode" "SI")])
11998
11999 (define_insn "*ashrsi3_cconly"
12000   [(set (reg FLAGS_REG)
12001         (compare
12002           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12003                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12004           (const_int 0)))
12005    (clobber (match_scratch:SI 0 "=r"))]
12006   "ix86_match_ccmode (insn, CCGOCmode)
12007    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
12008    && (optimize_size
12009        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12010   "sar{l}\t{%2, %0|%0, %2}"
12011   [(set_attr "type" "ishift")
12012    (set_attr "mode" "SI")])
12013
12014 (define_insn "*ashrsi3_cmp_zext"
12015   [(set (reg FLAGS_REG)
12016         (compare
12017           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12018                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12019           (const_int 0)))
12020    (set (match_operand:DI 0 "register_operand" "=r")
12021         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12022   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12023    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
12024    && (optimize_size
12025        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12026   "sar{l}\t{%2, %k0|%k0, %2}"
12027   [(set_attr "type" "ishift")
12028    (set_attr "mode" "SI")])
12029
12030 (define_expand "ashrhi3"
12031   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12032         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12033                      (match_operand:QI 2 "nonmemory_operand" "")))
12034    (clobber (reg:CC FLAGS_REG))]
12035   "TARGET_HIMODE_MATH"
12036   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12037
12038 (define_insn "*ashrhi3_1_one_bit"
12039   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12040         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12041                      (match_operand:QI 2 "const1_operand" "")))
12042    (clobber (reg:CC FLAGS_REG))]
12043   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12044    && (TARGET_SHIFT1 || optimize_size)"
12045   "sar{w}\t%0"
12046   [(set_attr "type" "ishift")
12047    (set (attr "length")
12048      (if_then_else (match_operand 0 "register_operand" "")
12049         (const_string "2")
12050         (const_string "*")))])
12051
12052 (define_insn "*ashrhi3_1"
12053   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12054         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12055                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12056    (clobber (reg:CC FLAGS_REG))]
12057   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12058   "@
12059    sar{w}\t{%2, %0|%0, %2}
12060    sar{w}\t{%b2, %0|%0, %b2}"
12061   [(set_attr "type" "ishift")
12062    (set_attr "mode" "HI")])
12063
12064 ;; This pattern can't accept a variable shift count, since shifts by
12065 ;; zero don't affect the flags.  We assume that shifts by constant
12066 ;; zero are optimized away.
12067 (define_insn "*ashrhi3_one_bit_cmp"
12068   [(set (reg FLAGS_REG)
12069         (compare
12070           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12071                        (match_operand:QI 2 "const1_operand" ""))
12072           (const_int 0)))
12073    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12074         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12075   "ix86_match_ccmode (insn, CCGOCmode)
12076    && (TARGET_SHIFT1 || optimize_size)
12077    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12078   "sar{w}\t%0"
12079   [(set_attr "type" "ishift")
12080    (set (attr "length")
12081      (if_then_else (match_operand 0 "register_operand" "")
12082         (const_string "2")
12083         (const_string "*")))])
12084
12085 (define_insn "*ashrhi3_one_bit_cconly"
12086   [(set (reg FLAGS_REG)
12087         (compare
12088           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12089                        (match_operand:QI 2 "const1_operand" ""))
12090           (const_int 0)))
12091    (clobber (match_scratch:HI 0 "=r"))]
12092   "ix86_match_ccmode (insn, CCGOCmode)
12093    && (TARGET_SHIFT1 || optimize_size)
12094    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12095   "sar{w}\t%0"
12096   [(set_attr "type" "ishift")
12097    (set_attr "length" "2")])
12098
12099 ;; This pattern can't accept a variable shift count, since shifts by
12100 ;; zero don't affect the flags.  We assume that shifts by constant
12101 ;; zero are optimized away.
12102 (define_insn "*ashrhi3_cmp"
12103   [(set (reg FLAGS_REG)
12104         (compare
12105           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12106                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12107           (const_int 0)))
12108    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12109         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12110   "ix86_match_ccmode (insn, CCGOCmode)
12111    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12112    && (optimize_size
12113        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12114   "sar{w}\t{%2, %0|%0, %2}"
12115   [(set_attr "type" "ishift")
12116    (set_attr "mode" "HI")])
12117
12118 (define_insn "*ashrhi3_cconly"
12119   [(set (reg FLAGS_REG)
12120         (compare
12121           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12122                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12123           (const_int 0)))
12124    (clobber (match_scratch:HI 0 "=r"))]
12125   "ix86_match_ccmode (insn, CCGOCmode)
12126    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12127    && (optimize_size
12128        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12129   "sar{w}\t{%2, %0|%0, %2}"
12130   [(set_attr "type" "ishift")
12131    (set_attr "mode" "HI")])
12132
12133 (define_expand "ashrqi3"
12134   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12135         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12136                      (match_operand:QI 2 "nonmemory_operand" "")))
12137    (clobber (reg:CC FLAGS_REG))]
12138   "TARGET_QIMODE_MATH"
12139   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12140
12141 (define_insn "*ashrqi3_1_one_bit"
12142   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12143         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12144                      (match_operand:QI 2 "const1_operand" "")))
12145    (clobber (reg:CC FLAGS_REG))]
12146   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12147    && (TARGET_SHIFT1 || optimize_size)"
12148   "sar{b}\t%0"
12149   [(set_attr "type" "ishift")
12150    (set (attr "length")
12151      (if_then_else (match_operand 0 "register_operand" "")
12152         (const_string "2")
12153         (const_string "*")))])
12154
12155 (define_insn "*ashrqi3_1_one_bit_slp"
12156   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12157         (ashiftrt:QI (match_dup 0)
12158                      (match_operand:QI 1 "const1_operand" "")))
12159    (clobber (reg:CC FLAGS_REG))]
12160   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12161    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
12162    && (TARGET_SHIFT1 || optimize_size)"
12163   "sar{b}\t%0"
12164   [(set_attr "type" "ishift1")
12165    (set (attr "length")
12166      (if_then_else (match_operand 0 "register_operand" "")
12167         (const_string "2")
12168         (const_string "*")))])
12169
12170 (define_insn "*ashrqi3_1"
12171   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12172         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12173                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12174    (clobber (reg:CC FLAGS_REG))]
12175   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12176   "@
12177    sar{b}\t{%2, %0|%0, %2}
12178    sar{b}\t{%b2, %0|%0, %b2}"
12179   [(set_attr "type" "ishift")
12180    (set_attr "mode" "QI")])
12181
12182 (define_insn "*ashrqi3_1_slp"
12183   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12184         (ashiftrt:QI (match_dup 0)
12185                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12186    (clobber (reg:CC FLAGS_REG))]
12187   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12188    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12189   "@
12190    sar{b}\t{%1, %0|%0, %1}
12191    sar{b}\t{%b1, %0|%0, %b1}"
12192   [(set_attr "type" "ishift1")
12193    (set_attr "mode" "QI")])
12194
12195 ;; This pattern can't accept a variable shift count, since shifts by
12196 ;; zero don't affect the flags.  We assume that shifts by constant
12197 ;; zero are optimized away.
12198 (define_insn "*ashrqi3_one_bit_cmp"
12199   [(set (reg FLAGS_REG)
12200         (compare
12201           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12202                        (match_operand:QI 2 "const1_operand" "I"))
12203           (const_int 0)))
12204    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12205         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12206   "ix86_match_ccmode (insn, CCGOCmode)
12207    && (TARGET_SHIFT1 || optimize_size)
12208    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12209   "sar{b}\t%0"
12210   [(set_attr "type" "ishift")
12211    (set (attr "length")
12212      (if_then_else (match_operand 0 "register_operand" "")
12213         (const_string "2")
12214         (const_string "*")))])
12215
12216 (define_insn "*ashrqi3_one_bit_cconly"
12217   [(set (reg FLAGS_REG)
12218         (compare
12219           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12220                        (match_operand:QI 2 "const1_operand" "I"))
12221           (const_int 0)))
12222    (clobber (match_scratch:QI 0 "=q"))]
12223   "ix86_match_ccmode (insn, CCGOCmode)
12224    && (TARGET_SHIFT1 || optimize_size)
12225    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12226   "sar{b}\t%0"
12227   [(set_attr "type" "ishift")
12228    (set_attr "length" "2")])
12229
12230 ;; This pattern can't accept a variable shift count, since shifts by
12231 ;; zero don't affect the flags.  We assume that shifts by constant
12232 ;; zero are optimized away.
12233 (define_insn "*ashrqi3_cmp"
12234   [(set (reg FLAGS_REG)
12235         (compare
12236           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12237                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12238           (const_int 0)))
12239    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12240         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12241   "ix86_match_ccmode (insn, CCGOCmode)
12242    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12243    && (optimize_size
12244        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12245   "sar{b}\t{%2, %0|%0, %2}"
12246   [(set_attr "type" "ishift")
12247    (set_attr "mode" "QI")])
12248
12249 (define_insn "*ashrqi3_cconly"
12250   [(set (reg FLAGS_REG)
12251         (compare
12252           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12253                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12254           (const_int 0)))
12255    (clobber (match_scratch:QI 0 "=q"))]
12256   "ix86_match_ccmode (insn, CCGOCmode)
12257    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12258    && (optimize_size
12259        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12260   "sar{b}\t{%2, %0|%0, %2}"
12261   [(set_attr "type" "ishift")
12262    (set_attr "mode" "QI")])
12263
12264 \f
12265 ;; Logical shift instructions
12266
12267 ;; See comment above `ashldi3' about how this works.
12268
12269 (define_expand "lshrti3"
12270   [(parallel [(set (match_operand:TI 0 "register_operand" "")
12271                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12272                                 (match_operand:QI 2 "nonmemory_operand" "")))
12273               (clobber (reg:CC FLAGS_REG))])]
12274   "TARGET_64BIT"
12275 {
12276   if (! immediate_operand (operands[2], QImode))
12277     {
12278       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12279       DONE;
12280     }
12281   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12282   DONE;
12283 })
12284
12285 (define_insn "lshrti3_1"
12286   [(set (match_operand:TI 0 "register_operand" "=r")
12287         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12288                      (match_operand:QI 2 "register_operand" "c")))
12289    (clobber (match_scratch:DI 3 "=&r"))
12290    (clobber (reg:CC FLAGS_REG))]
12291   "TARGET_64BIT"
12292   "#"
12293   [(set_attr "type" "multi")])
12294
12295 (define_insn "*lshrti3_2"
12296   [(set (match_operand:TI 0 "register_operand" "=r")
12297         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12298                      (match_operand:QI 2 "immediate_operand" "O")))
12299    (clobber (reg:CC FLAGS_REG))]
12300   "TARGET_64BIT"
12301   "#"
12302   [(set_attr "type" "multi")])
12303
12304 (define_split
12305   [(set (match_operand:TI 0 "register_operand" "")
12306         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12307                      (match_operand:QI 2 "register_operand" "")))
12308    (clobber (match_scratch:DI 3 ""))
12309    (clobber (reg:CC FLAGS_REG))]
12310   "TARGET_64BIT && reload_completed"
12311   [(const_int 0)]
12312   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12313
12314 (define_split
12315   [(set (match_operand:TI 0 "register_operand" "")
12316         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12317                      (match_operand:QI 2 "immediate_operand" "")))
12318    (clobber (reg:CC FLAGS_REG))]
12319   "TARGET_64BIT && reload_completed"
12320   [(const_int 0)]
12321   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12322
12323 (define_expand "lshrdi3"
12324   [(set (match_operand:DI 0 "shiftdi_operand" "")
12325         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12326                      (match_operand:QI 2 "nonmemory_operand" "")))]
12327   ""
12328   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12329
12330 (define_insn "*lshrdi3_1_one_bit_rex64"
12331   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12332         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12333                      (match_operand:QI 2 "const1_operand" "")))
12334    (clobber (reg:CC FLAGS_REG))]
12335   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12336    && (TARGET_SHIFT1 || optimize_size)"
12337   "shr{q}\t%0"
12338   [(set_attr "type" "ishift")
12339    (set (attr "length")
12340      (if_then_else (match_operand:DI 0 "register_operand" "")
12341         (const_string "2")
12342         (const_string "*")))])
12343
12344 (define_insn "*lshrdi3_1_rex64"
12345   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12346         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12347                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12348    (clobber (reg:CC FLAGS_REG))]
12349   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12350   "@
12351    shr{q}\t{%2, %0|%0, %2}
12352    shr{q}\t{%b2, %0|%0, %b2}"
12353   [(set_attr "type" "ishift")
12354    (set_attr "mode" "DI")])
12355
12356 ;; This pattern can't accept a variable shift count, since shifts by
12357 ;; zero don't affect the flags.  We assume that shifts by constant
12358 ;; zero are optimized away.
12359 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12360   [(set (reg FLAGS_REG)
12361         (compare
12362           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12363                        (match_operand:QI 2 "const1_operand" ""))
12364           (const_int 0)))
12365    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12366         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12367   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12368    && (TARGET_SHIFT1 || optimize_size)
12369    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12370   "shr{q}\t%0"
12371   [(set_attr "type" "ishift")
12372    (set (attr "length")
12373      (if_then_else (match_operand:DI 0 "register_operand" "")
12374         (const_string "2")
12375         (const_string "*")))])
12376
12377 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12378   [(set (reg FLAGS_REG)
12379         (compare
12380           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12381                        (match_operand:QI 2 "const1_operand" ""))
12382           (const_int 0)))
12383    (clobber (match_scratch:DI 0 "=r"))]
12384   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12385    && (TARGET_SHIFT1 || optimize_size)
12386    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12387   "shr{q}\t%0"
12388   [(set_attr "type" "ishift")
12389    (set_attr "length" "2")])
12390
12391 ;; This pattern can't accept a variable shift count, since shifts by
12392 ;; zero don't affect the flags.  We assume that shifts by constant
12393 ;; zero are optimized away.
12394 (define_insn "*lshrdi3_cmp_rex64"
12395   [(set (reg FLAGS_REG)
12396         (compare
12397           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12398                        (match_operand:QI 2 "const_int_operand" "e"))
12399           (const_int 0)))
12400    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12401         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12402   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12403    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12404    && (optimize_size
12405        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12406   "shr{q}\t{%2, %0|%0, %2}"
12407   [(set_attr "type" "ishift")
12408    (set_attr "mode" "DI")])
12409
12410 (define_insn "*lshrdi3_cconly_rex64"
12411   [(set (reg FLAGS_REG)
12412         (compare
12413           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12414                        (match_operand:QI 2 "const_int_operand" "e"))
12415           (const_int 0)))
12416    (clobber (match_scratch:DI 0 "=r"))]
12417   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12418    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12419    && (optimize_size
12420        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12421   "shr{q}\t{%2, %0|%0, %2}"
12422   [(set_attr "type" "ishift")
12423    (set_attr "mode" "DI")])
12424
12425 (define_insn "*lshrdi3_1"
12426   [(set (match_operand:DI 0 "register_operand" "=r")
12427         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12428                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12429    (clobber (reg:CC FLAGS_REG))]
12430   "!TARGET_64BIT"
12431   "#"
12432   [(set_attr "type" "multi")])
12433
12434 ;; By default we don't ask for a scratch register, because when DImode
12435 ;; values are manipulated, registers are already at a premium.  But if
12436 ;; we have one handy, we won't turn it away.
12437 (define_peephole2
12438   [(match_scratch:SI 3 "r")
12439    (parallel [(set (match_operand:DI 0 "register_operand" "")
12440                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12441                                 (match_operand:QI 2 "nonmemory_operand" "")))
12442               (clobber (reg:CC FLAGS_REG))])
12443    (match_dup 3)]
12444   "!TARGET_64BIT && TARGET_CMOVE"
12445   [(const_int 0)]
12446   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12447
12448 (define_split
12449   [(set (match_operand:DI 0 "register_operand" "")
12450         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12451                      (match_operand:QI 2 "nonmemory_operand" "")))
12452    (clobber (reg:CC FLAGS_REG))]
12453   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12454                      ? flow2_completed : reload_completed)"
12455   [(const_int 0)]
12456   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12457
12458 (define_expand "lshrsi3"
12459   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12460         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12461                      (match_operand:QI 2 "nonmemory_operand" "")))
12462    (clobber (reg:CC FLAGS_REG))]
12463   ""
12464   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12465
12466 (define_insn "*lshrsi3_1_one_bit"
12467   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12468         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12469                      (match_operand:QI 2 "const1_operand" "")))
12470    (clobber (reg:CC FLAGS_REG))]
12471   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12472    && (TARGET_SHIFT1 || optimize_size)"
12473   "shr{l}\t%0"
12474   [(set_attr "type" "ishift")
12475    (set (attr "length")
12476      (if_then_else (match_operand:SI 0 "register_operand" "")
12477         (const_string "2")
12478         (const_string "*")))])
12479
12480 (define_insn "*lshrsi3_1_one_bit_zext"
12481   [(set (match_operand:DI 0 "register_operand" "=r")
12482         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12483                      (match_operand:QI 2 "const1_operand" "")))
12484    (clobber (reg:CC FLAGS_REG))]
12485   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12486    && (TARGET_SHIFT1 || optimize_size)"
12487   "shr{l}\t%k0"
12488   [(set_attr "type" "ishift")
12489    (set_attr "length" "2")])
12490
12491 (define_insn "*lshrsi3_1"
12492   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12493         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12494                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12495    (clobber (reg:CC FLAGS_REG))]
12496   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12497   "@
12498    shr{l}\t{%2, %0|%0, %2}
12499    shr{l}\t{%b2, %0|%0, %b2}"
12500   [(set_attr "type" "ishift")
12501    (set_attr "mode" "SI")])
12502
12503 (define_insn "*lshrsi3_1_zext"
12504   [(set (match_operand:DI 0 "register_operand" "=r,r")
12505         (zero_extend:DI
12506           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12507                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12508    (clobber (reg:CC FLAGS_REG))]
12509   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12510   "@
12511    shr{l}\t{%2, %k0|%k0, %2}
12512    shr{l}\t{%b2, %k0|%k0, %b2}"
12513   [(set_attr "type" "ishift")
12514    (set_attr "mode" "SI")])
12515
12516 ;; This pattern can't accept a variable shift count, since shifts by
12517 ;; zero don't affect the flags.  We assume that shifts by constant
12518 ;; zero are optimized away.
12519 (define_insn "*lshrsi3_one_bit_cmp"
12520   [(set (reg FLAGS_REG)
12521         (compare
12522           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12523                        (match_operand:QI 2 "const1_operand" ""))
12524           (const_int 0)))
12525    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12526         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12527   "ix86_match_ccmode (insn, CCGOCmode)
12528    && (TARGET_SHIFT1 || optimize_size)
12529    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12530   "shr{l}\t%0"
12531   [(set_attr "type" "ishift")
12532    (set (attr "length")
12533      (if_then_else (match_operand:SI 0 "register_operand" "")
12534         (const_string "2")
12535         (const_string "*")))])
12536
12537 (define_insn "*lshrsi3_one_bit_cconly"
12538   [(set (reg FLAGS_REG)
12539         (compare
12540           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12541                        (match_operand:QI 2 "const1_operand" ""))
12542           (const_int 0)))
12543    (clobber (match_scratch:SI 0 "=r"))]
12544   "ix86_match_ccmode (insn, CCGOCmode)
12545    && (TARGET_SHIFT1 || optimize_size)
12546    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12547   "shr{l}\t%0"
12548   [(set_attr "type" "ishift")
12549    (set_attr "length" "2")])
12550
12551 (define_insn "*lshrsi3_cmp_one_bit_zext"
12552   [(set (reg FLAGS_REG)
12553         (compare
12554           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12555                        (match_operand:QI 2 "const1_operand" ""))
12556           (const_int 0)))
12557    (set (match_operand:DI 0 "register_operand" "=r")
12558         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12559   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12560    && (TARGET_SHIFT1 || optimize_size)
12561    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12562   "shr{l}\t%k0"
12563   [(set_attr "type" "ishift")
12564    (set_attr "length" "2")])
12565
12566 ;; This pattern can't accept a variable shift count, since shifts by
12567 ;; zero don't affect the flags.  We assume that shifts by constant
12568 ;; zero are optimized away.
12569 (define_insn "*lshrsi3_cmp"
12570   [(set (reg FLAGS_REG)
12571         (compare
12572           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12573                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12574           (const_int 0)))
12575    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12576         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12577   "ix86_match_ccmode (insn, CCGOCmode)
12578    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12579    && (optimize_size
12580        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12581   "shr{l}\t{%2, %0|%0, %2}"
12582   [(set_attr "type" "ishift")
12583    (set_attr "mode" "SI")])
12584
12585 (define_insn "*lshrsi3_cconly"
12586   [(set (reg FLAGS_REG)
12587       (compare
12588         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12589                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12590         (const_int 0)))
12591    (clobber (match_scratch:SI 0 "=r"))]
12592   "ix86_match_ccmode (insn, CCGOCmode)
12593    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12594    && (optimize_size
12595        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12596   "shr{l}\t{%2, %0|%0, %2}"
12597   [(set_attr "type" "ishift")
12598    (set_attr "mode" "SI")])
12599
12600 (define_insn "*lshrsi3_cmp_zext"
12601   [(set (reg FLAGS_REG)
12602         (compare
12603           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12604                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12605           (const_int 0)))
12606    (set (match_operand:DI 0 "register_operand" "=r")
12607         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12608   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12609    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12610    && (optimize_size
12611        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12612   "shr{l}\t{%2, %k0|%k0, %2}"
12613   [(set_attr "type" "ishift")
12614    (set_attr "mode" "SI")])
12615
12616 (define_expand "lshrhi3"
12617   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12618         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12619                      (match_operand:QI 2 "nonmemory_operand" "")))
12620    (clobber (reg:CC FLAGS_REG))]
12621   "TARGET_HIMODE_MATH"
12622   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12623
12624 (define_insn "*lshrhi3_1_one_bit"
12625   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12626         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12627                      (match_operand:QI 2 "const1_operand" "")))
12628    (clobber (reg:CC FLAGS_REG))]
12629   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12630    && (TARGET_SHIFT1 || optimize_size)"
12631   "shr{w}\t%0"
12632   [(set_attr "type" "ishift")
12633    (set (attr "length")
12634      (if_then_else (match_operand 0 "register_operand" "")
12635         (const_string "2")
12636         (const_string "*")))])
12637
12638 (define_insn "*lshrhi3_1"
12639   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12640         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12641                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12642    (clobber (reg:CC FLAGS_REG))]
12643   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12644   "@
12645    shr{w}\t{%2, %0|%0, %2}
12646    shr{w}\t{%b2, %0|%0, %b2}"
12647   [(set_attr "type" "ishift")
12648    (set_attr "mode" "HI")])
12649
12650 ;; This pattern can't accept a variable shift count, since shifts by
12651 ;; zero don't affect the flags.  We assume that shifts by constant
12652 ;; zero are optimized away.
12653 (define_insn "*lshrhi3_one_bit_cmp"
12654   [(set (reg FLAGS_REG)
12655         (compare
12656           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12657                        (match_operand:QI 2 "const1_operand" ""))
12658           (const_int 0)))
12659    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12660         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12661   "ix86_match_ccmode (insn, CCGOCmode)
12662    && (TARGET_SHIFT1 || optimize_size)
12663    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12664   "shr{w}\t%0"
12665   [(set_attr "type" "ishift")
12666    (set (attr "length")
12667      (if_then_else (match_operand:SI 0 "register_operand" "")
12668         (const_string "2")
12669         (const_string "*")))])
12670
12671 (define_insn "*lshrhi3_one_bit_cconly"
12672   [(set (reg FLAGS_REG)
12673         (compare
12674           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12675                        (match_operand:QI 2 "const1_operand" ""))
12676           (const_int 0)))
12677    (clobber (match_scratch:HI 0 "=r"))]
12678   "ix86_match_ccmode (insn, CCGOCmode)
12679    && (TARGET_SHIFT1 || optimize_size)
12680    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12681   "shr{w}\t%0"
12682   [(set_attr "type" "ishift")
12683    (set_attr "length" "2")])
12684
12685 ;; This pattern can't accept a variable shift count, since shifts by
12686 ;; zero don't affect the flags.  We assume that shifts by constant
12687 ;; zero are optimized away.
12688 (define_insn "*lshrhi3_cmp"
12689   [(set (reg FLAGS_REG)
12690         (compare
12691           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12692                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12693           (const_int 0)))
12694    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12695         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12696   "ix86_match_ccmode (insn, CCGOCmode)
12697    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12698    && (optimize_size
12699        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12700   "shr{w}\t{%2, %0|%0, %2}"
12701   [(set_attr "type" "ishift")
12702    (set_attr "mode" "HI")])
12703
12704 (define_insn "*lshrhi3_cconly"
12705   [(set (reg FLAGS_REG)
12706         (compare
12707           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12708                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12709           (const_int 0)))
12710    (clobber (match_scratch:HI 0 "=r"))]
12711   "ix86_match_ccmode (insn, CCGOCmode)
12712    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12713    && (optimize_size
12714        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12715   "shr{w}\t{%2, %0|%0, %2}"
12716   [(set_attr "type" "ishift")
12717    (set_attr "mode" "HI")])
12718
12719 (define_expand "lshrqi3"
12720   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12721         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12722                      (match_operand:QI 2 "nonmemory_operand" "")))
12723    (clobber (reg:CC FLAGS_REG))]
12724   "TARGET_QIMODE_MATH"
12725   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12726
12727 (define_insn "*lshrqi3_1_one_bit"
12728   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12729         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12730                      (match_operand:QI 2 "const1_operand" "")))
12731    (clobber (reg:CC FLAGS_REG))]
12732   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12733    && (TARGET_SHIFT1 || optimize_size)"
12734   "shr{b}\t%0"
12735   [(set_attr "type" "ishift")
12736    (set (attr "length")
12737      (if_then_else (match_operand 0 "register_operand" "")
12738         (const_string "2")
12739         (const_string "*")))])
12740
12741 (define_insn "*lshrqi3_1_one_bit_slp"
12742   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12743         (lshiftrt:QI (match_dup 0)
12744                      (match_operand:QI 1 "const1_operand" "")))
12745    (clobber (reg:CC FLAGS_REG))]
12746   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12747    && (TARGET_SHIFT1 || optimize_size)"
12748   "shr{b}\t%0"
12749   [(set_attr "type" "ishift1")
12750    (set (attr "length")
12751      (if_then_else (match_operand 0 "register_operand" "")
12752         (const_string "2")
12753         (const_string "*")))])
12754
12755 (define_insn "*lshrqi3_1"
12756   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12757         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12758                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12759    (clobber (reg:CC FLAGS_REG))]
12760   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12761   "@
12762    shr{b}\t{%2, %0|%0, %2}
12763    shr{b}\t{%b2, %0|%0, %b2}"
12764   [(set_attr "type" "ishift")
12765    (set_attr "mode" "QI")])
12766
12767 (define_insn "*lshrqi3_1_slp"
12768   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12769         (lshiftrt:QI (match_dup 0)
12770                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12771    (clobber (reg:CC FLAGS_REG))]
12772   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12773    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12774   "@
12775    shr{b}\t{%1, %0|%0, %1}
12776    shr{b}\t{%b1, %0|%0, %b1}"
12777   [(set_attr "type" "ishift1")
12778    (set_attr "mode" "QI")])
12779
12780 ;; This pattern can't accept a variable shift count, since shifts by
12781 ;; zero don't affect the flags.  We assume that shifts by constant
12782 ;; zero are optimized away.
12783 (define_insn "*lshrqi2_one_bit_cmp"
12784   [(set (reg FLAGS_REG)
12785         (compare
12786           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12787                        (match_operand:QI 2 "const1_operand" ""))
12788           (const_int 0)))
12789    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12790         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12791   "ix86_match_ccmode (insn, CCGOCmode)
12792    && (TARGET_SHIFT1 || optimize_size)
12793    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12794   "shr{b}\t%0"
12795   [(set_attr "type" "ishift")
12796    (set (attr "length")
12797      (if_then_else (match_operand:SI 0 "register_operand" "")
12798         (const_string "2")
12799         (const_string "*")))])
12800
12801 (define_insn "*lshrqi2_one_bit_cconly"
12802   [(set (reg FLAGS_REG)
12803         (compare
12804           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12805                        (match_operand:QI 2 "const1_operand" ""))
12806           (const_int 0)))
12807    (clobber (match_scratch:QI 0 "=q"))]
12808   "ix86_match_ccmode (insn, CCGOCmode)
12809    && (TARGET_SHIFT1 || optimize_size)
12810    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12811   "shr{b}\t%0"
12812   [(set_attr "type" "ishift")
12813    (set_attr "length" "2")])
12814
12815 ;; This pattern can't accept a variable shift count, since shifts by
12816 ;; zero don't affect the flags.  We assume that shifts by constant
12817 ;; zero are optimized away.
12818 (define_insn "*lshrqi2_cmp"
12819   [(set (reg FLAGS_REG)
12820         (compare
12821           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12822                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12823           (const_int 0)))
12824    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12825         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12826   "ix86_match_ccmode (insn, CCGOCmode)
12827    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12828    && (optimize_size
12829        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12830   "shr{b}\t{%2, %0|%0, %2}"
12831   [(set_attr "type" "ishift")
12832    (set_attr "mode" "QI")])
12833
12834 (define_insn "*lshrqi2_cconly"
12835   [(set (reg FLAGS_REG)
12836         (compare
12837           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12838                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12839           (const_int 0)))
12840    (clobber (match_scratch:QI 0 "=q"))]
12841   "ix86_match_ccmode (insn, CCGOCmode)
12842    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12843    && (optimize_size
12844        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12845   "shr{b}\t{%2, %0|%0, %2}"
12846   [(set_attr "type" "ishift")
12847    (set_attr "mode" "QI")])
12848 \f
12849 ;; Rotate instructions
12850
12851 (define_expand "rotldi3"
12852   [(set (match_operand:DI 0 "shiftdi_operand" "")
12853         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12854                    (match_operand:QI 2 "nonmemory_operand" "")))
12855    (clobber (reg:CC FLAGS_REG))]
12856  ""
12857 {
12858   if (TARGET_64BIT)
12859     {
12860       ix86_expand_binary_operator (ROTATE, DImode, operands);
12861       DONE;
12862     }
12863   if (!const_1_to_31_operand (operands[2], VOIDmode))
12864     FAIL;
12865   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12866   DONE;
12867 })
12868
12869 ;; Implement rotation using two double-precision shift instructions
12870 ;; and a scratch register.
12871 (define_insn_and_split "ix86_rotldi3"
12872  [(set (match_operand:DI 0 "register_operand" "=r")
12873        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12874                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12875   (clobber (reg:CC FLAGS_REG))
12876   (clobber (match_scratch:SI 3 "=&r"))]
12877  "!TARGET_64BIT"
12878  ""
12879  "&& reload_completed"
12880  [(set (match_dup 3) (match_dup 4))
12881   (parallel
12882    [(set (match_dup 4)
12883          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12884                  (lshiftrt:SI (match_dup 5)
12885                               (minus:QI (const_int 32) (match_dup 2)))))
12886     (clobber (reg:CC FLAGS_REG))])
12887   (parallel
12888    [(set (match_dup 5)
12889          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12890                  (lshiftrt:SI (match_dup 3)
12891                               (minus:QI (const_int 32) (match_dup 2)))))
12892     (clobber (reg:CC FLAGS_REG))])]
12893  "split_di (operands, 1, operands + 4, operands + 5);")
12894
12895 (define_insn "*rotlsi3_1_one_bit_rex64"
12896   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12897         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12898                    (match_operand:QI 2 "const1_operand" "")))
12899    (clobber (reg:CC FLAGS_REG))]
12900   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12901    && (TARGET_SHIFT1 || optimize_size)"
12902   "rol{q}\t%0"
12903   [(set_attr "type" "rotate")
12904    (set (attr "length")
12905      (if_then_else (match_operand:DI 0 "register_operand" "")
12906         (const_string "2")
12907         (const_string "*")))])
12908
12909 (define_insn "*rotldi3_1_rex64"
12910   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12911         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12912                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12913    (clobber (reg:CC FLAGS_REG))]
12914   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12915   "@
12916    rol{q}\t{%2, %0|%0, %2}
12917    rol{q}\t{%b2, %0|%0, %b2}"
12918   [(set_attr "type" "rotate")
12919    (set_attr "mode" "DI")])
12920
12921 (define_expand "rotlsi3"
12922   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12923         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12924                    (match_operand:QI 2 "nonmemory_operand" "")))
12925    (clobber (reg:CC FLAGS_REG))]
12926   ""
12927   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12928
12929 (define_insn "*rotlsi3_1_one_bit"
12930   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12931         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12932                    (match_operand:QI 2 "const1_operand" "")))
12933    (clobber (reg:CC FLAGS_REG))]
12934   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12935    && (TARGET_SHIFT1 || optimize_size)"
12936   "rol{l}\t%0"
12937   [(set_attr "type" "rotate")
12938    (set (attr "length")
12939      (if_then_else (match_operand:SI 0 "register_operand" "")
12940         (const_string "2")
12941         (const_string "*")))])
12942
12943 (define_insn "*rotlsi3_1_one_bit_zext"
12944   [(set (match_operand:DI 0 "register_operand" "=r")
12945         (zero_extend:DI
12946           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12947                      (match_operand:QI 2 "const1_operand" ""))))
12948    (clobber (reg:CC FLAGS_REG))]
12949   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12950    && (TARGET_SHIFT1 || optimize_size)"
12951   "rol{l}\t%k0"
12952   [(set_attr "type" "rotate")
12953    (set_attr "length" "2")])
12954
12955 (define_insn "*rotlsi3_1"
12956   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12957         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12958                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12959    (clobber (reg:CC FLAGS_REG))]
12960   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12961   "@
12962    rol{l}\t{%2, %0|%0, %2}
12963    rol{l}\t{%b2, %0|%0, %b2}"
12964   [(set_attr "type" "rotate")
12965    (set_attr "mode" "SI")])
12966
12967 (define_insn "*rotlsi3_1_zext"
12968   [(set (match_operand:DI 0 "register_operand" "=r,r")
12969         (zero_extend:DI
12970           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12971                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12972    (clobber (reg:CC FLAGS_REG))]
12973   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12974   "@
12975    rol{l}\t{%2, %k0|%k0, %2}
12976    rol{l}\t{%b2, %k0|%k0, %b2}"
12977   [(set_attr "type" "rotate")
12978    (set_attr "mode" "SI")])
12979
12980 (define_expand "rotlhi3"
12981   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12982         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12983                    (match_operand:QI 2 "nonmemory_operand" "")))
12984    (clobber (reg:CC FLAGS_REG))]
12985   "TARGET_HIMODE_MATH"
12986   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12987
12988 (define_insn "*rotlhi3_1_one_bit"
12989   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12990         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12991                    (match_operand:QI 2 "const1_operand" "")))
12992    (clobber (reg:CC FLAGS_REG))]
12993   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12994    && (TARGET_SHIFT1 || optimize_size)"
12995   "rol{w}\t%0"
12996   [(set_attr "type" "rotate")
12997    (set (attr "length")
12998      (if_then_else (match_operand 0 "register_operand" "")
12999         (const_string "2")
13000         (const_string "*")))])
13001
13002 (define_insn "*rotlhi3_1"
13003   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13004         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13005                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13006    (clobber (reg:CC FLAGS_REG))]
13007   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13008   "@
13009    rol{w}\t{%2, %0|%0, %2}
13010    rol{w}\t{%b2, %0|%0, %b2}"
13011   [(set_attr "type" "rotate")
13012    (set_attr "mode" "HI")])
13013
13014 (define_split
13015  [(set (match_operand:HI 0 "register_operand" "")
13016        (rotate:HI (match_dup 0) (const_int 8)))
13017   (clobber (reg:CC FLAGS_REG))]
13018  "reload_completed"
13019  [(parallel [(set (strict_low_part (match_dup 0))
13020                   (bswap:HI (match_dup 0)))
13021              (clobber (reg:CC FLAGS_REG))])]
13022  "")
13023
13024 (define_expand "rotlqi3"
13025   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13026         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13027                    (match_operand:QI 2 "nonmemory_operand" "")))
13028    (clobber (reg:CC FLAGS_REG))]
13029   "TARGET_QIMODE_MATH"
13030   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13031
13032 (define_insn "*rotlqi3_1_one_bit_slp"
13033   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13034         (rotate:QI (match_dup 0)
13035                    (match_operand:QI 1 "const1_operand" "")))
13036    (clobber (reg:CC FLAGS_REG))]
13037   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13038    && (TARGET_SHIFT1 || optimize_size)"
13039   "rol{b}\t%0"
13040   [(set_attr "type" "rotate1")
13041    (set (attr "length")
13042      (if_then_else (match_operand 0 "register_operand" "")
13043         (const_string "2")
13044         (const_string "*")))])
13045
13046 (define_insn "*rotlqi3_1_one_bit"
13047   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13048         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13049                    (match_operand:QI 2 "const1_operand" "")))
13050    (clobber (reg:CC FLAGS_REG))]
13051   "ix86_binary_operator_ok (ROTATE, QImode, operands)
13052    && (TARGET_SHIFT1 || optimize_size)"
13053   "rol{b}\t%0"
13054   [(set_attr "type" "rotate")
13055    (set (attr "length")
13056      (if_then_else (match_operand 0 "register_operand" "")
13057         (const_string "2")
13058         (const_string "*")))])
13059
13060 (define_insn "*rotlqi3_1_slp"
13061   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13062         (rotate:QI (match_dup 0)
13063                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13064    (clobber (reg:CC FLAGS_REG))]
13065   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13066    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13067   "@
13068    rol{b}\t{%1, %0|%0, %1}
13069    rol{b}\t{%b1, %0|%0, %b1}"
13070   [(set_attr "type" "rotate1")
13071    (set_attr "mode" "QI")])
13072
13073 (define_insn "*rotlqi3_1"
13074   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13075         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13076                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13077    (clobber (reg:CC FLAGS_REG))]
13078   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13079   "@
13080    rol{b}\t{%2, %0|%0, %2}
13081    rol{b}\t{%b2, %0|%0, %b2}"
13082   [(set_attr "type" "rotate")
13083    (set_attr "mode" "QI")])
13084
13085 (define_expand "rotrdi3"
13086   [(set (match_operand:DI 0 "shiftdi_operand" "")
13087         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13088                    (match_operand:QI 2 "nonmemory_operand" "")))
13089    (clobber (reg:CC FLAGS_REG))]
13090  ""
13091 {
13092   if (TARGET_64BIT)
13093     {
13094       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13095       DONE;
13096     }
13097   if (!const_1_to_31_operand (operands[2], VOIDmode))
13098     FAIL;
13099   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13100   DONE;
13101 })
13102
13103 ;; Implement rotation using two double-precision shift instructions
13104 ;; and a scratch register.
13105 (define_insn_and_split "ix86_rotrdi3"
13106  [(set (match_operand:DI 0 "register_operand" "=r")
13107        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13108                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13109   (clobber (reg:CC FLAGS_REG))
13110   (clobber (match_scratch:SI 3 "=&r"))]
13111  "!TARGET_64BIT"
13112  ""
13113  "&& reload_completed"
13114  [(set (match_dup 3) (match_dup 4))
13115   (parallel
13116    [(set (match_dup 4)
13117          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13118                  (ashift:SI (match_dup 5)
13119                             (minus:QI (const_int 32) (match_dup 2)))))
13120     (clobber (reg:CC FLAGS_REG))])
13121   (parallel
13122    [(set (match_dup 5)
13123          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13124                  (ashift:SI (match_dup 3)
13125                             (minus:QI (const_int 32) (match_dup 2)))))
13126     (clobber (reg:CC FLAGS_REG))])]
13127  "split_di (operands, 1, operands + 4, operands + 5);")
13128
13129 (define_insn "*rotrdi3_1_one_bit_rex64"
13130   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13131         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13132                      (match_operand:QI 2 "const1_operand" "")))
13133    (clobber (reg:CC FLAGS_REG))]
13134   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
13135    && (TARGET_SHIFT1 || optimize_size)"
13136   "ror{q}\t%0"
13137   [(set_attr "type" "rotate")
13138    (set (attr "length")
13139      (if_then_else (match_operand:DI 0 "register_operand" "")
13140         (const_string "2")
13141         (const_string "*")))])
13142
13143 (define_insn "*rotrdi3_1_rex64"
13144   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13145         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13146                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13147    (clobber (reg:CC FLAGS_REG))]
13148   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13149   "@
13150    ror{q}\t{%2, %0|%0, %2}
13151    ror{q}\t{%b2, %0|%0, %b2}"
13152   [(set_attr "type" "rotate")
13153    (set_attr "mode" "DI")])
13154
13155 (define_expand "rotrsi3"
13156   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13157         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13158                      (match_operand:QI 2 "nonmemory_operand" "")))
13159    (clobber (reg:CC FLAGS_REG))]
13160   ""
13161   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13162
13163 (define_insn "*rotrsi3_1_one_bit"
13164   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13165         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13166                      (match_operand:QI 2 "const1_operand" "")))
13167    (clobber (reg:CC FLAGS_REG))]
13168   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
13169    && (TARGET_SHIFT1 || optimize_size)"
13170   "ror{l}\t%0"
13171   [(set_attr "type" "rotate")
13172    (set (attr "length")
13173      (if_then_else (match_operand:SI 0 "register_operand" "")
13174         (const_string "2")
13175         (const_string "*")))])
13176
13177 (define_insn "*rotrsi3_1_one_bit_zext"
13178   [(set (match_operand:DI 0 "register_operand" "=r")
13179         (zero_extend:DI
13180           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13181                        (match_operand:QI 2 "const1_operand" ""))))
13182    (clobber (reg:CC FLAGS_REG))]
13183   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
13184    && (TARGET_SHIFT1 || optimize_size)"
13185   "ror{l}\t%k0"
13186   [(set_attr "type" "rotate")
13187    (set (attr "length")
13188      (if_then_else (match_operand:SI 0 "register_operand" "")
13189         (const_string "2")
13190         (const_string "*")))])
13191
13192 (define_insn "*rotrsi3_1"
13193   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13194         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13195                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13196    (clobber (reg:CC FLAGS_REG))]
13197   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13198   "@
13199    ror{l}\t{%2, %0|%0, %2}
13200    ror{l}\t{%b2, %0|%0, %b2}"
13201   [(set_attr "type" "rotate")
13202    (set_attr "mode" "SI")])
13203
13204 (define_insn "*rotrsi3_1_zext"
13205   [(set (match_operand:DI 0 "register_operand" "=r,r")
13206         (zero_extend:DI
13207           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13208                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13209    (clobber (reg:CC FLAGS_REG))]
13210   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13211   "@
13212    ror{l}\t{%2, %k0|%k0, %2}
13213    ror{l}\t{%b2, %k0|%k0, %b2}"
13214   [(set_attr "type" "rotate")
13215    (set_attr "mode" "SI")])
13216
13217 (define_expand "rotrhi3"
13218   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13219         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13220                      (match_operand:QI 2 "nonmemory_operand" "")))
13221    (clobber (reg:CC FLAGS_REG))]
13222   "TARGET_HIMODE_MATH"
13223   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13224
13225 (define_insn "*rotrhi3_one_bit"
13226   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13227         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13228                      (match_operand:QI 2 "const1_operand" "")))
13229    (clobber (reg:CC FLAGS_REG))]
13230   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
13231    && (TARGET_SHIFT1 || optimize_size)"
13232   "ror{w}\t%0"
13233   [(set_attr "type" "rotate")
13234    (set (attr "length")
13235      (if_then_else (match_operand 0 "register_operand" "")
13236         (const_string "2")
13237         (const_string "*")))])
13238
13239 (define_insn "*rotrhi3_1"
13240   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13241         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13242                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13243    (clobber (reg:CC FLAGS_REG))]
13244   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13245   "@
13246    ror{w}\t{%2, %0|%0, %2}
13247    ror{w}\t{%b2, %0|%0, %b2}"
13248   [(set_attr "type" "rotate")
13249    (set_attr "mode" "HI")])
13250
13251 (define_split
13252  [(set (match_operand:HI 0 "register_operand" "")
13253        (rotatert:HI (match_dup 0) (const_int 8)))
13254   (clobber (reg:CC FLAGS_REG))]
13255  "reload_completed"
13256  [(parallel [(set (strict_low_part (match_dup 0))
13257                   (bswap:HI (match_dup 0)))
13258              (clobber (reg:CC FLAGS_REG))])]
13259  "")
13260
13261 (define_expand "rotrqi3"
13262   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13263         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13264                      (match_operand:QI 2 "nonmemory_operand" "")))
13265    (clobber (reg:CC FLAGS_REG))]
13266   "TARGET_QIMODE_MATH"
13267   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13268
13269 (define_insn "*rotrqi3_1_one_bit"
13270   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13271         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13272                      (match_operand:QI 2 "const1_operand" "")))
13273    (clobber (reg:CC FLAGS_REG))]
13274   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
13275    && (TARGET_SHIFT1 || optimize_size)"
13276   "ror{b}\t%0"
13277   [(set_attr "type" "rotate")
13278    (set (attr "length")
13279      (if_then_else (match_operand 0 "register_operand" "")
13280         (const_string "2")
13281         (const_string "*")))])
13282
13283 (define_insn "*rotrqi3_1_one_bit_slp"
13284   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13285         (rotatert:QI (match_dup 0)
13286                      (match_operand:QI 1 "const1_operand" "")))
13287    (clobber (reg:CC FLAGS_REG))]
13288   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13289    && (TARGET_SHIFT1 || optimize_size)"
13290   "ror{b}\t%0"
13291   [(set_attr "type" "rotate1")
13292    (set (attr "length")
13293      (if_then_else (match_operand 0 "register_operand" "")
13294         (const_string "2")
13295         (const_string "*")))])
13296
13297 (define_insn "*rotrqi3_1"
13298   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13299         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13300                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13301    (clobber (reg:CC FLAGS_REG))]
13302   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13303   "@
13304    ror{b}\t{%2, %0|%0, %2}
13305    ror{b}\t{%b2, %0|%0, %b2}"
13306   [(set_attr "type" "rotate")
13307    (set_attr "mode" "QI")])
13308
13309 (define_insn "*rotrqi3_1_slp"
13310   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13311         (rotatert:QI (match_dup 0)
13312                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13313    (clobber (reg:CC FLAGS_REG))]
13314   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13315    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13316   "@
13317    ror{b}\t{%1, %0|%0, %1}
13318    ror{b}\t{%b1, %0|%0, %b1}"
13319   [(set_attr "type" "rotate1")
13320    (set_attr "mode" "QI")])
13321 \f
13322 ;; Bit set / bit test instructions
13323
13324 (define_expand "extv"
13325   [(set (match_operand:SI 0 "register_operand" "")
13326         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13327                          (match_operand:SI 2 "const8_operand" "")
13328                          (match_operand:SI 3 "const8_operand" "")))]
13329   ""
13330 {
13331   /* Handle extractions from %ah et al.  */
13332   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13333     FAIL;
13334
13335   /* From mips.md: extract_bit_field doesn't verify that our source
13336      matches the predicate, so check it again here.  */
13337   if (! ext_register_operand (operands[1], VOIDmode))
13338     FAIL;
13339 })
13340
13341 (define_expand "extzv"
13342   [(set (match_operand:SI 0 "register_operand" "")
13343         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13344                          (match_operand:SI 2 "const8_operand" "")
13345                          (match_operand:SI 3 "const8_operand" "")))]
13346   ""
13347 {
13348   /* Handle extractions from %ah et al.  */
13349   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13350     FAIL;
13351
13352   /* From mips.md: extract_bit_field doesn't verify that our source
13353      matches the predicate, so check it again here.  */
13354   if (! ext_register_operand (operands[1], VOIDmode))
13355     FAIL;
13356 })
13357
13358 (define_expand "insv"
13359   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13360                       (match_operand 1 "const8_operand" "")
13361                       (match_operand 2 "const8_operand" ""))
13362         (match_operand 3 "register_operand" ""))]
13363   ""
13364 {
13365   /* Handle insertions to %ah et al.  */
13366   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13367     FAIL;
13368
13369   /* From mips.md: insert_bit_field doesn't verify that our source
13370      matches the predicate, so check it again here.  */
13371   if (! ext_register_operand (operands[0], VOIDmode))
13372     FAIL;
13373
13374   if (TARGET_64BIT)
13375     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13376   else
13377     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13378
13379   DONE;
13380 })
13381
13382 ;; %%% bts, btr, btc, bt.
13383 ;; In general these instructions are *slow* when applied to memory,
13384 ;; since they enforce atomic operation.  When applied to registers,
13385 ;; it depends on the cpu implementation.  They're never faster than
13386 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13387 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13388 ;; within the instruction itself, so operating on bits in the high
13389 ;; 32-bits of a register becomes easier.
13390 ;;
13391 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13392 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13393 ;; negdf respectively, so they can never be disabled entirely.
13394
13395 (define_insn "*btsq"
13396   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13397                          (const_int 1)
13398                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13399         (const_int 1))
13400    (clobber (reg:CC FLAGS_REG))]
13401   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13402   "bts{q} %1,%0"
13403   [(set_attr "type" "alu1")])
13404
13405 (define_insn "*btrq"
13406   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13407                          (const_int 1)
13408                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13409         (const_int 0))
13410    (clobber (reg:CC FLAGS_REG))]
13411   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13412   "btr{q} %1,%0"
13413   [(set_attr "type" "alu1")])
13414
13415 (define_insn "*btcq"
13416   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13417                          (const_int 1)
13418                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13419         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13420    (clobber (reg:CC FLAGS_REG))]
13421   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13422   "btc{q} %1,%0"
13423   [(set_attr "type" "alu1")])
13424
13425 ;; Allow Nocona to avoid these instructions if a register is available.
13426
13427 (define_peephole2
13428   [(match_scratch:DI 2 "r")
13429    (parallel [(set (zero_extract:DI
13430                      (match_operand:DI 0 "register_operand" "")
13431                      (const_int 1)
13432                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13433                    (const_int 1))
13434               (clobber (reg:CC FLAGS_REG))])]
13435   "TARGET_64BIT && !TARGET_USE_BT"
13436   [(const_int 0)]
13437 {
13438   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13439   rtx op1;
13440
13441   if (HOST_BITS_PER_WIDE_INT >= 64)
13442     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13443   else if (i < HOST_BITS_PER_WIDE_INT)
13444     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13445   else
13446     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13447
13448   op1 = immed_double_const (lo, hi, DImode);
13449   if (i >= 31)
13450     {
13451       emit_move_insn (operands[2], op1);
13452       op1 = operands[2];
13453     }
13454
13455   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13456   DONE;
13457 })
13458
13459 (define_peephole2
13460   [(match_scratch:DI 2 "r")
13461    (parallel [(set (zero_extract:DI
13462                      (match_operand:DI 0 "register_operand" "")
13463                      (const_int 1)
13464                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13465                    (const_int 0))
13466               (clobber (reg:CC FLAGS_REG))])]
13467   "TARGET_64BIT && !TARGET_USE_BT"
13468   [(const_int 0)]
13469 {
13470   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13471   rtx op1;
13472
13473   if (HOST_BITS_PER_WIDE_INT >= 64)
13474     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13475   else if (i < HOST_BITS_PER_WIDE_INT)
13476     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13477   else
13478     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13479
13480   op1 = immed_double_const (~lo, ~hi, DImode);
13481   if (i >= 32)
13482     {
13483       emit_move_insn (operands[2], op1);
13484       op1 = operands[2];
13485     }
13486
13487   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13488   DONE;
13489 })
13490
13491 (define_peephole2
13492   [(match_scratch:DI 2 "r")
13493    (parallel [(set (zero_extract:DI
13494                      (match_operand:DI 0 "register_operand" "")
13495                      (const_int 1)
13496                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13497               (not:DI (zero_extract:DI
13498                         (match_dup 0) (const_int 1) (match_dup 1))))
13499               (clobber (reg:CC FLAGS_REG))])]
13500   "TARGET_64BIT && !TARGET_USE_BT"
13501   [(const_int 0)]
13502 {
13503   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13504   rtx op1;
13505
13506   if (HOST_BITS_PER_WIDE_INT >= 64)
13507     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13508   else if (i < HOST_BITS_PER_WIDE_INT)
13509     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13510   else
13511     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13512
13513   op1 = immed_double_const (lo, hi, DImode);
13514   if (i >= 31)
13515     {
13516       emit_move_insn (operands[2], op1);
13517       op1 = operands[2];
13518     }
13519
13520   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13521   DONE;
13522 })
13523 \f
13524 ;; Store-flag instructions.
13525
13526 ;; For all sCOND expanders, also expand the compare or test insn that
13527 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13528
13529 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13530 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13531 ;; way, which can later delete the movzx if only QImode is needed.
13532
13533 (define_expand "seq"
13534   [(set (match_operand:QI 0 "register_operand" "")
13535         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13536   ""
13537   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13538
13539 (define_expand "sne"
13540   [(set (match_operand:QI 0 "register_operand" "")
13541         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13542   ""
13543   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13544
13545 (define_expand "sgt"
13546   [(set (match_operand:QI 0 "register_operand" "")
13547         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13548   ""
13549   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13550
13551 (define_expand "sgtu"
13552   [(set (match_operand:QI 0 "register_operand" "")
13553         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13554   ""
13555   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13556
13557 (define_expand "slt"
13558   [(set (match_operand:QI 0 "register_operand" "")
13559         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13560   ""
13561   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13562
13563 (define_expand "sltu"
13564   [(set (match_operand:QI 0 "register_operand" "")
13565         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13566   ""
13567   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13568
13569 (define_expand "sge"
13570   [(set (match_operand:QI 0 "register_operand" "")
13571         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13572   ""
13573   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13574
13575 (define_expand "sgeu"
13576   [(set (match_operand:QI 0 "register_operand" "")
13577         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13578   ""
13579   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13580
13581 (define_expand "sle"
13582   [(set (match_operand:QI 0 "register_operand" "")
13583         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13584   ""
13585   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13586
13587 (define_expand "sleu"
13588   [(set (match_operand:QI 0 "register_operand" "")
13589         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13590   ""
13591   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13592
13593 (define_expand "sunordered"
13594   [(set (match_operand:QI 0 "register_operand" "")
13595         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13596   "TARGET_80387 || TARGET_SSE"
13597   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13598
13599 (define_expand "sordered"
13600   [(set (match_operand:QI 0 "register_operand" "")
13601         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13602   "TARGET_80387"
13603   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13604
13605 (define_expand "suneq"
13606   [(set (match_operand:QI 0 "register_operand" "")
13607         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13608   "TARGET_80387 || TARGET_SSE"
13609   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13610
13611 (define_expand "sunge"
13612   [(set (match_operand:QI 0 "register_operand" "")
13613         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13614   "TARGET_80387 || TARGET_SSE"
13615   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13616
13617 (define_expand "sungt"
13618   [(set (match_operand:QI 0 "register_operand" "")
13619         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13620   "TARGET_80387 || TARGET_SSE"
13621   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13622
13623 (define_expand "sunle"
13624   [(set (match_operand:QI 0 "register_operand" "")
13625         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13626   "TARGET_80387 || TARGET_SSE"
13627   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13628
13629 (define_expand "sunlt"
13630   [(set (match_operand:QI 0 "register_operand" "")
13631         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13632   "TARGET_80387 || TARGET_SSE"
13633   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13634
13635 (define_expand "sltgt"
13636   [(set (match_operand:QI 0 "register_operand" "")
13637         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13638   "TARGET_80387 || TARGET_SSE"
13639   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13640
13641 (define_insn "*setcc_1"
13642   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13643         (match_operator:QI 1 "ix86_comparison_operator"
13644           [(reg FLAGS_REG) (const_int 0)]))]
13645   ""
13646   "set%C1\t%0"
13647   [(set_attr "type" "setcc")
13648    (set_attr "mode" "QI")])
13649
13650 (define_insn "*setcc_2"
13651   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13652         (match_operator:QI 1 "ix86_comparison_operator"
13653           [(reg FLAGS_REG) (const_int 0)]))]
13654   ""
13655   "set%C1\t%0"
13656   [(set_attr "type" "setcc")
13657    (set_attr "mode" "QI")])
13658
13659 ;; In general it is not safe to assume too much about CCmode registers,
13660 ;; so simplify-rtx stops when it sees a second one.  Under certain
13661 ;; conditions this is safe on x86, so help combine not create
13662 ;;
13663 ;;      seta    %al
13664 ;;      testb   %al, %al
13665 ;;      sete    %al
13666
13667 (define_split
13668   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13669         (ne:QI (match_operator 1 "ix86_comparison_operator"
13670                  [(reg FLAGS_REG) (const_int 0)])
13671             (const_int 0)))]
13672   ""
13673   [(set (match_dup 0) (match_dup 1))]
13674 {
13675   PUT_MODE (operands[1], QImode);
13676 })
13677
13678 (define_split
13679   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13680         (ne:QI (match_operator 1 "ix86_comparison_operator"
13681                  [(reg FLAGS_REG) (const_int 0)])
13682             (const_int 0)))]
13683   ""
13684   [(set (match_dup 0) (match_dup 1))]
13685 {
13686   PUT_MODE (operands[1], QImode);
13687 })
13688
13689 (define_split
13690   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13691         (eq:QI (match_operator 1 "ix86_comparison_operator"
13692                  [(reg FLAGS_REG) (const_int 0)])
13693             (const_int 0)))]
13694   ""
13695   [(set (match_dup 0) (match_dup 1))]
13696 {
13697   rtx new_op1 = copy_rtx (operands[1]);
13698   operands[1] = new_op1;
13699   PUT_MODE (new_op1, QImode);
13700   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13701                                              GET_MODE (XEXP (new_op1, 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_op1, VOIDmode))
13706     FAIL;
13707 })
13708
13709 (define_split
13710   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13711         (eq:QI (match_operator 1 "ix86_comparison_operator"
13712                  [(reg FLAGS_REG) (const_int 0)])
13713             (const_int 0)))]
13714   ""
13715   [(set (match_dup 0) (match_dup 1))]
13716 {
13717   rtx new_op1 = copy_rtx (operands[1]);
13718   operands[1] = new_op1;
13719   PUT_MODE (new_op1, QImode);
13720   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13721                                              GET_MODE (XEXP (new_op1, 0))));
13722
13723   /* Make sure that (a) the CCmode we have for the flags is strong
13724      enough for the reversed compare or (b) we have a valid FP compare.  */
13725   if (! ix86_comparison_operator (new_op1, VOIDmode))
13726     FAIL;
13727 })
13728
13729 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13730 ;; subsequent logical operations are used to imitate conditional moves.
13731 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13732 ;; it directly.
13733
13734 (define_insn "*sse_setccsf"
13735   [(set (match_operand:SF 0 "register_operand" "=x")
13736         (match_operator:SF 1 "sse_comparison_operator"
13737           [(match_operand:SF 2 "register_operand" "0")
13738            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13739   "TARGET_SSE"
13740   "cmp%D1ss\t{%3, %0|%0, %3}"
13741   [(set_attr "type" "ssecmp")
13742    (set_attr "mode" "SF")])
13743
13744 (define_insn "*sse_setccdf"
13745   [(set (match_operand:DF 0 "register_operand" "=x")
13746         (match_operator:DF 1 "sse_comparison_operator"
13747           [(match_operand:DF 2 "register_operand" "0")
13748            (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13749   "TARGET_SSE2"
13750   "cmp%D1sd\t{%3, %0|%0, %3}"
13751   [(set_attr "type" "ssecmp")
13752    (set_attr "mode" "DF")])
13753 \f
13754 ;; Basic conditional jump instructions.
13755 ;; We ignore the overflow flag for signed branch instructions.
13756
13757 ;; For all bCOND expanders, also expand the compare or test insn that
13758 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13759
13760 (define_expand "beq"
13761   [(set (pc)
13762         (if_then_else (match_dup 1)
13763                       (label_ref (match_operand 0 "" ""))
13764                       (pc)))]
13765   ""
13766   "ix86_expand_branch (EQ, operands[0]); DONE;")
13767
13768 (define_expand "bne"
13769   [(set (pc)
13770         (if_then_else (match_dup 1)
13771                       (label_ref (match_operand 0 "" ""))
13772                       (pc)))]
13773   ""
13774   "ix86_expand_branch (NE, operands[0]); DONE;")
13775
13776 (define_expand "bgt"
13777   [(set (pc)
13778         (if_then_else (match_dup 1)
13779                       (label_ref (match_operand 0 "" ""))
13780                       (pc)))]
13781   ""
13782   "ix86_expand_branch (GT, operands[0]); DONE;")
13783
13784 (define_expand "bgtu"
13785   [(set (pc)
13786         (if_then_else (match_dup 1)
13787                       (label_ref (match_operand 0 "" ""))
13788                       (pc)))]
13789   ""
13790   "ix86_expand_branch (GTU, operands[0]); DONE;")
13791
13792 (define_expand "blt"
13793   [(set (pc)
13794         (if_then_else (match_dup 1)
13795                       (label_ref (match_operand 0 "" ""))
13796                       (pc)))]
13797   ""
13798   "ix86_expand_branch (LT, operands[0]); DONE;")
13799
13800 (define_expand "bltu"
13801   [(set (pc)
13802         (if_then_else (match_dup 1)
13803                       (label_ref (match_operand 0 "" ""))
13804                       (pc)))]
13805   ""
13806   "ix86_expand_branch (LTU, operands[0]); DONE;")
13807
13808 (define_expand "bge"
13809   [(set (pc)
13810         (if_then_else (match_dup 1)
13811                       (label_ref (match_operand 0 "" ""))
13812                       (pc)))]
13813   ""
13814   "ix86_expand_branch (GE, operands[0]); DONE;")
13815
13816 (define_expand "bgeu"
13817   [(set (pc)
13818         (if_then_else (match_dup 1)
13819                       (label_ref (match_operand 0 "" ""))
13820                       (pc)))]
13821   ""
13822   "ix86_expand_branch (GEU, operands[0]); DONE;")
13823
13824 (define_expand "ble"
13825   [(set (pc)
13826         (if_then_else (match_dup 1)
13827                       (label_ref (match_operand 0 "" ""))
13828                       (pc)))]
13829   ""
13830   "ix86_expand_branch (LE, operands[0]); DONE;")
13831
13832 (define_expand "bleu"
13833   [(set (pc)
13834         (if_then_else (match_dup 1)
13835                       (label_ref (match_operand 0 "" ""))
13836                       (pc)))]
13837   ""
13838   "ix86_expand_branch (LEU, operands[0]); DONE;")
13839
13840 (define_expand "bunordered"
13841   [(set (pc)
13842         (if_then_else (match_dup 1)
13843                       (label_ref (match_operand 0 "" ""))
13844                       (pc)))]
13845   "TARGET_80387 || TARGET_SSE_MATH"
13846   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13847
13848 (define_expand "bordered"
13849   [(set (pc)
13850         (if_then_else (match_dup 1)
13851                       (label_ref (match_operand 0 "" ""))
13852                       (pc)))]
13853   "TARGET_80387 || TARGET_SSE_MATH"
13854   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13855
13856 (define_expand "buneq"
13857   [(set (pc)
13858         (if_then_else (match_dup 1)
13859                       (label_ref (match_operand 0 "" ""))
13860                       (pc)))]
13861   "TARGET_80387 || TARGET_SSE_MATH"
13862   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13863
13864 (define_expand "bunge"
13865   [(set (pc)
13866         (if_then_else (match_dup 1)
13867                       (label_ref (match_operand 0 "" ""))
13868                       (pc)))]
13869   "TARGET_80387 || TARGET_SSE_MATH"
13870   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13871
13872 (define_expand "bungt"
13873   [(set (pc)
13874         (if_then_else (match_dup 1)
13875                       (label_ref (match_operand 0 "" ""))
13876                       (pc)))]
13877   "TARGET_80387 || TARGET_SSE_MATH"
13878   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13879
13880 (define_expand "bunle"
13881   [(set (pc)
13882         (if_then_else (match_dup 1)
13883                       (label_ref (match_operand 0 "" ""))
13884                       (pc)))]
13885   "TARGET_80387 || TARGET_SSE_MATH"
13886   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13887
13888 (define_expand "bunlt"
13889   [(set (pc)
13890         (if_then_else (match_dup 1)
13891                       (label_ref (match_operand 0 "" ""))
13892                       (pc)))]
13893   "TARGET_80387 || TARGET_SSE_MATH"
13894   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13895
13896 (define_expand "bltgt"
13897   [(set (pc)
13898         (if_then_else (match_dup 1)
13899                       (label_ref (match_operand 0 "" ""))
13900                       (pc)))]
13901   "TARGET_80387 || TARGET_SSE_MATH"
13902   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13903
13904 (define_insn "*jcc_1"
13905   [(set (pc)
13906         (if_then_else (match_operator 1 "ix86_comparison_operator"
13907                                       [(reg FLAGS_REG) (const_int 0)])
13908                       (label_ref (match_operand 0 "" ""))
13909                       (pc)))]
13910   ""
13911   "%+j%C1\t%l0"
13912   [(set_attr "type" "ibr")
13913    (set_attr "modrm" "0")
13914    (set (attr "length")
13915            (if_then_else (and (ge (minus (match_dup 0) (pc))
13916                                   (const_int -126))
13917                               (lt (minus (match_dup 0) (pc))
13918                                   (const_int 128)))
13919              (const_int 2)
13920              (const_int 6)))])
13921
13922 (define_insn "*jcc_2"
13923   [(set (pc)
13924         (if_then_else (match_operator 1 "ix86_comparison_operator"
13925                                       [(reg FLAGS_REG) (const_int 0)])
13926                       (pc)
13927                       (label_ref (match_operand 0 "" ""))))]
13928   ""
13929   "%+j%c1\t%l0"
13930   [(set_attr "type" "ibr")
13931    (set_attr "modrm" "0")
13932    (set (attr "length")
13933            (if_then_else (and (ge (minus (match_dup 0) (pc))
13934                                   (const_int -126))
13935                               (lt (minus (match_dup 0) (pc))
13936                                   (const_int 128)))
13937              (const_int 2)
13938              (const_int 6)))])
13939
13940 ;; In general it is not safe to assume too much about CCmode registers,
13941 ;; so simplify-rtx stops when it sees a second one.  Under certain
13942 ;; conditions this is safe on x86, so help combine not create
13943 ;;
13944 ;;      seta    %al
13945 ;;      testb   %al, %al
13946 ;;      je      Lfoo
13947
13948 (define_split
13949   [(set (pc)
13950         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13951                                       [(reg FLAGS_REG) (const_int 0)])
13952                           (const_int 0))
13953                       (label_ref (match_operand 1 "" ""))
13954                       (pc)))]
13955   ""
13956   [(set (pc)
13957         (if_then_else (match_dup 0)
13958                       (label_ref (match_dup 1))
13959                       (pc)))]
13960 {
13961   PUT_MODE (operands[0], VOIDmode);
13962 })
13963
13964 (define_split
13965   [(set (pc)
13966         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13967                                       [(reg FLAGS_REG) (const_int 0)])
13968                           (const_int 0))
13969                       (label_ref (match_operand 1 "" ""))
13970                       (pc)))]
13971   ""
13972   [(set (pc)
13973         (if_then_else (match_dup 0)
13974                       (label_ref (match_dup 1))
13975                       (pc)))]
13976 {
13977   rtx new_op0 = copy_rtx (operands[0]);
13978   operands[0] = new_op0;
13979   PUT_MODE (new_op0, VOIDmode);
13980   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13981                                              GET_MODE (XEXP (new_op0, 0))));
13982
13983   /* Make sure that (a) the CCmode we have for the flags is strong
13984      enough for the reversed compare or (b) we have a valid FP compare.  */
13985   if (! ix86_comparison_operator (new_op0, VOIDmode))
13986     FAIL;
13987 })
13988
13989 ;; Define combination compare-and-branch fp compare instructions to use
13990 ;; during early optimization.  Splitting the operation apart early makes
13991 ;; for bad code when we want to reverse the operation.
13992
13993 (define_insn "*fp_jcc_1_mixed"
13994   [(set (pc)
13995         (if_then_else (match_operator 0 "comparison_operator"
13996                         [(match_operand 1 "register_operand" "f,x")
13997                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13998           (label_ref (match_operand 3 "" ""))
13999           (pc)))
14000    (clobber (reg:CCFP FPSR_REG))
14001    (clobber (reg:CCFP FLAGS_REG))]
14002   "TARGET_MIX_SSE_I387
14003    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14004    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14005    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14006   "#")
14007
14008 (define_insn "*fp_jcc_1_sse"
14009   [(set (pc)
14010         (if_then_else (match_operator 0 "comparison_operator"
14011                         [(match_operand 1 "register_operand" "x")
14012                          (match_operand 2 "nonimmediate_operand" "xm")])
14013           (label_ref (match_operand 3 "" ""))
14014           (pc)))
14015    (clobber (reg:CCFP FPSR_REG))
14016    (clobber (reg:CCFP FLAGS_REG))]
14017   "TARGET_SSE_MATH
14018    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14019    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14020    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14021   "#")
14022
14023 (define_insn "*fp_jcc_1_387"
14024   [(set (pc)
14025         (if_then_else (match_operator 0 "comparison_operator"
14026                         [(match_operand 1 "register_operand" "f")
14027                          (match_operand 2 "register_operand" "f")])
14028           (label_ref (match_operand 3 "" ""))
14029           (pc)))
14030    (clobber (reg:CCFP FPSR_REG))
14031    (clobber (reg:CCFP FLAGS_REG))]
14032   "TARGET_CMOVE && TARGET_80387
14033    && FLOAT_MODE_P (GET_MODE (operands[1]))
14034    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14035    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14036   "#")
14037
14038 (define_insn "*fp_jcc_2_mixed"
14039   [(set (pc)
14040         (if_then_else (match_operator 0 "comparison_operator"
14041                         [(match_operand 1 "register_operand" "f,x")
14042                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14043           (pc)
14044           (label_ref (match_operand 3 "" ""))))
14045    (clobber (reg:CCFP FPSR_REG))
14046    (clobber (reg:CCFP FLAGS_REG))]
14047   "TARGET_MIX_SSE_I387
14048    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14049    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14050    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14051   "#")
14052
14053 (define_insn "*fp_jcc_2_sse"
14054   [(set (pc)
14055         (if_then_else (match_operator 0 "comparison_operator"
14056                         [(match_operand 1 "register_operand" "x")
14057                          (match_operand 2 "nonimmediate_operand" "xm")])
14058           (pc)
14059           (label_ref (match_operand 3 "" ""))))
14060    (clobber (reg:CCFP FPSR_REG))
14061    (clobber (reg:CCFP FLAGS_REG))]
14062   "TARGET_SSE_MATH
14063    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14064    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14065    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14066   "#")
14067
14068 (define_insn "*fp_jcc_2_387"
14069   [(set (pc)
14070         (if_then_else (match_operator 0 "comparison_operator"
14071                         [(match_operand 1 "register_operand" "f")
14072                          (match_operand 2 "register_operand" "f")])
14073           (pc)
14074           (label_ref (match_operand 3 "" ""))))
14075    (clobber (reg:CCFP FPSR_REG))
14076    (clobber (reg:CCFP FLAGS_REG))]
14077   "TARGET_CMOVE && TARGET_80387
14078    && FLOAT_MODE_P (GET_MODE (operands[1]))
14079    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14080    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14081   "#")
14082
14083 (define_insn "*fp_jcc_3_387"
14084   [(set (pc)
14085         (if_then_else (match_operator 0 "comparison_operator"
14086                         [(match_operand 1 "register_operand" "f")
14087                          (match_operand 2 "nonimmediate_operand" "fm")])
14088           (label_ref (match_operand 3 "" ""))
14089           (pc)))
14090    (clobber (reg:CCFP FPSR_REG))
14091    (clobber (reg:CCFP FLAGS_REG))
14092    (clobber (match_scratch:HI 4 "=a"))]
14093   "TARGET_80387
14094    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14095    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14096    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14097    && SELECT_CC_MODE (GET_CODE (operands[0]),
14098                       operands[1], operands[2]) == CCFPmode
14099    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14100   "#")
14101
14102 (define_insn "*fp_jcc_4_387"
14103   [(set (pc)
14104         (if_then_else (match_operator 0 "comparison_operator"
14105                         [(match_operand 1 "register_operand" "f")
14106                          (match_operand 2 "nonimmediate_operand" "fm")])
14107           (pc)
14108           (label_ref (match_operand 3 "" ""))))
14109    (clobber (reg:CCFP FPSR_REG))
14110    (clobber (reg:CCFP FLAGS_REG))
14111    (clobber (match_scratch:HI 4 "=a"))]
14112   "TARGET_80387
14113    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14114    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14115    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14116    && SELECT_CC_MODE (GET_CODE (operands[0]),
14117                       operands[1], operands[2]) == CCFPmode
14118    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14119   "#")
14120
14121 (define_insn "*fp_jcc_5_387"
14122   [(set (pc)
14123         (if_then_else (match_operator 0 "comparison_operator"
14124                         [(match_operand 1 "register_operand" "f")
14125                          (match_operand 2 "register_operand" "f")])
14126           (label_ref (match_operand 3 "" ""))
14127           (pc)))
14128    (clobber (reg:CCFP FPSR_REG))
14129    (clobber (reg:CCFP FLAGS_REG))
14130    (clobber (match_scratch:HI 4 "=a"))]
14131   "TARGET_80387
14132    && FLOAT_MODE_P (GET_MODE (operands[1]))
14133    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14134    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14135   "#")
14136
14137 (define_insn "*fp_jcc_6_387"
14138   [(set (pc)
14139         (if_then_else (match_operator 0 "comparison_operator"
14140                         [(match_operand 1 "register_operand" "f")
14141                          (match_operand 2 "register_operand" "f")])
14142           (pc)
14143           (label_ref (match_operand 3 "" ""))))
14144    (clobber (reg:CCFP FPSR_REG))
14145    (clobber (reg:CCFP FLAGS_REG))
14146    (clobber (match_scratch:HI 4 "=a"))]
14147   "TARGET_80387
14148    && FLOAT_MODE_P (GET_MODE (operands[1]))
14149    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14150    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14151   "#")
14152
14153 (define_insn "*fp_jcc_7_387"
14154   [(set (pc)
14155         (if_then_else (match_operator 0 "comparison_operator"
14156                         [(match_operand 1 "register_operand" "f")
14157                          (match_operand 2 "const0_operand" "X")])
14158           (label_ref (match_operand 3 "" ""))
14159           (pc)))
14160    (clobber (reg:CCFP FPSR_REG))
14161    (clobber (reg:CCFP FLAGS_REG))
14162    (clobber (match_scratch:HI 4 "=a"))]
14163   "TARGET_80387
14164    && FLOAT_MODE_P (GET_MODE (operands[1]))
14165    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14166    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14167    && SELECT_CC_MODE (GET_CODE (operands[0]),
14168                       operands[1], operands[2]) == CCFPmode
14169    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14170   "#")
14171
14172 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14173 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14174 ;; with a precedence over other operators and is always put in the first
14175 ;; place. Swap condition and operands to match ficom instruction.
14176
14177 (define_insn "*fp_jcc_8<mode>_387"
14178   [(set (pc)
14179         (if_then_else (match_operator 0 "comparison_operator"
14180                         [(match_operator 1 "float_operator"
14181                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14182                            (match_operand 3 "register_operand" "f,f")])
14183           (label_ref (match_operand 4 "" ""))
14184           (pc)))
14185    (clobber (reg:CCFP FPSR_REG))
14186    (clobber (reg:CCFP FLAGS_REG))
14187    (clobber (match_scratch:HI 5 "=a,a"))]
14188   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14189    && FLOAT_MODE_P (GET_MODE (operands[3]))
14190    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14191    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14192    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14193    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14194   "#")
14195
14196 (define_split
14197   [(set (pc)
14198         (if_then_else (match_operator 0 "comparison_operator"
14199                         [(match_operand 1 "register_operand" "")
14200                          (match_operand 2 "nonimmediate_operand" "")])
14201           (match_operand 3 "" "")
14202           (match_operand 4 "" "")))
14203    (clobber (reg:CCFP FPSR_REG))
14204    (clobber (reg:CCFP FLAGS_REG))]
14205   "reload_completed"
14206   [(const_int 0)]
14207 {
14208   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14209                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14210   DONE;
14211 })
14212
14213 (define_split
14214   [(set (pc)
14215         (if_then_else (match_operator 0 "comparison_operator"
14216                         [(match_operand 1 "register_operand" "")
14217                          (match_operand 2 "general_operand" "")])
14218           (match_operand 3 "" "")
14219           (match_operand 4 "" "")))
14220    (clobber (reg:CCFP FPSR_REG))
14221    (clobber (reg:CCFP FLAGS_REG))
14222    (clobber (match_scratch:HI 5 "=a"))]
14223   "reload_completed"
14224   [(const_int 0)]
14225 {
14226   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14227                         operands[3], operands[4], operands[5], NULL_RTX);
14228   DONE;
14229 })
14230
14231 (define_split
14232   [(set (pc)
14233         (if_then_else (match_operator 0 "comparison_operator"
14234                         [(match_operator 1 "float_operator"
14235                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14236                            (match_operand 3 "register_operand" "")])
14237           (match_operand 4 "" "")
14238           (match_operand 5 "" "")))
14239    (clobber (reg:CCFP FPSR_REG))
14240    (clobber (reg:CCFP FLAGS_REG))
14241    (clobber (match_scratch:HI 6 "=a"))]
14242   "reload_completed"
14243   [(const_int 0)]
14244 {
14245   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14246   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14247                         operands[3], operands[7],
14248                         operands[4], operands[5], operands[6], NULL_RTX);
14249   DONE;
14250 })
14251
14252 ;; %%% Kill this when reload knows how to do it.
14253 (define_split
14254   [(set (pc)
14255         (if_then_else (match_operator 0 "comparison_operator"
14256                         [(match_operator 1 "float_operator"
14257                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14258                            (match_operand 3 "register_operand" "")])
14259           (match_operand 4 "" "")
14260           (match_operand 5 "" "")))
14261    (clobber (reg:CCFP FPSR_REG))
14262    (clobber (reg:CCFP FLAGS_REG))
14263    (clobber (match_scratch:HI 6 "=a"))]
14264   "reload_completed"
14265   [(const_int 0)]
14266 {
14267   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14268   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14269   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14270                         operands[3], operands[7],
14271                         operands[4], operands[5], operands[6], operands[2]);
14272   DONE;
14273 })
14274 \f
14275 ;; Unconditional and other jump instructions
14276
14277 (define_insn "jump"
14278   [(set (pc)
14279         (label_ref (match_operand 0 "" "")))]
14280   ""
14281   "jmp\t%l0"
14282   [(set_attr "type" "ibr")
14283    (set (attr "length")
14284            (if_then_else (and (ge (minus (match_dup 0) (pc))
14285                                   (const_int -126))
14286                               (lt (minus (match_dup 0) (pc))
14287                                   (const_int 128)))
14288              (const_int 2)
14289              (const_int 5)))
14290    (set_attr "modrm" "0")])
14291
14292 (define_expand "indirect_jump"
14293   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14294   ""
14295   "")
14296
14297 (define_insn "*indirect_jump"
14298   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14299   "!TARGET_64BIT"
14300   "jmp\t%A0"
14301   [(set_attr "type" "ibr")
14302    (set_attr "length_immediate" "0")])
14303
14304 (define_insn "*indirect_jump_rtx64"
14305   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14306   "TARGET_64BIT"
14307   "jmp\t%A0"
14308   [(set_attr "type" "ibr")
14309    (set_attr "length_immediate" "0")])
14310
14311 (define_expand "tablejump"
14312   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14313               (use (label_ref (match_operand 1 "" "")))])]
14314   ""
14315 {
14316   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14317      relative.  Convert the relative address to an absolute address.  */
14318   if (flag_pic)
14319     {
14320       rtx op0, op1;
14321       enum rtx_code code;
14322
14323       /* We can't use @GOTOFF for text labels on VxWorks;
14324          see gotoff_operand.  */
14325       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14326         {
14327           code = PLUS;
14328           op0 = operands[0];
14329           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14330         }
14331       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14332         {
14333           code = PLUS;
14334           op0 = operands[0];
14335           op1 = pic_offset_table_rtx;
14336         }
14337       else
14338         {
14339           code = MINUS;
14340           op0 = pic_offset_table_rtx;
14341           op1 = operands[0];
14342         }
14343
14344       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14345                                          OPTAB_DIRECT);
14346     }
14347 })
14348
14349 (define_insn "*tablejump_1"
14350   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14351    (use (label_ref (match_operand 1 "" "")))]
14352   "!TARGET_64BIT"
14353   "jmp\t%A0"
14354   [(set_attr "type" "ibr")
14355    (set_attr "length_immediate" "0")])
14356
14357 (define_insn "*tablejump_1_rtx64"
14358   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14359    (use (label_ref (match_operand 1 "" "")))]
14360   "TARGET_64BIT"
14361   "jmp\t%A0"
14362   [(set_attr "type" "ibr")
14363    (set_attr "length_immediate" "0")])
14364 \f
14365 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14366
14367 (define_peephole2
14368   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14369    (set (match_operand:QI 1 "register_operand" "")
14370         (match_operator:QI 2 "ix86_comparison_operator"
14371           [(reg FLAGS_REG) (const_int 0)]))
14372    (set (match_operand 3 "q_regs_operand" "")
14373         (zero_extend (match_dup 1)))]
14374   "(peep2_reg_dead_p (3, operands[1])
14375     || operands_match_p (operands[1], operands[3]))
14376    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14377   [(set (match_dup 4) (match_dup 0))
14378    (set (strict_low_part (match_dup 5))
14379         (match_dup 2))]
14380 {
14381   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14382   operands[5] = gen_lowpart (QImode, operands[3]);
14383   ix86_expand_clear (operands[3]);
14384 })
14385
14386 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14387
14388 (define_peephole2
14389   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14390    (set (match_operand:QI 1 "register_operand" "")
14391         (match_operator:QI 2 "ix86_comparison_operator"
14392           [(reg FLAGS_REG) (const_int 0)]))
14393    (parallel [(set (match_operand 3 "q_regs_operand" "")
14394                    (zero_extend (match_dup 1)))
14395               (clobber (reg:CC FLAGS_REG))])]
14396   "(peep2_reg_dead_p (3, operands[1])
14397     || operands_match_p (operands[1], operands[3]))
14398    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14399   [(set (match_dup 4) (match_dup 0))
14400    (set (strict_low_part (match_dup 5))
14401         (match_dup 2))]
14402 {
14403   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14404   operands[5] = gen_lowpart (QImode, operands[3]);
14405   ix86_expand_clear (operands[3]);
14406 })
14407 \f
14408 ;; Call instructions.
14409
14410 ;; The predicates normally associated with named expanders are not properly
14411 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14412 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14413
14414 ;; Call subroutine returning no value.
14415
14416 (define_expand "call_pop"
14417   [(parallel [(call (match_operand:QI 0 "" "")
14418                     (match_operand:SI 1 "" ""))
14419               (set (reg:SI SP_REG)
14420                    (plus:SI (reg:SI SP_REG)
14421                             (match_operand:SI 3 "" "")))])]
14422   "!TARGET_64BIT"
14423 {
14424   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14425   DONE;
14426 })
14427
14428 (define_insn "*call_pop_0"
14429   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14430          (match_operand:SI 1 "" ""))
14431    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14432                             (match_operand:SI 2 "immediate_operand" "")))]
14433   "!TARGET_64BIT"
14434 {
14435   if (SIBLING_CALL_P (insn))
14436     return "jmp\t%P0";
14437   else
14438     return "call\t%P0";
14439 }
14440   [(set_attr "type" "call")])
14441
14442 (define_insn "*call_pop_1"
14443   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14444          (match_operand:SI 1 "" ""))
14445    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14446                             (match_operand:SI 2 "immediate_operand" "i")))]
14447   "!TARGET_64BIT"
14448 {
14449   if (constant_call_address_operand (operands[0], Pmode))
14450     {
14451       if (SIBLING_CALL_P (insn))
14452         return "jmp\t%P0";
14453       else
14454         return "call\t%P0";
14455     }
14456   if (SIBLING_CALL_P (insn))
14457     return "jmp\t%A0";
14458   else
14459     return "call\t%A0";
14460 }
14461   [(set_attr "type" "call")])
14462
14463 (define_expand "call"
14464   [(call (match_operand:QI 0 "" "")
14465          (match_operand 1 "" ""))
14466    (use (match_operand 2 "" ""))]
14467   ""
14468 {
14469   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14470   DONE;
14471 })
14472
14473 (define_expand "sibcall"
14474   [(call (match_operand:QI 0 "" "")
14475          (match_operand 1 "" ""))
14476    (use (match_operand 2 "" ""))]
14477   ""
14478 {
14479   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14480   DONE;
14481 })
14482
14483 (define_insn "*call_0"
14484   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14485          (match_operand 1 "" ""))]
14486   ""
14487 {
14488   if (SIBLING_CALL_P (insn))
14489     return "jmp\t%P0";
14490   else
14491     return "call\t%P0";
14492 }
14493   [(set_attr "type" "call")])
14494
14495 (define_insn "*call_1"
14496   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14497          (match_operand 1 "" ""))]
14498   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14499 {
14500   if (constant_call_address_operand (operands[0], Pmode))
14501     return "call\t%P0";
14502   return "call\t%A0";
14503 }
14504   [(set_attr "type" "call")])
14505
14506 (define_insn "*sibcall_1"
14507   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14508          (match_operand 1 "" ""))]
14509   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14510 {
14511   if (constant_call_address_operand (operands[0], Pmode))
14512     return "jmp\t%P0";
14513   return "jmp\t%A0";
14514 }
14515   [(set_attr "type" "call")])
14516
14517 (define_insn "*call_1_rex64"
14518   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14519          (match_operand 1 "" ""))]
14520   "!SIBLING_CALL_P (insn) && TARGET_64BIT
14521    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14522 {
14523   if (constant_call_address_operand (operands[0], Pmode))
14524     return "call\t%P0";
14525   return "call\t%A0";
14526 }
14527   [(set_attr "type" "call")])
14528
14529 (define_insn "*call_1_rex64_large"
14530   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14531          (match_operand 1 "" ""))]
14532   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14533   "call\t%A0"
14534   [(set_attr "type" "call")])
14535
14536 (define_insn "*sibcall_1_rex64"
14537   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14538          (match_operand 1 "" ""))]
14539   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14540   "jmp\t%P0"
14541   [(set_attr "type" "call")])
14542
14543 (define_insn "*sibcall_1_rex64_v"
14544   [(call (mem:QI (reg:DI R11_REG))
14545          (match_operand 0 "" ""))]
14546   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14547   "jmp\t*%%r11"
14548   [(set_attr "type" "call")])
14549
14550
14551 ;; Call subroutine, returning value in operand 0
14552
14553 (define_expand "call_value_pop"
14554   [(parallel [(set (match_operand 0 "" "")
14555                    (call (match_operand:QI 1 "" "")
14556                          (match_operand:SI 2 "" "")))
14557               (set (reg:SI SP_REG)
14558                    (plus:SI (reg:SI SP_REG)
14559                             (match_operand:SI 4 "" "")))])]
14560   "!TARGET_64BIT"
14561 {
14562   ix86_expand_call (operands[0], operands[1], operands[2],
14563                     operands[3], operands[4], 0);
14564   DONE;
14565 })
14566
14567 (define_expand "call_value"
14568   [(set (match_operand 0 "" "")
14569         (call (match_operand:QI 1 "" "")
14570               (match_operand:SI 2 "" "")))
14571    (use (match_operand:SI 3 "" ""))]
14572   ;; Operand 2 not used on the i386.
14573   ""
14574 {
14575   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14576   DONE;
14577 })
14578
14579 (define_expand "sibcall_value"
14580   [(set (match_operand 0 "" "")
14581         (call (match_operand:QI 1 "" "")
14582               (match_operand:SI 2 "" "")))
14583    (use (match_operand:SI 3 "" ""))]
14584   ;; Operand 2 not used on the i386.
14585   ""
14586 {
14587   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14588   DONE;
14589 })
14590
14591 ;; Call subroutine returning any type.
14592
14593 (define_expand "untyped_call"
14594   [(parallel [(call (match_operand 0 "" "")
14595                     (const_int 0))
14596               (match_operand 1 "" "")
14597               (match_operand 2 "" "")])]
14598   ""
14599 {
14600   int i;
14601
14602   /* In order to give reg-stack an easier job in validating two
14603      coprocessor registers as containing a possible return value,
14604      simply pretend the untyped call returns a complex long double
14605      value.  */
14606
14607   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14608                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14609                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14610                     NULL, 0);
14611
14612   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14613     {
14614       rtx set = XVECEXP (operands[2], 0, i);
14615       emit_move_insn (SET_DEST (set), SET_SRC (set));
14616     }
14617
14618   /* The optimizer does not know that the call sets the function value
14619      registers we stored in the result block.  We avoid problems by
14620      claiming that all hard registers are used and clobbered at this
14621      point.  */
14622   emit_insn (gen_blockage (const0_rtx));
14623
14624   DONE;
14625 })
14626 \f
14627 ;; Prologue and epilogue instructions
14628
14629 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14630 ;; all of memory.  This blocks insns from being moved across this point.
14631
14632 (define_insn "blockage"
14633   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14634   ""
14635   ""
14636   [(set_attr "length" "0")])
14637
14638 ;; Insn emitted into the body of a function to return from a function.
14639 ;; This is only done if the function's epilogue is known to be simple.
14640 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14641
14642 (define_expand "return"
14643   [(return)]
14644   "ix86_can_use_return_insn_p ()"
14645 {
14646   if (current_function_pops_args)
14647     {
14648       rtx popc = GEN_INT (current_function_pops_args);
14649       emit_jump_insn (gen_return_pop_internal (popc));
14650       DONE;
14651     }
14652 })
14653
14654 (define_insn "return_internal"
14655   [(return)]
14656   "reload_completed"
14657   "ret"
14658   [(set_attr "length" "1")
14659    (set_attr "length_immediate" "0")
14660    (set_attr "modrm" "0")])
14661
14662 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14663 ;; instruction Athlon and K8 have.
14664
14665 (define_insn "return_internal_long"
14666   [(return)
14667    (unspec [(const_int 0)] UNSPEC_REP)]
14668   "reload_completed"
14669   "rep {;} ret"
14670   [(set_attr "length" "1")
14671    (set_attr "length_immediate" "0")
14672    (set_attr "prefix_rep" "1")
14673    (set_attr "modrm" "0")])
14674
14675 (define_insn "return_pop_internal"
14676   [(return)
14677    (use (match_operand:SI 0 "const_int_operand" ""))]
14678   "reload_completed"
14679   "ret\t%0"
14680   [(set_attr "length" "3")
14681    (set_attr "length_immediate" "2")
14682    (set_attr "modrm" "0")])
14683
14684 (define_insn "return_indirect_internal"
14685   [(return)
14686    (use (match_operand:SI 0 "register_operand" "r"))]
14687   "reload_completed"
14688   "jmp\t%A0"
14689   [(set_attr "type" "ibr")
14690    (set_attr "length_immediate" "0")])
14691
14692 (define_insn "nop"
14693   [(const_int 0)]
14694   ""
14695   "nop"
14696   [(set_attr "length" "1")
14697    (set_attr "length_immediate" "0")
14698    (set_attr "modrm" "0")])
14699
14700 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14701 ;; branch prediction penalty for the third jump in a 16-byte
14702 ;; block on K8.
14703
14704 (define_insn "align"
14705   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14706   ""
14707 {
14708 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14709   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14710 #else
14711   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14712      The align insn is used to avoid 3 jump instructions in the row to improve
14713      branch prediction and the benefits hardly outweigh the cost of extra 8
14714      nops on the average inserted by full alignment pseudo operation.  */
14715 #endif
14716   return "";
14717 }
14718   [(set_attr "length" "16")])
14719
14720 (define_expand "prologue"
14721   [(const_int 1)]
14722   ""
14723   "ix86_expand_prologue (); DONE;")
14724
14725 (define_insn "set_got"
14726   [(set (match_operand:SI 0 "register_operand" "=r")
14727         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14728    (clobber (reg:CC FLAGS_REG))]
14729   "!TARGET_64BIT"
14730   { return output_set_got (operands[0], NULL_RTX); }
14731   [(set_attr "type" "multi")
14732    (set_attr "length" "12")])
14733
14734 (define_insn "set_got_labelled"
14735   [(set (match_operand:SI 0 "register_operand" "=r")
14736         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14737          UNSPEC_SET_GOT))
14738    (clobber (reg:CC FLAGS_REG))]
14739   "!TARGET_64BIT"
14740   { return output_set_got (operands[0], operands[1]); }
14741   [(set_attr "type" "multi")
14742    (set_attr "length" "12")])
14743
14744 (define_insn "set_got_rex64"
14745   [(set (match_operand:DI 0 "register_operand" "=r")
14746         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14747   "TARGET_64BIT"
14748   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14749   [(set_attr "type" "lea")
14750    (set_attr "length" "6")])
14751
14752 (define_insn "set_rip_rex64"
14753   [(set (match_operand:DI 0 "register_operand" "=r")
14754         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14755   "TARGET_64BIT"
14756   "lea{q}\t%l1(%%rip), %0"
14757   [(set_attr "type" "lea")
14758    (set_attr "length" "6")])
14759
14760 (define_insn "set_got_offset_rex64"
14761   [(set (match_operand:DI 0 "register_operand" "=r")
14762         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
14763   "TARGET_64BIT"
14764   "movabs{q}\t$_GLOBAL_OFFSET_TABLE_-%l1, %0"
14765   [(set_attr "type" "imov")
14766    (set_attr "length" "11")])
14767
14768 (define_expand "epilogue"
14769   [(const_int 1)]
14770   ""
14771   "ix86_expand_epilogue (1); DONE;")
14772
14773 (define_expand "sibcall_epilogue"
14774   [(const_int 1)]
14775   ""
14776   "ix86_expand_epilogue (0); DONE;")
14777
14778 (define_expand "eh_return"
14779   [(use (match_operand 0 "register_operand" ""))]
14780   ""
14781 {
14782   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14783
14784   /* Tricky bit: we write the address of the handler to which we will
14785      be returning into someone else's stack frame, one word below the
14786      stack address we wish to restore.  */
14787   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14788   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14789   tmp = gen_rtx_MEM (Pmode, tmp);
14790   emit_move_insn (tmp, ra);
14791
14792   if (Pmode == SImode)
14793     emit_jump_insn (gen_eh_return_si (sa));
14794   else
14795     emit_jump_insn (gen_eh_return_di (sa));
14796   emit_barrier ();
14797   DONE;
14798 })
14799
14800 (define_insn_and_split "eh_return_si"
14801   [(set (pc)
14802         (unspec [(match_operand:SI 0 "register_operand" "c")]
14803                  UNSPEC_EH_RETURN))]
14804   "!TARGET_64BIT"
14805   "#"
14806   "reload_completed"
14807   [(const_int 1)]
14808   "ix86_expand_epilogue (2); DONE;")
14809
14810 (define_insn_and_split "eh_return_di"
14811   [(set (pc)
14812         (unspec [(match_operand:DI 0 "register_operand" "c")]
14813                  UNSPEC_EH_RETURN))]
14814   "TARGET_64BIT"
14815   "#"
14816   "reload_completed"
14817   [(const_int 1)]
14818   "ix86_expand_epilogue (2); DONE;")
14819
14820 (define_insn "leave"
14821   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14822    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14823    (clobber (mem:BLK (scratch)))]
14824   "!TARGET_64BIT"
14825   "leave"
14826   [(set_attr "type" "leave")])
14827
14828 (define_insn "leave_rex64"
14829   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14830    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14831    (clobber (mem:BLK (scratch)))]
14832   "TARGET_64BIT"
14833   "leave"
14834   [(set_attr "type" "leave")])
14835 \f
14836 (define_expand "ffssi2"
14837   [(parallel
14838      [(set (match_operand:SI 0 "register_operand" "")
14839            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14840       (clobber (match_scratch:SI 2 ""))
14841       (clobber (reg:CC FLAGS_REG))])]
14842   ""
14843   "")
14844
14845 (define_insn_and_split "*ffs_cmove"
14846   [(set (match_operand:SI 0 "register_operand" "=r")
14847         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14848    (clobber (match_scratch:SI 2 "=&r"))
14849    (clobber (reg:CC FLAGS_REG))]
14850   "TARGET_CMOVE"
14851   "#"
14852   "&& reload_completed"
14853   [(set (match_dup 2) (const_int -1))
14854    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14855               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14856    (set (match_dup 0) (if_then_else:SI
14857                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14858                         (match_dup 2)
14859                         (match_dup 0)))
14860    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14861               (clobber (reg:CC FLAGS_REG))])]
14862   "")
14863
14864 (define_insn_and_split "*ffs_no_cmove"
14865   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14866         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14867    (clobber (match_scratch:SI 2 "=&q"))
14868    (clobber (reg:CC FLAGS_REG))]
14869   ""
14870   "#"
14871   "reload_completed"
14872   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14873               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14874    (set (strict_low_part (match_dup 3))
14875         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14876    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14877               (clobber (reg:CC FLAGS_REG))])
14878    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14879               (clobber (reg:CC FLAGS_REG))])
14880    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14881               (clobber (reg:CC FLAGS_REG))])]
14882 {
14883   operands[3] = gen_lowpart (QImode, operands[2]);
14884   ix86_expand_clear (operands[2]);
14885 })
14886
14887 (define_insn "*ffssi_1"
14888   [(set (reg:CCZ FLAGS_REG)
14889         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14890                      (const_int 0)))
14891    (set (match_operand:SI 0 "register_operand" "=r")
14892         (ctz:SI (match_dup 1)))]
14893   ""
14894   "bsf{l}\t{%1, %0|%0, %1}"
14895   [(set_attr "prefix_0f" "1")])
14896
14897 (define_expand "ffsdi2"
14898   [(parallel
14899      [(set (match_operand:DI 0 "register_operand" "")
14900            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14901       (clobber (match_scratch:DI 2 ""))
14902       (clobber (reg:CC FLAGS_REG))])]
14903   "TARGET_64BIT && TARGET_CMOVE"
14904   "")
14905
14906 (define_insn_and_split "*ffs_rex64"
14907   [(set (match_operand:DI 0 "register_operand" "=r")
14908         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14909    (clobber (match_scratch:DI 2 "=&r"))
14910    (clobber (reg:CC FLAGS_REG))]
14911   "TARGET_64BIT && TARGET_CMOVE"
14912   "#"
14913   "&& reload_completed"
14914   [(set (match_dup 2) (const_int -1))
14915    (parallel [(set (reg:CCZ FLAGS_REG)
14916                    (compare:CCZ (match_dup 1) (const_int 0)))
14917               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14918    (set (match_dup 0) (if_then_else:DI
14919                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14920                         (match_dup 2)
14921                         (match_dup 0)))
14922    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14923               (clobber (reg:CC FLAGS_REG))])]
14924   "")
14925
14926 (define_insn "*ffsdi_1"
14927   [(set (reg:CCZ FLAGS_REG)
14928         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14929                      (const_int 0)))
14930    (set (match_operand:DI 0 "register_operand" "=r")
14931         (ctz:DI (match_dup 1)))]
14932   "TARGET_64BIT"
14933   "bsf{q}\t{%1, %0|%0, %1}"
14934   [(set_attr "prefix_0f" "1")])
14935
14936 (define_insn "ctzsi2"
14937   [(set (match_operand:SI 0 "register_operand" "=r")
14938         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14939    (clobber (reg:CC FLAGS_REG))]
14940   ""
14941   "bsf{l}\t{%1, %0|%0, %1}"
14942   [(set_attr "prefix_0f" "1")])
14943
14944 (define_insn "ctzdi2"
14945   [(set (match_operand:DI 0 "register_operand" "=r")
14946         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14947    (clobber (reg:CC FLAGS_REG))]
14948   "TARGET_64BIT"
14949   "bsf{q}\t{%1, %0|%0, %1}"
14950   [(set_attr "prefix_0f" "1")])
14951
14952 (define_expand "clzsi2"
14953   [(parallel
14954      [(set (match_operand:SI 0 "register_operand" "")
14955            (minus:SI (const_int 31)
14956                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14957       (clobber (reg:CC FLAGS_REG))])
14958    (parallel
14959      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14960       (clobber (reg:CC FLAGS_REG))])]
14961   ""
14962 {
14963   if (TARGET_ABM)
14964     {
14965       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14966       DONE;
14967     }
14968 })
14969
14970 (define_insn "clzsi2_abm"
14971   [(set (match_operand:SI 0 "register_operand" "=r")
14972         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14973    (clobber (reg:CC FLAGS_REG))]
14974   "TARGET_ABM"
14975   "lzcnt{l}\t{%1, %0|%0, %1}"
14976   [(set_attr "prefix_rep" "1")
14977    (set_attr "type" "bitmanip")
14978    (set_attr "mode" "SI")])
14979
14980 (define_insn "*bsr"
14981   [(set (match_operand:SI 0 "register_operand" "=r")
14982         (minus:SI (const_int 31)
14983                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14984    (clobber (reg:CC FLAGS_REG))]
14985   ""
14986   "bsr{l}\t{%1, %0|%0, %1}"
14987   [(set_attr "prefix_0f" "1")
14988    (set_attr "mode" "SI")])
14989
14990 (define_insn "popcountsi2"
14991   [(set (match_operand:SI 0 "register_operand" "=r")
14992         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14993    (clobber (reg:CC FLAGS_REG))]
14994   "TARGET_POPCNT"
14995   "popcnt{l}\t{%1, %0|%0, %1}"
14996   [(set_attr "prefix_rep" "1")
14997    (set_attr "type" "bitmanip")
14998    (set_attr "mode" "SI")])
14999
15000 (define_insn "*popcountsi2_cmp"
15001   [(set (reg FLAGS_REG)
15002         (compare
15003           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15004           (const_int 0)))
15005    (set (match_operand:SI 0 "register_operand" "=r")
15006         (popcount:SI (match_dup 1)))]
15007   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15008   "popcnt{l}\t{%1, %0|%0, %1}"
15009   [(set_attr "prefix_rep" "1")
15010    (set_attr "type" "bitmanip")
15011    (set_attr "mode" "SI")])
15012
15013 (define_insn "*popcountsi2_cmp_zext"
15014   [(set (reg FLAGS_REG)
15015         (compare
15016           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15017           (const_int 0)))
15018    (set (match_operand:DI 0 "register_operand" "=r")
15019         (zero_extend:DI(popcount:SI (match_dup 1))))]
15020   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15021   "popcnt{l}\t{%1, %0|%0, %1}"
15022   [(set_attr "prefix_rep" "1")
15023    (set_attr "type" "bitmanip")
15024    (set_attr "mode" "SI")])
15025
15026 (define_expand "bswapsi2"
15027   [(set (match_operand:SI 0 "register_operand" "")
15028         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15029   ""
15030 {
15031   if (!TARGET_BSWAP)
15032     {
15033       rtx x = operands[0];
15034
15035       emit_move_insn (x, operands[1]);
15036       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15037       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15038       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15039       DONE;
15040     }
15041 })
15042
15043 (define_insn "*bswapsi_1"
15044   [(set (match_operand:SI 0 "register_operand" "=r")
15045         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15046   "TARGET_BSWAP"
15047   "bswap\t%0"
15048   [(set_attr "prefix_0f" "1")
15049    (set_attr "length" "2")])
15050
15051 (define_insn "*bswaphi_lowpart_1"
15052   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15053         (bswap:HI (match_dup 0)))
15054    (clobber (reg:CC FLAGS_REG))]
15055   "TARGET_USE_XCHGB || optimize_size"
15056   "@
15057     xchg{b}\t{%h0, %b0|%b0, %h0}
15058     rol{w}\t{$8, %0|%0, 8}"
15059   [(set_attr "length" "2,4")
15060    (set_attr "mode" "QI,HI")])
15061
15062 (define_insn "bswaphi_lowpart"
15063   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15064         (bswap:HI (match_dup 0)))
15065    (clobber (reg:CC FLAGS_REG))]
15066   ""
15067   "rol{w}\t{$8, %0|%0, 8}"
15068   [(set_attr "length" "4")
15069    (set_attr "mode" "HI")])
15070
15071 (define_insn "bswapdi2"
15072   [(set (match_operand:DI 0 "register_operand" "=r")
15073         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15074   "TARGET_64BIT"
15075   "bswap\t%0"
15076   [(set_attr "prefix_0f" "1")
15077    (set_attr "length" "3")])
15078
15079 (define_expand "clzdi2"
15080   [(parallel
15081      [(set (match_operand:DI 0 "register_operand" "")
15082            (minus:DI (const_int 63)
15083                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15084       (clobber (reg:CC FLAGS_REG))])
15085    (parallel
15086      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15087       (clobber (reg:CC FLAGS_REG))])]
15088   "TARGET_64BIT"
15089 {
15090   if (TARGET_ABM)
15091     {
15092       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15093       DONE;
15094     }
15095 })
15096
15097 (define_insn "clzdi2_abm"
15098   [(set (match_operand:DI 0 "register_operand" "=r")
15099         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15100    (clobber (reg:CC FLAGS_REG))]
15101   "TARGET_64BIT && TARGET_ABM"
15102   "lzcnt{q}\t{%1, %0|%0, %1}"
15103   [(set_attr "prefix_rep" "1")
15104    (set_attr "type" "bitmanip")
15105    (set_attr "mode" "DI")])
15106
15107 (define_insn "*bsr_rex64"
15108   [(set (match_operand:DI 0 "register_operand" "=r")
15109         (minus:DI (const_int 63)
15110                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15111    (clobber (reg:CC FLAGS_REG))]
15112   "TARGET_64BIT"
15113   "bsr{q}\t{%1, %0|%0, %1}"
15114   [(set_attr "prefix_0f" "1")
15115    (set_attr "mode" "DI")])
15116
15117 (define_insn "popcountdi2"
15118   [(set (match_operand:DI 0 "register_operand" "=r")
15119         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15120    (clobber (reg:CC FLAGS_REG))]
15121   "TARGET_64BIT && TARGET_POPCNT"
15122   "popcnt{q}\t{%1, %0|%0, %1}"
15123   [(set_attr "prefix_rep" "1")
15124    (set_attr "type" "bitmanip")
15125    (set_attr "mode" "DI")])
15126
15127 (define_insn "*popcountdi2_cmp"
15128   [(set (reg FLAGS_REG)
15129         (compare
15130           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15131           (const_int 0)))
15132    (set (match_operand:DI 0 "register_operand" "=r")
15133         (popcount:DI (match_dup 1)))]
15134   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15135   "popcnt{q}\t{%1, %0|%0, %1}"
15136   [(set_attr "prefix_rep" "1")
15137    (set_attr "type" "bitmanip")
15138    (set_attr "mode" "DI")])
15139
15140 (define_expand "clzhi2"
15141   [(parallel
15142      [(set (match_operand:HI 0 "register_operand" "")
15143            (minus:HI (const_int 15)
15144                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15145       (clobber (reg:CC FLAGS_REG))])
15146    (parallel
15147      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15148       (clobber (reg:CC FLAGS_REG))])]
15149   ""
15150 {
15151   if (TARGET_ABM)
15152     {
15153       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15154       DONE;
15155     }
15156 })
15157
15158 (define_insn "clzhi2_abm"
15159   [(set (match_operand:HI 0 "register_operand" "=r")
15160         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15161    (clobber (reg:CC FLAGS_REG))]
15162   "TARGET_ABM"
15163   "lzcnt{w}\t{%1, %0|%0, %1}"
15164   [(set_attr "prefix_rep" "1")
15165    (set_attr "type" "bitmanip")
15166    (set_attr "mode" "HI")])
15167
15168 (define_insn "*bsrhi"
15169   [(set (match_operand:HI 0 "register_operand" "=r")
15170         (minus:HI (const_int 15)
15171                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15172    (clobber (reg:CC FLAGS_REG))]
15173   ""
15174   "bsr{w}\t{%1, %0|%0, %1}"
15175   [(set_attr "prefix_0f" "1")
15176    (set_attr "mode" "HI")])
15177
15178 (define_insn "popcounthi2"
15179   [(set (match_operand:HI 0 "register_operand" "=r")
15180         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15181    (clobber (reg:CC FLAGS_REG))]
15182   "TARGET_POPCNT"
15183   "popcnt{w}\t{%1, %0|%0, %1}"
15184   [(set_attr "prefix_rep" "1")
15185    (set_attr "type" "bitmanip")
15186    (set_attr "mode" "HI")])
15187
15188 (define_insn "*popcounthi2_cmp"
15189   [(set (reg FLAGS_REG)
15190         (compare
15191           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15192           (const_int 0)))
15193    (set (match_operand:HI 0 "register_operand" "=r")
15194         (popcount:HI (match_dup 1)))]
15195   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15196   "popcnt{w}\t{%1, %0|%0, %1}"
15197   [(set_attr "prefix_rep" "1")
15198    (set_attr "type" "bitmanip")
15199    (set_attr "mode" "HI")])
15200
15201 (define_expand "paritydi2"
15202   [(set (match_operand:DI 0 "register_operand" "")
15203         (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
15204   "! TARGET_POPCNT"
15205 {
15206   rtx scratch = gen_reg_rtx (QImode);
15207   rtx cond;
15208
15209   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15210                                 NULL_RTX, operands[1]));
15211
15212   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15213                          gen_rtx_REG (CCmode, FLAGS_REG),
15214                          const0_rtx);
15215   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15216
15217   if (TARGET_64BIT)
15218     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15219   else
15220     {
15221       rtx tmp = gen_reg_rtx (SImode);
15222
15223       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15224       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15225     }
15226   DONE;
15227 })
15228
15229 (define_insn_and_split "paritydi2_cmp"
15230   [(set (reg:CC FLAGS_REG)
15231         (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
15232    (clobber (match_scratch:DI 0 "=r,X"))
15233    (clobber (match_scratch:SI 1 "=r,r"))
15234    (clobber (match_scratch:HI 2 "=Q,Q"))]
15235   "! TARGET_POPCNT"
15236   "#"
15237   "&& reload_completed"
15238   [(parallel
15239      [(set (match_dup 1)
15240            (xor:SI (match_dup 1) (match_dup 4)))
15241       (clobber (reg:CC FLAGS_REG))])
15242    (parallel
15243      [(set (reg:CC FLAGS_REG)
15244            (parity:CC (match_dup 1)))
15245       (clobber (match_dup 1))
15246       (clobber (match_dup 2))])]
15247 {
15248   operands[4] = gen_lowpart (SImode, operands[3]);
15249
15250   if (MEM_P (operands[3]))
15251     emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
15252   else if (! TARGET_64BIT)
15253     operands[1] = gen_highpart (SImode, operands[3]);
15254   else
15255     {
15256       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15257       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15258     }
15259 })
15260
15261 (define_expand "paritysi2"
15262   [(set (match_operand:SI 0 "register_operand" "")
15263         (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
15264   "! TARGET_POPCNT"
15265 {
15266   rtx scratch = gen_reg_rtx (QImode);
15267   rtx cond;
15268
15269   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15270
15271   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15272                          gen_rtx_REG (CCmode, FLAGS_REG),
15273                          const0_rtx);
15274   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15275
15276   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15277   DONE;
15278 })
15279
15280 (define_insn_and_split "paritysi2_cmp"
15281   [(set (reg:CC FLAGS_REG)
15282         (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
15283    (clobber (match_scratch:SI 0 "=r,X"))
15284    (clobber (match_scratch:HI 1 "=Q,Q"))]
15285   "! TARGET_POPCNT"
15286   "#"
15287   "&& reload_completed"
15288   [(parallel
15289      [(set (match_dup 1)
15290            (xor:HI (match_dup 1) (match_dup 3)))
15291       (clobber (reg:CC FLAGS_REG))])
15292    (parallel
15293      [(set (reg:CC FLAGS_REG)
15294            (parity:CC (match_dup 1)))
15295       (clobber (match_dup 1))])]
15296 {
15297   operands[3] = gen_lowpart (HImode, operands[2]);
15298
15299   if (MEM_P (operands[2]))
15300     emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15301   else
15302     {
15303       emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15304       emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15305     }
15306 })
15307
15308 (define_insn "*parityhi2_cmp"
15309   [(set (reg:CC FLAGS_REG)
15310         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15311    (clobber (match_scratch:HI 0 "=Q"))]
15312   "! TARGET_POPCNT"
15313   "xor{b}\t{%h0, %b0|%b0, %h0}"
15314   [(set_attr "length" "2")
15315    (set_attr "mode" "HI")])
15316
15317 (define_insn "*parityqi2_cmp"
15318   [(set (reg:CC FLAGS_REG)
15319         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15320   "! TARGET_POPCNT"
15321   "test{b}\t%0, %0"
15322   [(set_attr "length" "2")
15323    (set_attr "mode" "QI")])
15324 \f
15325 ;; Thread-local storage patterns for ELF.
15326 ;;
15327 ;; Note that these code sequences must appear exactly as shown
15328 ;; in order to allow linker relaxation.
15329
15330 (define_insn "*tls_global_dynamic_32_gnu"
15331   [(set (match_operand:SI 0 "register_operand" "=a")
15332         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15333                     (match_operand:SI 2 "tls_symbolic_operand" "")
15334                     (match_operand:SI 3 "call_insn_operand" "")]
15335                     UNSPEC_TLS_GD))
15336    (clobber (match_scratch:SI 4 "=d"))
15337    (clobber (match_scratch:SI 5 "=c"))
15338    (clobber (reg:CC FLAGS_REG))]
15339   "!TARGET_64BIT && TARGET_GNU_TLS"
15340   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15341   [(set_attr "type" "multi")
15342    (set_attr "length" "12")])
15343
15344 (define_insn "*tls_global_dynamic_32_sun"
15345   [(set (match_operand:SI 0 "register_operand" "=a")
15346         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15347                     (match_operand:SI 2 "tls_symbolic_operand" "")
15348                     (match_operand:SI 3 "call_insn_operand" "")]
15349                     UNSPEC_TLS_GD))
15350    (clobber (match_scratch:SI 4 "=d"))
15351    (clobber (match_scratch:SI 5 "=c"))
15352    (clobber (reg:CC FLAGS_REG))]
15353   "!TARGET_64BIT && TARGET_SUN_TLS"
15354   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15355         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15356   [(set_attr "type" "multi")
15357    (set_attr "length" "14")])
15358
15359 (define_expand "tls_global_dynamic_32"
15360   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15361                    (unspec:SI
15362                     [(match_dup 2)
15363                      (match_operand:SI 1 "tls_symbolic_operand" "")
15364                      (match_dup 3)]
15365                     UNSPEC_TLS_GD))
15366               (clobber (match_scratch:SI 4 ""))
15367               (clobber (match_scratch:SI 5 ""))
15368               (clobber (reg:CC FLAGS_REG))])]
15369   ""
15370 {
15371   if (flag_pic)
15372     operands[2] = pic_offset_table_rtx;
15373   else
15374     {
15375       operands[2] = gen_reg_rtx (Pmode);
15376       emit_insn (gen_set_got (operands[2]));
15377     }
15378   if (TARGET_GNU2_TLS)
15379     {
15380        emit_insn (gen_tls_dynamic_gnu2_32
15381                   (operands[0], operands[1], operands[2]));
15382        DONE;
15383     }
15384   operands[3] = ix86_tls_get_addr ();
15385 })
15386
15387 (define_insn "*tls_global_dynamic_64"
15388   [(set (match_operand:DI 0 "register_operand" "=a")
15389         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15390                  (match_operand:DI 3 "" "")))
15391    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15392               UNSPEC_TLS_GD)]
15393   "TARGET_64BIT"
15394   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15395   [(set_attr "type" "multi")
15396    (set_attr "length" "16")])
15397
15398 (define_expand "tls_global_dynamic_64"
15399   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15400                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15401               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15402                          UNSPEC_TLS_GD)])]
15403   ""
15404 {
15405   if (TARGET_GNU2_TLS)
15406     {
15407        emit_insn (gen_tls_dynamic_gnu2_64
15408                   (operands[0], operands[1]));
15409        DONE;
15410     }
15411   operands[2] = ix86_tls_get_addr ();
15412 })
15413
15414 (define_insn "*tls_local_dynamic_base_32_gnu"
15415   [(set (match_operand:SI 0 "register_operand" "=a")
15416         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15417                     (match_operand:SI 2 "call_insn_operand" "")]
15418                    UNSPEC_TLS_LD_BASE))
15419    (clobber (match_scratch:SI 3 "=d"))
15420    (clobber (match_scratch:SI 4 "=c"))
15421    (clobber (reg:CC FLAGS_REG))]
15422   "!TARGET_64BIT && TARGET_GNU_TLS"
15423   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15424   [(set_attr "type" "multi")
15425    (set_attr "length" "11")])
15426
15427 (define_insn "*tls_local_dynamic_base_32_sun"
15428   [(set (match_operand:SI 0 "register_operand" "=a")
15429         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15430                     (match_operand:SI 2 "call_insn_operand" "")]
15431                    UNSPEC_TLS_LD_BASE))
15432    (clobber (match_scratch:SI 3 "=d"))
15433    (clobber (match_scratch:SI 4 "=c"))
15434    (clobber (reg:CC FLAGS_REG))]
15435   "!TARGET_64BIT && TARGET_SUN_TLS"
15436   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15437         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15438   [(set_attr "type" "multi")
15439    (set_attr "length" "13")])
15440
15441 (define_expand "tls_local_dynamic_base_32"
15442   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15443                    (unspec:SI [(match_dup 1) (match_dup 2)]
15444                               UNSPEC_TLS_LD_BASE))
15445               (clobber (match_scratch:SI 3 ""))
15446               (clobber (match_scratch:SI 4 ""))
15447               (clobber (reg:CC FLAGS_REG))])]
15448   ""
15449 {
15450   if (flag_pic)
15451     operands[1] = pic_offset_table_rtx;
15452   else
15453     {
15454       operands[1] = gen_reg_rtx (Pmode);
15455       emit_insn (gen_set_got (operands[1]));
15456     }
15457   if (TARGET_GNU2_TLS)
15458     {
15459        emit_insn (gen_tls_dynamic_gnu2_32
15460                   (operands[0], ix86_tls_module_base (), operands[1]));
15461        DONE;
15462     }
15463   operands[2] = ix86_tls_get_addr ();
15464 })
15465
15466 (define_insn "*tls_local_dynamic_base_64"
15467   [(set (match_operand:DI 0 "register_operand" "=a")
15468         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15469                  (match_operand:DI 2 "" "")))
15470    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15471   "TARGET_64BIT"
15472   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15473   [(set_attr "type" "multi")
15474    (set_attr "length" "12")])
15475
15476 (define_expand "tls_local_dynamic_base_64"
15477   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15478                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15479               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15480   ""
15481 {
15482   if (TARGET_GNU2_TLS)
15483     {
15484        emit_insn (gen_tls_dynamic_gnu2_64
15485                   (operands[0], ix86_tls_module_base ()));
15486        DONE;
15487     }
15488   operands[1] = ix86_tls_get_addr ();
15489 })
15490
15491 ;; Local dynamic of a single variable is a lose.  Show combine how
15492 ;; to convert that back to global dynamic.
15493
15494 (define_insn_and_split "*tls_local_dynamic_32_once"
15495   [(set (match_operand:SI 0 "register_operand" "=a")
15496         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15497                              (match_operand:SI 2 "call_insn_operand" "")]
15498                             UNSPEC_TLS_LD_BASE)
15499                  (const:SI (unspec:SI
15500                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15501                             UNSPEC_DTPOFF))))
15502    (clobber (match_scratch:SI 4 "=d"))
15503    (clobber (match_scratch:SI 5 "=c"))
15504    (clobber (reg:CC FLAGS_REG))]
15505   ""
15506   "#"
15507   ""
15508   [(parallel [(set (match_dup 0)
15509                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15510                               UNSPEC_TLS_GD))
15511               (clobber (match_dup 4))
15512               (clobber (match_dup 5))
15513               (clobber (reg:CC FLAGS_REG))])]
15514   "")
15515
15516 ;; Load and add the thread base pointer from %gs:0.
15517
15518 (define_insn "*load_tp_si"
15519   [(set (match_operand:SI 0 "register_operand" "=r")
15520         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15521   "!TARGET_64BIT"
15522   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15523   [(set_attr "type" "imov")
15524    (set_attr "modrm" "0")
15525    (set_attr "length" "7")
15526    (set_attr "memory" "load")
15527    (set_attr "imm_disp" "false")])
15528
15529 (define_insn "*add_tp_si"
15530   [(set (match_operand:SI 0 "register_operand" "=r")
15531         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15532                  (match_operand:SI 1 "register_operand" "0")))
15533    (clobber (reg:CC FLAGS_REG))]
15534   "!TARGET_64BIT"
15535   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15536   [(set_attr "type" "alu")
15537    (set_attr "modrm" "0")
15538    (set_attr "length" "7")
15539    (set_attr "memory" "load")
15540    (set_attr "imm_disp" "false")])
15541
15542 (define_insn "*load_tp_di"
15543   [(set (match_operand:DI 0 "register_operand" "=r")
15544         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15545   "TARGET_64BIT"
15546   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15547   [(set_attr "type" "imov")
15548    (set_attr "modrm" "0")
15549    (set_attr "length" "7")
15550    (set_attr "memory" "load")
15551    (set_attr "imm_disp" "false")])
15552
15553 (define_insn "*add_tp_di"
15554   [(set (match_operand:DI 0 "register_operand" "=r")
15555         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15556                  (match_operand:DI 1 "register_operand" "0")))
15557    (clobber (reg:CC FLAGS_REG))]
15558   "TARGET_64BIT"
15559   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15560   [(set_attr "type" "alu")
15561    (set_attr "modrm" "0")
15562    (set_attr "length" "7")
15563    (set_attr "memory" "load")
15564    (set_attr "imm_disp" "false")])
15565
15566 ;; GNU2 TLS patterns can be split.
15567
15568 (define_expand "tls_dynamic_gnu2_32"
15569   [(set (match_dup 3)
15570         (plus:SI (match_operand:SI 2 "register_operand" "")
15571                  (const:SI
15572                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15573                              UNSPEC_TLSDESC))))
15574    (parallel
15575     [(set (match_operand:SI 0 "register_operand" "")
15576           (unspec:SI [(match_dup 1) (match_dup 3)
15577                       (match_dup 2) (reg:SI SP_REG)]
15578                       UNSPEC_TLSDESC))
15579      (clobber (reg:CC FLAGS_REG))])]
15580   "!TARGET_64BIT && TARGET_GNU2_TLS"
15581 {
15582   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15583   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15584 })
15585
15586 (define_insn "*tls_dynamic_lea_32"
15587   [(set (match_operand:SI 0 "register_operand" "=r")
15588         (plus:SI (match_operand:SI 1 "register_operand" "b")
15589                  (const:SI
15590                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15591                               UNSPEC_TLSDESC))))]
15592   "!TARGET_64BIT && TARGET_GNU2_TLS"
15593   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15594   [(set_attr "type" "lea")
15595    (set_attr "mode" "SI")
15596    (set_attr "length" "6")
15597    (set_attr "length_address" "4")])
15598
15599 (define_insn "*tls_dynamic_call_32"
15600   [(set (match_operand:SI 0 "register_operand" "=a")
15601         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15602                     (match_operand:SI 2 "register_operand" "0")
15603                     ;; we have to make sure %ebx still points to the GOT
15604                     (match_operand:SI 3 "register_operand" "b")
15605                     (reg:SI SP_REG)]
15606                    UNSPEC_TLSDESC))
15607    (clobber (reg:CC FLAGS_REG))]
15608   "!TARGET_64BIT && TARGET_GNU2_TLS"
15609   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15610   [(set_attr "type" "call")
15611    (set_attr "length" "2")
15612    (set_attr "length_address" "0")])
15613
15614 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15615   [(set (match_operand:SI 0 "register_operand" "=&a")
15616         (plus:SI
15617          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15618                      (match_operand:SI 4 "" "")
15619                      (match_operand:SI 2 "register_operand" "b")
15620                      (reg:SI SP_REG)]
15621                     UNSPEC_TLSDESC)
15622          (const:SI (unspec:SI
15623                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15624                     UNSPEC_DTPOFF))))
15625    (clobber (reg:CC FLAGS_REG))]
15626   "!TARGET_64BIT && TARGET_GNU2_TLS"
15627   "#"
15628   ""
15629   [(set (match_dup 0) (match_dup 5))]
15630 {
15631   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15632   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15633 })
15634
15635 (define_expand "tls_dynamic_gnu2_64"
15636   [(set (match_dup 2)
15637         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15638                    UNSPEC_TLSDESC))
15639    (parallel
15640     [(set (match_operand:DI 0 "register_operand" "")
15641           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15642                      UNSPEC_TLSDESC))
15643      (clobber (reg:CC FLAGS_REG))])]
15644   "TARGET_64BIT && TARGET_GNU2_TLS"
15645 {
15646   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15647   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15648 })
15649
15650 (define_insn "*tls_dynamic_lea_64"
15651   [(set (match_operand:DI 0 "register_operand" "=r")
15652         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15653                    UNSPEC_TLSDESC))]
15654   "TARGET_64BIT && TARGET_GNU2_TLS"
15655   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15656   [(set_attr "type" "lea")
15657    (set_attr "mode" "DI")
15658    (set_attr "length" "7")
15659    (set_attr "length_address" "4")])
15660
15661 (define_insn "*tls_dynamic_call_64"
15662   [(set (match_operand:DI 0 "register_operand" "=a")
15663         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15664                     (match_operand:DI 2 "register_operand" "0")
15665                     (reg:DI SP_REG)]
15666                    UNSPEC_TLSDESC))
15667    (clobber (reg:CC FLAGS_REG))]
15668   "TARGET_64BIT && TARGET_GNU2_TLS"
15669   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15670   [(set_attr "type" "call")
15671    (set_attr "length" "2")
15672    (set_attr "length_address" "0")])
15673
15674 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15675   [(set (match_operand:DI 0 "register_operand" "=&a")
15676         (plus:DI
15677          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15678                      (match_operand:DI 3 "" "")
15679                      (reg:DI SP_REG)]
15680                     UNSPEC_TLSDESC)
15681          (const:DI (unspec:DI
15682                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15683                     UNSPEC_DTPOFF))))
15684    (clobber (reg:CC FLAGS_REG))]
15685   "TARGET_64BIT && TARGET_GNU2_TLS"
15686   "#"
15687   ""
15688   [(set (match_dup 0) (match_dup 4))]
15689 {
15690   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15691   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15692 })
15693
15694 ;;
15695 \f
15696 ;; These patterns match the binary 387 instructions for addM3, subM3,
15697 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15698 ;; SFmode.  The first is the normal insn, the second the same insn but
15699 ;; with one operand a conversion, and the third the same insn but with
15700 ;; the other operand a conversion.  The conversion may be SFmode or
15701 ;; SImode if the target mode DFmode, but only SImode if the target mode
15702 ;; is SFmode.
15703
15704 ;; Gcc is slightly more smart about handling normal two address instructions
15705 ;; so use special patterns for add and mull.
15706
15707 (define_insn "*fop_sf_comm_mixed"
15708   [(set (match_operand:SF 0 "register_operand" "=f,x")
15709         (match_operator:SF 3 "binary_fp_operator"
15710                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15711                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15712   "TARGET_MIX_SSE_I387
15713    && COMMUTATIVE_ARITH_P (operands[3])
15714    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15715   "* return output_387_binary_op (insn, operands);"
15716   [(set (attr "type")
15717         (if_then_else (eq_attr "alternative" "1")
15718            (if_then_else (match_operand:SF 3 "mult_operator" "")
15719               (const_string "ssemul")
15720               (const_string "sseadd"))
15721            (if_then_else (match_operand:SF 3 "mult_operator" "")
15722               (const_string "fmul")
15723               (const_string "fop"))))
15724    (set_attr "mode" "SF")])
15725
15726 (define_insn "*fop_sf_comm_sse"
15727   [(set (match_operand:SF 0 "register_operand" "=x")
15728         (match_operator:SF 3 "binary_fp_operator"
15729                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15730                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15731   "TARGET_SSE_MATH
15732    && COMMUTATIVE_ARITH_P (operands[3])
15733    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15734   "* return output_387_binary_op (insn, operands);"
15735   [(set (attr "type")
15736         (if_then_else (match_operand:SF 3 "mult_operator" "")
15737            (const_string "ssemul")
15738            (const_string "sseadd")))
15739    (set_attr "mode" "SF")])
15740
15741 (define_insn "*fop_sf_comm_i387"
15742   [(set (match_operand:SF 0 "register_operand" "=f")
15743         (match_operator:SF 3 "binary_fp_operator"
15744                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15745                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15746   "TARGET_80387
15747    && COMMUTATIVE_ARITH_P (operands[3])
15748    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15749   "* return output_387_binary_op (insn, operands);"
15750   [(set (attr "type")
15751         (if_then_else (match_operand:SF 3 "mult_operator" "")
15752            (const_string "fmul")
15753            (const_string "fop")))
15754    (set_attr "mode" "SF")])
15755
15756 (define_insn "*fop_sf_1_mixed"
15757   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15758         (match_operator:SF 3 "binary_fp_operator"
15759                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15760                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15761   "TARGET_MIX_SSE_I387
15762    && !COMMUTATIVE_ARITH_P (operands[3])
15763    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15764   "* return output_387_binary_op (insn, operands);"
15765   [(set (attr "type")
15766         (cond [(and (eq_attr "alternative" "2")
15767                     (match_operand:SF 3 "mult_operator" ""))
15768                  (const_string "ssemul")
15769                (and (eq_attr "alternative" "2")
15770                     (match_operand:SF 3 "div_operator" ""))
15771                  (const_string "ssediv")
15772                (eq_attr "alternative" "2")
15773                  (const_string "sseadd")
15774                (match_operand:SF 3 "mult_operator" "")
15775                  (const_string "fmul")
15776                (match_operand:SF 3 "div_operator" "")
15777                  (const_string "fdiv")
15778               ]
15779               (const_string "fop")))
15780    (set_attr "mode" "SF")])
15781
15782 (define_insn "*fop_sf_1_sse"
15783   [(set (match_operand:SF 0 "register_operand" "=x")
15784         (match_operator:SF 3 "binary_fp_operator"
15785                         [(match_operand:SF 1 "register_operand" "0")
15786                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15787   "TARGET_SSE_MATH
15788    && !COMMUTATIVE_ARITH_P (operands[3])"
15789   "* return output_387_binary_op (insn, operands);"
15790   [(set (attr "type")
15791         (cond [(match_operand:SF 3 "mult_operator" "")
15792                  (const_string "ssemul")
15793                (match_operand:SF 3 "div_operator" "")
15794                  (const_string "ssediv")
15795               ]
15796               (const_string "sseadd")))
15797    (set_attr "mode" "SF")])
15798
15799 ;; This pattern is not fully shadowed by the pattern above.
15800 (define_insn "*fop_sf_1_i387"
15801   [(set (match_operand:SF 0 "register_operand" "=f,f")
15802         (match_operator:SF 3 "binary_fp_operator"
15803                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15804                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15805   "TARGET_80387 && !TARGET_SSE_MATH
15806    && !COMMUTATIVE_ARITH_P (operands[3])
15807    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15808   "* return output_387_binary_op (insn, operands);"
15809   [(set (attr "type")
15810         (cond [(match_operand:SF 3 "mult_operator" "")
15811                  (const_string "fmul")
15812                (match_operand:SF 3 "div_operator" "")
15813                  (const_string "fdiv")
15814               ]
15815               (const_string "fop")))
15816    (set_attr "mode" "SF")])
15817
15818 ;; ??? Add SSE splitters for these!
15819 (define_insn "*fop_sf_2<mode>_i387"
15820   [(set (match_operand:SF 0 "register_operand" "=f,f")
15821         (match_operator:SF 3 "binary_fp_operator"
15822           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15823            (match_operand:SF 2 "register_operand" "0,0")]))]
15824   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15825   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15826   [(set (attr "type")
15827         (cond [(match_operand:SF 3 "mult_operator" "")
15828                  (const_string "fmul")
15829                (match_operand:SF 3 "div_operator" "")
15830                  (const_string "fdiv")
15831               ]
15832               (const_string "fop")))
15833    (set_attr "fp_int_src" "true")
15834    (set_attr "mode" "<MODE>")])
15835
15836 (define_insn "*fop_sf_3<mode>_i387"
15837   [(set (match_operand:SF 0 "register_operand" "=f,f")
15838         (match_operator:SF 3 "binary_fp_operator"
15839           [(match_operand:SF 1 "register_operand" "0,0")
15840            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15841   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15842   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15843   [(set (attr "type")
15844         (cond [(match_operand:SF 3 "mult_operator" "")
15845                  (const_string "fmul")
15846                (match_operand:SF 3 "div_operator" "")
15847                  (const_string "fdiv")
15848               ]
15849               (const_string "fop")))
15850    (set_attr "fp_int_src" "true")
15851    (set_attr "mode" "<MODE>")])
15852
15853 (define_insn "*fop_df_comm_mixed"
15854   [(set (match_operand:DF 0 "register_operand" "=f,x")
15855         (match_operator:DF 3 "binary_fp_operator"
15856           [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15857            (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15858   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15859    && COMMUTATIVE_ARITH_P (operands[3])
15860    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15861   "* return output_387_binary_op (insn, operands);"
15862   [(set (attr "type")
15863         (if_then_else (eq_attr "alternative" "1")
15864            (if_then_else (match_operand:DF 3 "mult_operator" "")
15865               (const_string "ssemul")
15866               (const_string "sseadd"))
15867            (if_then_else (match_operand:DF 3 "mult_operator" "")
15868               (const_string "fmul")
15869               (const_string "fop"))))
15870    (set_attr "mode" "DF")])
15871
15872 (define_insn "*fop_df_comm_sse"
15873   [(set (match_operand:DF 0 "register_operand" "=x")
15874         (match_operator:DF 3 "binary_fp_operator"
15875           [(match_operand:DF 1 "nonimmediate_operand" "%0")
15876            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15877   "TARGET_SSE2 && TARGET_SSE_MATH
15878    && COMMUTATIVE_ARITH_P (operands[3])
15879    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15880   "* return output_387_binary_op (insn, operands);"
15881   [(set (attr "type")
15882         (if_then_else (match_operand:DF 3 "mult_operator" "")
15883            (const_string "ssemul")
15884            (const_string "sseadd")))
15885    (set_attr "mode" "DF")])
15886
15887 (define_insn "*fop_df_comm_i387"
15888   [(set (match_operand:DF 0 "register_operand" "=f")
15889         (match_operator:DF 3 "binary_fp_operator"
15890                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15891                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15892   "TARGET_80387
15893    && COMMUTATIVE_ARITH_P (operands[3])
15894    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15895   "* return output_387_binary_op (insn, operands);"
15896   [(set (attr "type")
15897         (if_then_else (match_operand:DF 3 "mult_operator" "")
15898            (const_string "fmul")
15899            (const_string "fop")))
15900    (set_attr "mode" "DF")])
15901
15902 (define_insn "*fop_df_1_mixed"
15903   [(set (match_operand:DF 0 "register_operand" "=f,f,x")
15904         (match_operator:DF 3 "binary_fp_operator"
15905           [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15906            (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
15907   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15908    && !COMMUTATIVE_ARITH_P (operands[3])
15909    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15910   "* return output_387_binary_op (insn, operands);"
15911   [(set (attr "type")
15912         (cond [(and (eq_attr "alternative" "2")
15913                     (match_operand:DF 3 "mult_operator" ""))
15914                  (const_string "ssemul")
15915                (and (eq_attr "alternative" "2")
15916                     (match_operand:DF 3 "div_operator" ""))
15917                  (const_string "ssediv")
15918                (eq_attr "alternative" "2")
15919                  (const_string "sseadd")
15920                (match_operand:DF 3 "mult_operator" "")
15921                  (const_string "fmul")
15922                (match_operand:DF 3 "div_operator" "")
15923                  (const_string "fdiv")
15924               ]
15925               (const_string "fop")))
15926    (set_attr "mode" "DF")])
15927
15928 (define_insn "*fop_df_1_sse"
15929   [(set (match_operand:DF 0 "register_operand" "=x")
15930         (match_operator:DF 3 "binary_fp_operator"
15931           [(match_operand:DF 1 "register_operand" "0")
15932            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15933   "TARGET_SSE2 && TARGET_SSE_MATH
15934    && !COMMUTATIVE_ARITH_P (operands[3])"
15935   "* return output_387_binary_op (insn, operands);"
15936   [(set_attr "mode" "DF")
15937    (set (attr "type")
15938         (cond [(match_operand:DF 3 "mult_operator" "")
15939                  (const_string "ssemul")
15940                (match_operand:DF 3 "div_operator" "")
15941                  (const_string "ssediv")
15942               ]
15943               (const_string "sseadd")))])
15944
15945 ;; This pattern is not fully shadowed by the pattern above.
15946 (define_insn "*fop_df_1_i387"
15947   [(set (match_operand:DF 0 "register_operand" "=f,f")
15948         (match_operator:DF 3 "binary_fp_operator"
15949                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15950                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15951   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15952    && !COMMUTATIVE_ARITH_P (operands[3])
15953    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15954   "* return output_387_binary_op (insn, operands);"
15955   [(set (attr "type")
15956         (cond [(match_operand:DF 3 "mult_operator" "")
15957                  (const_string "fmul")
15958                (match_operand:DF 3 "div_operator" "")
15959                  (const_string "fdiv")
15960               ]
15961               (const_string "fop")))
15962    (set_attr "mode" "DF")])
15963
15964 ;; ??? Add SSE splitters for these!
15965 (define_insn "*fop_df_2<mode>_i387"
15966   [(set (match_operand:DF 0 "register_operand" "=f,f")
15967         (match_operator:DF 3 "binary_fp_operator"
15968            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15969             (match_operand:DF 2 "register_operand" "0,0")]))]
15970   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15971    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15972   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15973   [(set (attr "type")
15974         (cond [(match_operand:DF 3 "mult_operator" "")
15975                  (const_string "fmul")
15976                (match_operand:DF 3 "div_operator" "")
15977                  (const_string "fdiv")
15978               ]
15979               (const_string "fop")))
15980    (set_attr "fp_int_src" "true")
15981    (set_attr "mode" "<MODE>")])
15982
15983 (define_insn "*fop_df_3<mode>_i387"
15984   [(set (match_operand:DF 0 "register_operand" "=f,f")
15985         (match_operator:DF 3 "binary_fp_operator"
15986            [(match_operand:DF 1 "register_operand" "0,0")
15987             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15988   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15989    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15990   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15991   [(set (attr "type")
15992         (cond [(match_operand:DF 3 "mult_operator" "")
15993                  (const_string "fmul")
15994                (match_operand:DF 3 "div_operator" "")
15995                  (const_string "fdiv")
15996               ]
15997               (const_string "fop")))
15998    (set_attr "fp_int_src" "true")
15999    (set_attr "mode" "<MODE>")])
16000
16001 (define_insn "*fop_df_4_i387"
16002   [(set (match_operand:DF 0 "register_operand" "=f,f")
16003         (match_operator:DF 3 "binary_fp_operator"
16004            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16005             (match_operand:DF 2 "register_operand" "0,f")]))]
16006   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16007    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16008   "* return output_387_binary_op (insn, operands);"
16009   [(set (attr "type")
16010         (cond [(match_operand:DF 3 "mult_operator" "")
16011                  (const_string "fmul")
16012                (match_operand:DF 3 "div_operator" "")
16013                  (const_string "fdiv")
16014               ]
16015               (const_string "fop")))
16016    (set_attr "mode" "SF")])
16017
16018 (define_insn "*fop_df_5_i387"
16019   [(set (match_operand:DF 0 "register_operand" "=f,f")
16020         (match_operator:DF 3 "binary_fp_operator"
16021           [(match_operand:DF 1 "register_operand" "0,f")
16022            (float_extend:DF
16023             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16024   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16025   "* return output_387_binary_op (insn, operands);"
16026   [(set (attr "type")
16027         (cond [(match_operand:DF 3 "mult_operator" "")
16028                  (const_string "fmul")
16029                (match_operand:DF 3 "div_operator" "")
16030                  (const_string "fdiv")
16031               ]
16032               (const_string "fop")))
16033    (set_attr "mode" "SF")])
16034
16035 (define_insn "*fop_df_6_i387"
16036   [(set (match_operand:DF 0 "register_operand" "=f,f")
16037         (match_operator:DF 3 "binary_fp_operator"
16038           [(float_extend:DF
16039             (match_operand:SF 1 "register_operand" "0,f"))
16040            (float_extend:DF
16041             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16042   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16043   "* return output_387_binary_op (insn, operands);"
16044   [(set (attr "type")
16045         (cond [(match_operand:DF 3 "mult_operator" "")
16046                  (const_string "fmul")
16047                (match_operand:DF 3 "div_operator" "")
16048                  (const_string "fdiv")
16049               ]
16050               (const_string "fop")))
16051    (set_attr "mode" "SF")])
16052
16053 (define_insn "*fop_xf_comm_i387"
16054   [(set (match_operand:XF 0 "register_operand" "=f")
16055         (match_operator:XF 3 "binary_fp_operator"
16056                         [(match_operand:XF 1 "register_operand" "%0")
16057                          (match_operand:XF 2 "register_operand" "f")]))]
16058   "TARGET_80387
16059    && COMMUTATIVE_ARITH_P (operands[3])"
16060   "* return output_387_binary_op (insn, operands);"
16061   [(set (attr "type")
16062         (if_then_else (match_operand:XF 3 "mult_operator" "")
16063            (const_string "fmul")
16064            (const_string "fop")))
16065    (set_attr "mode" "XF")])
16066
16067 (define_insn "*fop_xf_1_i387"
16068   [(set (match_operand:XF 0 "register_operand" "=f,f")
16069         (match_operator:XF 3 "binary_fp_operator"
16070                         [(match_operand:XF 1 "register_operand" "0,f")
16071                          (match_operand:XF 2 "register_operand" "f,0")]))]
16072   "TARGET_80387
16073    && !COMMUTATIVE_ARITH_P (operands[3])"
16074   "* return output_387_binary_op (insn, operands);"
16075   [(set (attr "type")
16076         (cond [(match_operand:XF 3 "mult_operator" "")
16077                  (const_string "fmul")
16078                (match_operand:XF 3 "div_operator" "")
16079                  (const_string "fdiv")
16080               ]
16081               (const_string "fop")))
16082    (set_attr "mode" "XF")])
16083
16084 (define_insn "*fop_xf_2<mode>_i387"
16085   [(set (match_operand:XF 0 "register_operand" "=f,f")
16086         (match_operator:XF 3 "binary_fp_operator"
16087            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16088             (match_operand:XF 2 "register_operand" "0,0")]))]
16089   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16090   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16091   [(set (attr "type")
16092         (cond [(match_operand:XF 3 "mult_operator" "")
16093                  (const_string "fmul")
16094                (match_operand:XF 3 "div_operator" "")
16095                  (const_string "fdiv")
16096               ]
16097               (const_string "fop")))
16098    (set_attr "fp_int_src" "true")
16099    (set_attr "mode" "<MODE>")])
16100
16101 (define_insn "*fop_xf_3<mode>_i387"
16102   [(set (match_operand:XF 0 "register_operand" "=f,f")
16103         (match_operator:XF 3 "binary_fp_operator"
16104           [(match_operand:XF 1 "register_operand" "0,0")
16105            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16106   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16107   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16108   [(set (attr "type")
16109         (cond [(match_operand:XF 3 "mult_operator" "")
16110                  (const_string "fmul")
16111                (match_operand:XF 3 "div_operator" "")
16112                  (const_string "fdiv")
16113               ]
16114               (const_string "fop")))
16115    (set_attr "fp_int_src" "true")
16116    (set_attr "mode" "<MODE>")])
16117
16118 (define_insn "*fop_xf_4_i387"
16119   [(set (match_operand:XF 0 "register_operand" "=f,f")
16120         (match_operator:XF 3 "binary_fp_operator"
16121            [(float_extend:XF
16122               (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
16123             (match_operand:XF 2 "register_operand" "0,f")]))]
16124   "TARGET_80387"
16125   "* return output_387_binary_op (insn, operands);"
16126   [(set (attr "type")
16127         (cond [(match_operand:XF 3 "mult_operator" "")
16128                  (const_string "fmul")
16129                (match_operand:XF 3 "div_operator" "")
16130                  (const_string "fdiv")
16131               ]
16132               (const_string "fop")))
16133    (set_attr "mode" "SF")])
16134
16135 (define_insn "*fop_xf_5_i387"
16136   [(set (match_operand:XF 0 "register_operand" "=f,f")
16137         (match_operator:XF 3 "binary_fp_operator"
16138           [(match_operand:XF 1 "register_operand" "0,f")
16139            (float_extend:XF
16140              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
16141   "TARGET_80387"
16142   "* return output_387_binary_op (insn, operands);"
16143   [(set (attr "type")
16144         (cond [(match_operand:XF 3 "mult_operator" "")
16145                  (const_string "fmul")
16146                (match_operand:XF 3 "div_operator" "")
16147                  (const_string "fdiv")
16148               ]
16149               (const_string "fop")))
16150    (set_attr "mode" "SF")])
16151
16152 (define_insn "*fop_xf_6_i387"
16153   [(set (match_operand:XF 0 "register_operand" "=f,f")
16154         (match_operator:XF 3 "binary_fp_operator"
16155           [(float_extend:XF
16156              (match_operand:X87MODEF12 1 "register_operand" "0,f"))
16157            (float_extend:XF
16158              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
16159   "TARGET_80387"
16160   "* return output_387_binary_op (insn, operands);"
16161   [(set (attr "type")
16162         (cond [(match_operand:XF 3 "mult_operator" "")
16163                  (const_string "fmul")
16164                (match_operand:XF 3 "div_operator" "")
16165                  (const_string "fdiv")
16166               ]
16167               (const_string "fop")))
16168    (set_attr "mode" "SF")])
16169
16170 (define_split
16171   [(set (match_operand 0 "register_operand" "")
16172         (match_operator 3 "binary_fp_operator"
16173            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16174             (match_operand 2 "register_operand" "")]))]
16175   "TARGET_80387 && reload_completed
16176    && FLOAT_MODE_P (GET_MODE (operands[0]))"
16177   [(const_int 0)]
16178 {
16179   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16180   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16181   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16182                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16183                                           GET_MODE (operands[3]),
16184                                           operands[4],
16185                                           operands[2])));
16186   ix86_free_from_memory (GET_MODE (operands[1]));
16187   DONE;
16188 })
16189
16190 (define_split
16191   [(set (match_operand 0 "register_operand" "")
16192         (match_operator 3 "binary_fp_operator"
16193            [(match_operand 1 "register_operand" "")
16194             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16195   "TARGET_80387 && reload_completed
16196    && FLOAT_MODE_P (GET_MODE (operands[0]))"
16197   [(const_int 0)]
16198 {
16199   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16200   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16201   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16202                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16203                                           GET_MODE (operands[3]),
16204                                           operands[1],
16205                                           operands[4])));
16206   ix86_free_from_memory (GET_MODE (operands[2]));
16207   DONE;
16208 })
16209 \f
16210 ;; FPU special functions.
16211
16212 ;; This pattern implements a no-op XFmode truncation for
16213 ;; all fancy i386 XFmode math functions.
16214
16215 (define_insn "truncxf<mode>2_i387_noop_unspec"
16216   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16217         (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
16218         UNSPEC_TRUNC_NOOP))]
16219   "TARGET_USE_FANCY_MATH_387"
16220   "* return output_387_reg_move (insn, operands);"
16221   [(set_attr "type" "fmov")
16222    (set_attr "mode" "<MODE>")])
16223
16224 (define_insn "sqrtxf2"
16225   [(set (match_operand:XF 0 "register_operand" "=f")
16226         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16227   "TARGET_USE_FANCY_MATH_387"
16228   "fsqrt"
16229   [(set_attr "type" "fpspc")
16230    (set_attr "mode" "XF")
16231    (set_attr "athlon_decode" "direct")
16232    (set_attr "amdfam10_decode" "direct")])
16233
16234 (define_insn "sqrt_extend<mode>xf2_i387"
16235   [(set (match_operand:XF 0 "register_operand" "=f")
16236         (sqrt:XF
16237           (float_extend:XF
16238             (match_operand:X87MODEF12 1 "register_operand" "0"))))]
16239   "TARGET_USE_FANCY_MATH_387"
16240   "fsqrt"
16241   [(set_attr "type" "fpspc")
16242    (set_attr "mode" "XF")
16243    (set_attr "athlon_decode" "direct")   
16244    (set_attr "amdfam10_decode" "direct")])
16245
16246 (define_insn "*sqrt<mode>2_sse"
16247   [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
16248         (sqrt:SSEMODEF
16249           (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
16250   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16251   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16252   [(set_attr "type" "sse")
16253    (set_attr "mode" "<MODE>")
16254    (set_attr "athlon_decode" "*")
16255    (set_attr "amdfam10_decode" "*")])
16256
16257 (define_expand "sqrt<mode>2"
16258   [(set (match_operand:X87MODEF12 0 "register_operand" "")
16259         (sqrt:X87MODEF12
16260           (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
16261   "TARGET_USE_FANCY_MATH_387
16262    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16263 {
16264   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16265     {
16266       rtx op0 = gen_reg_rtx (XFmode);
16267       rtx op1 = force_reg (<MODE>mode, operands[1]);
16268
16269       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16270       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16271       DONE;
16272    }
16273 })
16274
16275 (define_insn "fpremxf4_i387"
16276   [(set (match_operand:XF 0 "register_operand" "=f")
16277         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16278                     (match_operand:XF 3 "register_operand" "1")]
16279                    UNSPEC_FPREM_F))
16280    (set (match_operand:XF 1 "register_operand" "=u")
16281         (unspec:XF [(match_dup 2) (match_dup 3)]
16282                    UNSPEC_FPREM_U))
16283    (set (reg:CCFP FPSR_REG)
16284         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16285                      UNSPEC_C2_FLAG))]
16286   "TARGET_USE_FANCY_MATH_387"
16287   "fprem"
16288   [(set_attr "type" "fpspc")
16289    (set_attr "mode" "XF")])
16290
16291 (define_expand "fmodxf3"
16292   [(use (match_operand:XF 0 "register_operand" ""))
16293    (use (match_operand:XF 1 "register_operand" ""))
16294    (use (match_operand:XF 2 "register_operand" ""))]
16295   "TARGET_USE_FANCY_MATH_387"
16296 {
16297   rtx label = gen_label_rtx ();
16298
16299   emit_label (label);
16300
16301   emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
16302                                 operands[1], operands[2]));
16303   ix86_emit_fp_unordered_jump (label);
16304   LABEL_NUSES (label) = 1;
16305
16306   emit_move_insn (operands[0], operands[1]);
16307   DONE;
16308 })
16309
16310 (define_expand "fmod<mode>3"
16311   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16312    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16313    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16314   "TARGET_USE_FANCY_MATH_387"
16315 {
16316   rtx label = gen_label_rtx ();
16317
16318   rtx op1 = gen_reg_rtx (XFmode);
16319   rtx op2 = gen_reg_rtx (XFmode);
16320
16321   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16322   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16323
16324   emit_label (label);
16325   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16326   ix86_emit_fp_unordered_jump (label);
16327   LABEL_NUSES (label) = 1;
16328
16329   /* Truncate the result properly for strict SSE math.  */
16330   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16331       && !TARGET_MIX_SSE_I387)
16332     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16333   else
16334     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16335
16336   DONE;
16337 })
16338
16339 (define_insn "fprem1xf4_i387"
16340   [(set (match_operand:XF 0 "register_operand" "=f")
16341         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16342                     (match_operand:XF 3 "register_operand" "1")]
16343                    UNSPEC_FPREM1_F))
16344    (set (match_operand:XF 1 "register_operand" "=u")
16345         (unspec:XF [(match_dup 2) (match_dup 3)]
16346                    UNSPEC_FPREM1_U))
16347    (set (reg:CCFP FPSR_REG)
16348         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16349                      UNSPEC_C2_FLAG))]
16350   "TARGET_USE_FANCY_MATH_387"
16351   "fprem1"
16352   [(set_attr "type" "fpspc")
16353    (set_attr "mode" "XF")])
16354
16355 (define_expand "remainderxf3"
16356   [(use (match_operand:XF 0 "register_operand" ""))
16357    (use (match_operand:XF 1 "register_operand" ""))
16358    (use (match_operand:XF 2 "register_operand" ""))]
16359   "TARGET_USE_FANCY_MATH_387"
16360 {
16361   rtx label = gen_label_rtx ();
16362
16363   emit_label (label);
16364
16365   emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
16366                                  operands[1], operands[2]));
16367   ix86_emit_fp_unordered_jump (label);
16368   LABEL_NUSES (label) = 1;
16369
16370   emit_move_insn (operands[0], operands[1]);
16371   DONE;
16372 })
16373
16374 (define_expand "remainder<mode>3"
16375   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16376    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16377    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16378   "TARGET_USE_FANCY_MATH_387"
16379 {
16380   rtx label = gen_label_rtx ();
16381
16382   rtx op1 = gen_reg_rtx (XFmode);
16383   rtx op2 = gen_reg_rtx (XFmode);
16384
16385   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16386   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16387
16388   emit_label (label);
16389
16390   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16391   ix86_emit_fp_unordered_jump (label);
16392   LABEL_NUSES (label) = 1;
16393
16394   /* Truncate the result properly for strict SSE math.  */
16395   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16396       && !TARGET_MIX_SSE_I387)
16397     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16398   else
16399     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16400
16401   DONE;
16402 })
16403
16404 (define_insn "*sinxf2_i387"
16405   [(set (match_operand:XF 0 "register_operand" "=f")
16406         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16407   "TARGET_USE_FANCY_MATH_387
16408    && flag_unsafe_math_optimizations"
16409   "fsin"
16410   [(set_attr "type" "fpspc")
16411    (set_attr "mode" "XF")])
16412
16413 (define_insn "*sin_extend<mode>xf2_i387"
16414   [(set (match_operand:XF 0 "register_operand" "=f")
16415         (unspec:XF [(float_extend:XF
16416                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
16417                    UNSPEC_SIN))]
16418   "TARGET_USE_FANCY_MATH_387
16419    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16420        || TARGET_MIX_SSE_I387)
16421    && flag_unsafe_math_optimizations"
16422   "fsin"
16423   [(set_attr "type" "fpspc")
16424    (set_attr "mode" "XF")])
16425
16426 (define_insn "*cosxf2_i387"
16427   [(set (match_operand:XF 0 "register_operand" "=f")
16428         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16429   "TARGET_USE_FANCY_MATH_387
16430    && flag_unsafe_math_optimizations"
16431   "fcos"
16432   [(set_attr "type" "fpspc")
16433    (set_attr "mode" "XF")])
16434
16435 (define_insn "*cos_extend<mode>xf2_i387"
16436   [(set (match_operand:XF 0 "register_operand" "=f")
16437         (unspec:XF [(float_extend:XF
16438                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
16439                    UNSPEC_COS))]
16440   "TARGET_USE_FANCY_MATH_387
16441    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16442        || TARGET_MIX_SSE_I387)
16443    && flag_unsafe_math_optimizations"
16444   "fcos"
16445   [(set_attr "type" "fpspc")
16446    (set_attr "mode" "XF")])
16447
16448 ;; When sincos pattern is defined, sin and cos builtin functions will be
16449 ;; expanded to sincos pattern with one of its outputs left unused.
16450 ;; CSE pass will figure out if two sincos patterns can be combined,
16451 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16452 ;; depending on the unused output.
16453
16454 (define_insn "sincosxf3"
16455   [(set (match_operand:XF 0 "register_operand" "=f")
16456         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16457                    UNSPEC_SINCOS_COS))
16458    (set (match_operand:XF 1 "register_operand" "=u")
16459         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16460   "TARGET_USE_FANCY_MATH_387
16461    && flag_unsafe_math_optimizations"
16462   "fsincos"
16463   [(set_attr "type" "fpspc")
16464    (set_attr "mode" "XF")])
16465
16466 (define_split
16467   [(set (match_operand:XF 0 "register_operand" "")
16468         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16469                    UNSPEC_SINCOS_COS))
16470    (set (match_operand:XF 1 "register_operand" "")
16471         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16472   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16473    && !reload_completed && !reload_in_progress"
16474   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16475   "")
16476
16477 (define_split
16478   [(set (match_operand:XF 0 "register_operand" "")
16479         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16480                    UNSPEC_SINCOS_COS))
16481    (set (match_operand:XF 1 "register_operand" "")
16482         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16483   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16484    && !reload_completed && !reload_in_progress"
16485   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16486   "")
16487
16488 (define_insn "sincos_extend<mode>xf3_i387"
16489   [(set (match_operand:XF 0 "register_operand" "=f")
16490         (unspec:XF [(float_extend:XF
16491                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16492                    UNSPEC_SINCOS_COS))
16493    (set (match_operand:XF 1 "register_operand" "=u")
16494         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16495   "TARGET_USE_FANCY_MATH_387
16496    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16497        || TARGET_MIX_SSE_I387)
16498    && flag_unsafe_math_optimizations"
16499   "fsincos"
16500   [(set_attr "type" "fpspc")
16501    (set_attr "mode" "XF")])
16502
16503 (define_split
16504   [(set (match_operand:XF 0 "register_operand" "")
16505         (unspec:XF [(float_extend:XF
16506                       (match_operand:X87MODEF12 2 "register_operand" ""))]
16507                    UNSPEC_SINCOS_COS))
16508    (set (match_operand:XF 1 "register_operand" "")
16509         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16510   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16511    && !reload_completed && !reload_in_progress"
16512   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16513   "")
16514
16515 (define_split
16516   [(set (match_operand:XF 0 "register_operand" "")
16517         (unspec:XF [(float_extend:XF
16518                       (match_operand:X87MODEF12 2 "register_operand" ""))]
16519                    UNSPEC_SINCOS_COS))
16520    (set (match_operand:XF 1 "register_operand" "")
16521         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16522   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16523    && !reload_completed && !reload_in_progress"
16524   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16525   "")
16526
16527 (define_expand "sincos<mode>3"
16528   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16529    (use (match_operand:X87MODEF12 1 "register_operand" ""))
16530    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16531   "TARGET_USE_FANCY_MATH_387
16532    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16533        || TARGET_MIX_SSE_I387)
16534    && flag_unsafe_math_optimizations"
16535 {
16536   rtx op0 = gen_reg_rtx (XFmode);
16537   rtx op1 = gen_reg_rtx (XFmode);
16538
16539   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16540   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16541   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16542   DONE;
16543 })
16544
16545 (define_insn "fptanxf4_i387"
16546   [(set (match_operand:XF 0 "register_operand" "=f")
16547         (match_operand:XF 3 "const_double_operand" "F"))
16548    (set (match_operand:XF 1 "register_operand" "=u")
16549         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16550                    UNSPEC_TAN))]
16551   "TARGET_USE_FANCY_MATH_387
16552    && flag_unsafe_math_optimizations
16553    && standard_80387_constant_p (operands[3]) == 2"
16554   "fptan"
16555   [(set_attr "type" "fpspc")
16556    (set_attr "mode" "XF")])
16557
16558 (define_insn "fptan_extend<mode>xf4_i387"
16559   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16560         (match_operand:X87MODEF12 3 "const_double_operand" "F"))
16561    (set (match_operand:XF 1 "register_operand" "=u")
16562         (unspec:XF [(float_extend:XF
16563                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16564                    UNSPEC_TAN))]
16565   "TARGET_USE_FANCY_MATH_387
16566    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16567        || TARGET_MIX_SSE_I387)
16568    && flag_unsafe_math_optimizations
16569    && standard_80387_constant_p (operands[3]) == 2"
16570   "fptan"
16571   [(set_attr "type" "fpspc")
16572    (set_attr "mode" "XF")])
16573
16574 (define_expand "tanxf2"
16575   [(use (match_operand:XF 0 "register_operand" ""))
16576    (use (match_operand:XF 1 "register_operand" ""))]
16577   "TARGET_USE_FANCY_MATH_387
16578    && flag_unsafe_math_optimizations"
16579 {
16580   rtx one = gen_reg_rtx (XFmode);
16581   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16582
16583   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16584   DONE;
16585 })
16586
16587 (define_expand "tan<mode>2"
16588   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16589    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16590   "TARGET_USE_FANCY_MATH_387
16591    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16592        || TARGET_MIX_SSE_I387)
16593    && flag_unsafe_math_optimizations"
16594 {
16595   rtx op0 = gen_reg_rtx (XFmode);
16596
16597   rtx one = gen_reg_rtx (<MODE>mode);
16598   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16599
16600   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16601                                              operands[1], op2));
16602   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16603   DONE;
16604 })
16605
16606 (define_insn "*fpatanxf3_i387"
16607   [(set (match_operand:XF 0 "register_operand" "=f")
16608         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16609                     (match_operand:XF 2 "register_operand" "u")]
16610                    UNSPEC_FPATAN))
16611    (clobber (match_scratch:XF 3 "=2"))]
16612   "TARGET_USE_FANCY_MATH_387
16613    && flag_unsafe_math_optimizations"
16614   "fpatan"
16615   [(set_attr "type" "fpspc")
16616    (set_attr "mode" "XF")])
16617
16618 (define_insn "fpatan_extend<mode>xf3_i387"
16619   [(set (match_operand:XF 0 "register_operand" "=f")
16620         (unspec:XF [(float_extend:XF
16621                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16622                     (float_extend:XF
16623                       (match_operand:X87MODEF12 2 "register_operand" "u"))]
16624                    UNSPEC_FPATAN))
16625    (clobber (match_scratch:XF 3 "=2"))]
16626   "TARGET_USE_FANCY_MATH_387
16627    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16628        || TARGET_MIX_SSE_I387)
16629    && flag_unsafe_math_optimizations"
16630   "fpatan"
16631   [(set_attr "type" "fpspc")
16632    (set_attr "mode" "XF")])
16633
16634 (define_expand "atan2xf3"
16635   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16636                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16637                                (match_operand:XF 1 "register_operand" "")]
16638                               UNSPEC_FPATAN))
16639               (clobber (match_scratch:XF 3 ""))])]
16640   "TARGET_USE_FANCY_MATH_387
16641    && flag_unsafe_math_optimizations"
16642   "")
16643
16644 (define_expand "atan2<mode>3"
16645   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16646    (use (match_operand:X87MODEF12 1 "register_operand" ""))
16647    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16648   "TARGET_USE_FANCY_MATH_387
16649    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16650        || TARGET_MIX_SSE_I387)
16651    && flag_unsafe_math_optimizations"
16652 {
16653   rtx op0 = gen_reg_rtx (XFmode);
16654
16655   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16656   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16657   DONE;
16658 })
16659
16660 (define_expand "atanxf2"
16661   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16662                    (unspec:XF [(match_dup 2)
16663                                (match_operand:XF 1 "register_operand" "")]
16664                               UNSPEC_FPATAN))
16665               (clobber (match_scratch:XF 3 ""))])]
16666   "TARGET_USE_FANCY_MATH_387
16667    && flag_unsafe_math_optimizations"
16668 {
16669   operands[2] = gen_reg_rtx (XFmode);
16670   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16671 })
16672
16673 (define_expand "atan<mode>2"
16674   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16675    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16676   "TARGET_USE_FANCY_MATH_387
16677    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16678        || TARGET_MIX_SSE_I387)
16679    && flag_unsafe_math_optimizations"
16680 {
16681   rtx op0 = gen_reg_rtx (XFmode);
16682
16683   rtx op2 = gen_reg_rtx (<MODE>mode);
16684   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16685
16686   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16687   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16688   DONE;
16689 })
16690
16691 (define_expand "asinxf2"
16692   [(set (match_dup 2)
16693         (mult:XF (match_operand:XF 1 "register_operand" "")
16694                  (match_dup 1)))
16695    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16696    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16697    (parallel [(set (match_operand:XF 0 "register_operand" "")
16698                    (unspec:XF [(match_dup 5) (match_dup 1)]
16699                               UNSPEC_FPATAN))
16700               (clobber (match_scratch:XF 6 ""))])]
16701   "TARGET_USE_FANCY_MATH_387
16702    && flag_unsafe_math_optimizations && !optimize_size"
16703 {
16704   int i;
16705
16706   for (i = 2; i < 6; i++)
16707     operands[i] = gen_reg_rtx (XFmode);
16708
16709   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16710 })
16711
16712 (define_expand "asin<mode>2"
16713   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16714    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16715  "TARGET_USE_FANCY_MATH_387
16716    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16717        || TARGET_MIX_SSE_I387)
16718    && flag_unsafe_math_optimizations && !optimize_size"
16719 {
16720   rtx op0 = gen_reg_rtx (XFmode);
16721   rtx op1 = gen_reg_rtx (XFmode);
16722
16723   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16724   emit_insn (gen_asinxf2 (op0, op1));
16725   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16726   DONE;
16727 })
16728
16729 (define_expand "acosxf2"
16730   [(set (match_dup 2)
16731         (mult:XF (match_operand:XF 1 "register_operand" "")
16732                  (match_dup 1)))
16733    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16734    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16735    (parallel [(set (match_operand:XF 0 "register_operand" "")
16736                    (unspec:XF [(match_dup 1) (match_dup 5)]
16737                               UNSPEC_FPATAN))
16738               (clobber (match_scratch:XF 6 ""))])]
16739   "TARGET_USE_FANCY_MATH_387
16740    && flag_unsafe_math_optimizations && !optimize_size"
16741 {
16742   int i;
16743
16744   for (i = 2; i < 6; i++)
16745     operands[i] = gen_reg_rtx (XFmode);
16746
16747   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16748 })
16749
16750 (define_expand "acos<mode>2"
16751   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16752    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16753  "TARGET_USE_FANCY_MATH_387
16754    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16755        || TARGET_MIX_SSE_I387)
16756    && flag_unsafe_math_optimizations && !optimize_size"
16757 {
16758   rtx op0 = gen_reg_rtx (XFmode);
16759   rtx op1 = gen_reg_rtx (XFmode);
16760
16761   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16762   emit_insn (gen_acosxf2 (op0, op1));
16763   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16764   DONE;
16765 })
16766
16767 (define_insn "fyl2xxf3_i387"
16768   [(set (match_operand:XF 0 "register_operand" "=f")
16769         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16770                     (match_operand:XF 2 "register_operand" "u")]
16771                    UNSPEC_FYL2X))
16772    (clobber (match_scratch:XF 3 "=2"))]
16773   "TARGET_USE_FANCY_MATH_387
16774    && flag_unsafe_math_optimizations"
16775   "fyl2x"
16776   [(set_attr "type" "fpspc")
16777    (set_attr "mode" "XF")])
16778
16779 (define_insn "fyl2x_extend<mode>xf3_i387"
16780   [(set (match_operand:XF 0 "register_operand" "=f")
16781         (unspec:XF [(float_extend:XF
16782                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16783                     (match_operand:XF 2 "register_operand" "u")]
16784                    UNSPEC_FYL2X))
16785    (clobber (match_scratch:XF 3 "=2"))]
16786   "TARGET_USE_FANCY_MATH_387
16787    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16788        || TARGET_MIX_SSE_I387)
16789    && flag_unsafe_math_optimizations"
16790   "fyl2x"
16791   [(set_attr "type" "fpspc")
16792    (set_attr "mode" "XF")])
16793
16794 (define_expand "logxf2"
16795   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16796                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16797                                (match_dup 2)] UNSPEC_FYL2X))
16798               (clobber (match_scratch:XF 3 ""))])]
16799   "TARGET_USE_FANCY_MATH_387
16800    && flag_unsafe_math_optimizations"
16801 {
16802   operands[2] = gen_reg_rtx (XFmode);
16803   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16804 })
16805
16806 (define_expand "log<mode>2"
16807   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16808    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16809   "TARGET_USE_FANCY_MATH_387
16810    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16811        || TARGET_MIX_SSE_I387)
16812    && flag_unsafe_math_optimizations"
16813 {
16814   rtx op0 = gen_reg_rtx (XFmode);
16815
16816   rtx op2 = gen_reg_rtx (XFmode);
16817   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16818
16819   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16820   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16821   DONE;
16822 })
16823
16824 (define_expand "log10xf2"
16825   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16826                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16827                                (match_dup 2)] UNSPEC_FYL2X))
16828               (clobber (match_scratch:XF 3 ""))])]
16829   "TARGET_USE_FANCY_MATH_387
16830    && flag_unsafe_math_optimizations"
16831 {
16832   operands[2] = gen_reg_rtx (XFmode);
16833   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16834 })
16835
16836 (define_expand "log10<mode>2"
16837   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16838    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16839   "TARGET_USE_FANCY_MATH_387
16840    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16841        || TARGET_MIX_SSE_I387)
16842    && flag_unsafe_math_optimizations"
16843 {
16844   rtx op0 = gen_reg_rtx (XFmode);
16845
16846   rtx op2 = gen_reg_rtx (XFmode);
16847   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16848
16849   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16850   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16851   DONE;
16852 })
16853
16854 (define_expand "log2xf2"
16855   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16856                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16857                                (match_dup 2)] UNSPEC_FYL2X))
16858               (clobber (match_scratch:XF 3 ""))])]
16859   "TARGET_USE_FANCY_MATH_387
16860    && flag_unsafe_math_optimizations"
16861 {
16862   operands[2] = gen_reg_rtx (XFmode);
16863   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16864 })
16865
16866 (define_expand "log2<mode>2"
16867   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16868    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16869   "TARGET_USE_FANCY_MATH_387
16870    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16871        || TARGET_MIX_SSE_I387)
16872    && flag_unsafe_math_optimizations"
16873 {
16874   rtx op0 = gen_reg_rtx (XFmode);
16875
16876   rtx op2 = gen_reg_rtx (XFmode);
16877   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16878
16879   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16880   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16881   DONE;
16882 })
16883
16884 (define_insn "fyl2xp1xf3_i387"
16885   [(set (match_operand:XF 0 "register_operand" "=f")
16886         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16887                     (match_operand:XF 2 "register_operand" "u")]
16888                    UNSPEC_FYL2XP1))
16889    (clobber (match_scratch:XF 3 "=2"))]
16890   "TARGET_USE_FANCY_MATH_387
16891    && flag_unsafe_math_optimizations"
16892   "fyl2xp1"
16893   [(set_attr "type" "fpspc")
16894    (set_attr "mode" "XF")])
16895
16896 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16897   [(set (match_operand:XF 0 "register_operand" "=f")
16898         (unspec:XF [(float_extend:XF
16899                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16900                     (match_operand:XF 2 "register_operand" "u")]
16901                    UNSPEC_FYL2XP1))
16902    (clobber (match_scratch:XF 3 "=2"))]
16903   "TARGET_USE_FANCY_MATH_387
16904    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16905        || TARGET_MIX_SSE_I387)
16906    && flag_unsafe_math_optimizations"
16907   "fyl2xp1"
16908   [(set_attr "type" "fpspc")
16909    (set_attr "mode" "XF")])
16910
16911 (define_expand "log1pxf2"
16912   [(use (match_operand:XF 0 "register_operand" ""))
16913    (use (match_operand:XF 1 "register_operand" ""))]
16914   "TARGET_USE_FANCY_MATH_387
16915    && flag_unsafe_math_optimizations && !optimize_size"
16916 {
16917   ix86_emit_i387_log1p (operands[0], operands[1]);
16918   DONE;
16919 })
16920
16921 (define_expand "log1p<mode>2"
16922   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16923    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16924   "TARGET_USE_FANCY_MATH_387
16925    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16926        || TARGET_MIX_SSE_I387)
16927    && flag_unsafe_math_optimizations && !optimize_size"
16928 {
16929   rtx op0 = gen_reg_rtx (XFmode);
16930
16931   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16932
16933   ix86_emit_i387_log1p (op0, operands[1]);
16934   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16935   DONE;
16936 })
16937
16938 (define_insn "fxtractxf3_i387"
16939   [(set (match_operand:XF 0 "register_operand" "=f")
16940         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16941                    UNSPEC_XTRACT_FRACT))
16942    (set (match_operand:XF 1 "register_operand" "=u")
16943         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16944   "TARGET_USE_FANCY_MATH_387
16945    && flag_unsafe_math_optimizations"
16946   "fxtract"
16947   [(set_attr "type" "fpspc")
16948    (set_attr "mode" "XF")])
16949
16950 (define_insn "fxtract_extend<mode>xf3_i387"
16951   [(set (match_operand:XF 0 "register_operand" "=f")
16952         (unspec:XF [(float_extend:XF
16953                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16954                    UNSPEC_XTRACT_FRACT))
16955    (set (match_operand:XF 1 "register_operand" "=u")
16956         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16957   "TARGET_USE_FANCY_MATH_387
16958    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16959        || TARGET_MIX_SSE_I387)
16960    && flag_unsafe_math_optimizations"
16961   "fxtract"
16962   [(set_attr "type" "fpspc")
16963    (set_attr "mode" "XF")])
16964
16965 (define_expand "logbxf2"
16966   [(parallel [(set (match_dup 2)
16967                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16968                               UNSPEC_XTRACT_FRACT))
16969               (set (match_operand:XF 0 "register_operand" "")
16970                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16971   "TARGET_USE_FANCY_MATH_387
16972    && flag_unsafe_math_optimizations"
16973 {
16974   operands[2] = gen_reg_rtx (XFmode);
16975 })
16976
16977 (define_expand "logb<mode>2"
16978   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16979    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16980   "TARGET_USE_FANCY_MATH_387
16981    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16982        || TARGET_MIX_SSE_I387)
16983    && flag_unsafe_math_optimizations"
16984 {
16985   rtx op0 = gen_reg_rtx (XFmode);
16986   rtx op1 = gen_reg_rtx (XFmode);
16987
16988   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16989   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16990   DONE;
16991 })
16992
16993 (define_expand "ilogbxf2"
16994   [(use (match_operand:SI 0 "register_operand" ""))
16995    (use (match_operand:XF 1 "register_operand" ""))]
16996   "TARGET_USE_FANCY_MATH_387
16997    && flag_unsafe_math_optimizations && !optimize_size"
16998 {
16999   rtx op0 = gen_reg_rtx (XFmode);
17000   rtx op1 = gen_reg_rtx (XFmode);
17001
17002   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17003   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17004   DONE;
17005 })
17006
17007 (define_expand "ilogb<mode>2"
17008   [(use (match_operand:SI 0 "register_operand" ""))
17009    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
17010   "TARGET_USE_FANCY_MATH_387
17011    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17012        || TARGET_MIX_SSE_I387)
17013    && flag_unsafe_math_optimizations && !optimize_size"
17014 {
17015   rtx op0 = gen_reg_rtx (XFmode);
17016   rtx op1 = gen_reg_rtx (XFmode);
17017
17018   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17019   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17020   DONE;
17021 })
17022
17023 (define_insn "*f2xm1xf2_i387"
17024   [(set (match_operand:XF 0 "register_operand" "=f")
17025         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17026                    UNSPEC_F2XM1))]
17027   "TARGET_USE_FANCY_MATH_387
17028    && flag_unsafe_math_optimizations"
17029   "f2xm1"
17030   [(set_attr "type" "fpspc")
17031    (set_attr "mode" "XF")])
17032
17033 (define_insn "*fscalexf4_i387"
17034   [(set (match_operand:XF 0 "register_operand" "=f")
17035         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17036                     (match_operand:XF 3 "register_operand" "1")]
17037                    UNSPEC_FSCALE_FRACT))
17038    (set (match_operand:XF 1 "register_operand" "=u")
17039         (unspec:XF [(match_dup 2) (match_dup 3)]
17040                    UNSPEC_FSCALE_EXP))]
17041   "TARGET_USE_FANCY_MATH_387
17042    && flag_unsafe_math_optimizations"
17043   "fscale"
17044   [(set_attr "type" "fpspc")
17045    (set_attr "mode" "XF")])
17046
17047 (define_expand "expNcorexf3"
17048   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17049                                (match_operand:XF 2 "register_operand" "")))
17050    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17051    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17052    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17053    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17054    (parallel [(set (match_operand:XF 0 "register_operand" "")
17055                    (unspec:XF [(match_dup 8) (match_dup 4)]
17056                               UNSPEC_FSCALE_FRACT))
17057               (set (match_dup 9)
17058                    (unspec:XF [(match_dup 8) (match_dup 4)]
17059                               UNSPEC_FSCALE_EXP))])]
17060   "TARGET_USE_FANCY_MATH_387
17061    && flag_unsafe_math_optimizations && !optimize_size"
17062 {
17063   int i;
17064
17065   for (i = 3; i < 10; i++)
17066     operands[i] = gen_reg_rtx (XFmode);
17067
17068   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17069 })
17070
17071 (define_expand "expxf2"
17072   [(use (match_operand:XF 0 "register_operand" ""))
17073    (use (match_operand:XF 1 "register_operand" ""))]
17074   "TARGET_USE_FANCY_MATH_387
17075    && flag_unsafe_math_optimizations && !optimize_size"
17076 {
17077   rtx op2 = gen_reg_rtx (XFmode);
17078   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17079
17080   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17081   DONE;
17082 })
17083
17084 (define_expand "exp<mode>2"
17085   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17086    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17087  "TARGET_USE_FANCY_MATH_387
17088    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17089        || TARGET_MIX_SSE_I387)
17090    && flag_unsafe_math_optimizations && !optimize_size"
17091 {
17092   rtx op0 = gen_reg_rtx (XFmode);
17093   rtx op1 = gen_reg_rtx (XFmode);
17094
17095   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17096   emit_insn (gen_expxf2 (op0, op1));
17097   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17098   DONE;
17099 })
17100
17101 (define_expand "exp10xf2"
17102   [(use (match_operand:XF 0 "register_operand" ""))
17103    (use (match_operand:XF 1 "register_operand" ""))]
17104   "TARGET_USE_FANCY_MATH_387
17105    && flag_unsafe_math_optimizations && !optimize_size"
17106 {
17107   rtx op2 = gen_reg_rtx (XFmode);
17108   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17109
17110   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17111   DONE;
17112 })
17113
17114 (define_expand "exp10<mode>2"
17115   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17116    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17117  "TARGET_USE_FANCY_MATH_387
17118    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17119        || TARGET_MIX_SSE_I387)
17120    && flag_unsafe_math_optimizations && !optimize_size"
17121 {
17122   rtx op0 = gen_reg_rtx (XFmode);
17123   rtx op1 = gen_reg_rtx (XFmode);
17124
17125   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17126   emit_insn (gen_exp10xf2 (op0, op1));
17127   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17128   DONE;
17129 })
17130
17131 (define_expand "exp2xf2"
17132   [(use (match_operand:XF 0 "register_operand" ""))
17133    (use (match_operand:XF 1 "register_operand" ""))]
17134   "TARGET_USE_FANCY_MATH_387
17135    && flag_unsafe_math_optimizations && !optimize_size"
17136 {
17137   rtx op2 = gen_reg_rtx (XFmode);
17138   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17139
17140   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17141   DONE;
17142 })
17143
17144 (define_expand "exp2<mode>2"
17145   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17146    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17147  "TARGET_USE_FANCY_MATH_387
17148    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17149        || TARGET_MIX_SSE_I387)
17150    && flag_unsafe_math_optimizations && !optimize_size"
17151 {
17152   rtx op0 = gen_reg_rtx (XFmode);
17153   rtx op1 = gen_reg_rtx (XFmode);
17154
17155   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17156   emit_insn (gen_exp2xf2 (op0, op1));
17157   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17158   DONE;
17159 })
17160
17161 (define_expand "expm1xf2"
17162   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17163                                (match_dup 2)))
17164    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17165    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17166    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17167    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17168    (parallel [(set (match_dup 7)
17169                    (unspec:XF [(match_dup 6) (match_dup 4)]
17170                               UNSPEC_FSCALE_FRACT))
17171               (set (match_dup 8)
17172                    (unspec:XF [(match_dup 6) (match_dup 4)]
17173                               UNSPEC_FSCALE_EXP))])
17174    (parallel [(set (match_dup 10)
17175                    (unspec:XF [(match_dup 9) (match_dup 8)]
17176                               UNSPEC_FSCALE_FRACT))
17177               (set (match_dup 11)
17178                    (unspec:XF [(match_dup 9) (match_dup 8)]
17179                               UNSPEC_FSCALE_EXP))])
17180    (set (match_dup 12) (minus:XF (match_dup 10)
17181                                  (float_extend:XF (match_dup 13))))
17182    (set (match_operand:XF 0 "register_operand" "")
17183         (plus:XF (match_dup 12) (match_dup 7)))]
17184   "TARGET_USE_FANCY_MATH_387
17185    && flag_unsafe_math_optimizations && !optimize_size"
17186 {
17187   int i;
17188
17189   for (i = 2; i < 13; i++)
17190     operands[i] = gen_reg_rtx (XFmode);
17191
17192   operands[13]
17193     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17194
17195   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17196 })
17197
17198 (define_expand "expm1<mode>2"
17199   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17200    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17201  "TARGET_USE_FANCY_MATH_387
17202    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17203        || TARGET_MIX_SSE_I387)
17204    && flag_unsafe_math_optimizations && !optimize_size"
17205 {
17206   rtx op0 = gen_reg_rtx (XFmode);
17207   rtx op1 = gen_reg_rtx (XFmode);
17208
17209   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17210   emit_insn (gen_expm1xf2 (op0, op1));
17211   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17212   DONE;
17213 })
17214
17215 (define_expand "ldexpxf3"
17216   [(set (match_dup 3)
17217         (float:XF (match_operand:SI 2 "register_operand" "")))
17218    (parallel [(set (match_operand:XF 0 " register_operand" "")
17219                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17220                                (match_dup 3)]
17221                               UNSPEC_FSCALE_FRACT))
17222               (set (match_dup 4)
17223                    (unspec:XF [(match_dup 1) (match_dup 3)]
17224                               UNSPEC_FSCALE_EXP))])]
17225   "TARGET_USE_FANCY_MATH_387
17226    && flag_unsafe_math_optimizations && !optimize_size"
17227 {
17228   operands[3] = gen_reg_rtx (XFmode);
17229   operands[4] = gen_reg_rtx (XFmode);
17230 })
17231
17232 (define_expand "ldexp<mode>3"
17233   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17234    (use (match_operand:X87MODEF12 1 "general_operand" ""))
17235    (use (match_operand:SI 2 "register_operand" ""))]
17236  "TARGET_USE_FANCY_MATH_387
17237    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17238        || TARGET_MIX_SSE_I387)
17239    && flag_unsafe_math_optimizations && !optimize_size"
17240 {
17241   rtx op0 = gen_reg_rtx (XFmode);
17242   rtx op1 = gen_reg_rtx (XFmode);
17243
17244   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17245   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17246   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17247   DONE;
17248 })
17249
17250 (define_expand "scalbxf3"
17251   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17252                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17253                                (match_operand:XF 2 "register_operand" "")]
17254                               UNSPEC_FSCALE_FRACT))
17255               (set (match_dup 3)
17256                    (unspec:XF [(match_dup 1) (match_dup 2)]
17257                               UNSPEC_FSCALE_EXP))])]
17258   "TARGET_USE_FANCY_MATH_387
17259    && flag_unsafe_math_optimizations && !optimize_size"
17260 {
17261   operands[3] = gen_reg_rtx (XFmode);
17262 })
17263
17264 (define_expand "scalb<mode>3"
17265   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17266    (use (match_operand:X87MODEF12 1 "general_operand" ""))
17267    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
17268  "TARGET_USE_FANCY_MATH_387
17269    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17270        || TARGET_MIX_SSE_I387)
17271    && flag_unsafe_math_optimizations && !optimize_size"
17272 {
17273   rtx op0 = gen_reg_rtx (XFmode);
17274   rtx op1 = gen_reg_rtx (XFmode);
17275   rtx op2 = gen_reg_rtx (XFmode);
17276
17277   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17278   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17279   emit_insn (gen_scalbxf3 (op0, op1, op2));
17280   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17281   DONE;
17282 })
17283 \f
17284
17285 (define_insn "rintxf2"
17286   [(set (match_operand:XF 0 "register_operand" "=f")
17287         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17288                    UNSPEC_FRNDINT))]
17289   "TARGET_USE_FANCY_MATH_387
17290    && flag_unsafe_math_optimizations"
17291   "frndint"
17292   [(set_attr "type" "fpspc")
17293    (set_attr "mode" "XF")])
17294
17295 (define_expand "rint<mode>2"
17296   [(use (match_operand:SSEMODEF 0 "register_operand" ""))
17297    (use (match_operand:SSEMODEF 1 "register_operand" ""))]
17298   "(TARGET_USE_FANCY_MATH_387
17299     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17300         || TARGET_MIX_SSE_I387)
17301     && flag_unsafe_math_optimizations)
17302    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17303        && !flag_trapping_math
17304        && !optimize_size)"
17305 {
17306   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17307       && !flag_trapping_math
17308       && !optimize_size)
17309     ix86_expand_rint (operand0, operand1);
17310   else
17311     {
17312       rtx op0 = gen_reg_rtx (XFmode);
17313       rtx op1 = gen_reg_rtx (XFmode);
17314
17315       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17316       emit_insn (gen_rintxf2 (op0, op1));
17317
17318       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17319     }
17320   DONE;
17321 })
17322
17323 (define_expand "round<mode>2"
17324   [(match_operand:SSEMODEF 0 "register_operand" "")
17325    (match_operand:SSEMODEF 1 "nonimmediate_operand" "")]
17326   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17327    && !flag_trapping_math && !flag_rounding_math
17328    && !optimize_size"
17329 {
17330   if ((<MODE>mode != DFmode) || TARGET_64BIT)
17331     ix86_expand_round (operand0, operand1);
17332   else
17333     ix86_expand_rounddf_32 (operand0, operand1);
17334   DONE;
17335 })
17336
17337 (define_insn_and_split "*fistdi2_1"
17338   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17339         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17340                    UNSPEC_FIST))]
17341   "TARGET_USE_FANCY_MATH_387
17342    && !(reload_completed || reload_in_progress)"
17343   "#"
17344   "&& 1"
17345   [(const_int 0)]
17346 {
17347   if (memory_operand (operands[0], VOIDmode))
17348     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17349   else
17350     {
17351       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17352       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17353                                          operands[2]));
17354     }
17355   DONE;
17356 }
17357   [(set_attr "type" "fpspc")
17358    (set_attr "mode" "DI")])
17359
17360 (define_insn "fistdi2"
17361   [(set (match_operand:DI 0 "memory_operand" "=m")
17362         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17363                    UNSPEC_FIST))
17364    (clobber (match_scratch:XF 2 "=&1f"))]
17365   "TARGET_USE_FANCY_MATH_387"
17366   "* return output_fix_trunc (insn, operands, 0);"
17367   [(set_attr "type" "fpspc")
17368    (set_attr "mode" "DI")])
17369
17370 (define_insn "fistdi2_with_temp"
17371   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17372         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17373                    UNSPEC_FIST))
17374    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17375    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17376   "TARGET_USE_FANCY_MATH_387"
17377   "#"
17378   [(set_attr "type" "fpspc")
17379    (set_attr "mode" "DI")])
17380
17381 (define_split
17382   [(set (match_operand:DI 0 "register_operand" "")
17383         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17384                    UNSPEC_FIST))
17385    (clobber (match_operand:DI 2 "memory_operand" ""))
17386    (clobber (match_scratch 3 ""))]
17387   "reload_completed"
17388   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17389               (clobber (match_dup 3))])
17390    (set (match_dup 0) (match_dup 2))]
17391   "")
17392
17393 (define_split
17394   [(set (match_operand:DI 0 "memory_operand" "")
17395         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17396                    UNSPEC_FIST))
17397    (clobber (match_operand:DI 2 "memory_operand" ""))
17398    (clobber (match_scratch 3 ""))]
17399   "reload_completed"
17400   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17401               (clobber (match_dup 3))])]
17402   "")
17403
17404 (define_insn_and_split "*fist<mode>2_1"
17405   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17406         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17407                            UNSPEC_FIST))]
17408   "TARGET_USE_FANCY_MATH_387
17409    && !(reload_completed || reload_in_progress)"
17410   "#"
17411   "&& 1"
17412   [(const_int 0)]
17413 {
17414   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17415   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17416                                         operands[2]));
17417   DONE;
17418 }
17419   [(set_attr "type" "fpspc")
17420    (set_attr "mode" "<MODE>")])
17421
17422 (define_insn "fist<mode>2"
17423   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17424         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17425                            UNSPEC_FIST))]
17426   "TARGET_USE_FANCY_MATH_387"
17427   "* return output_fix_trunc (insn, operands, 0);"
17428   [(set_attr "type" "fpspc")
17429    (set_attr "mode" "<MODE>")])
17430
17431 (define_insn "fist<mode>2_with_temp"
17432   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17433         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17434                            UNSPEC_FIST))
17435    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17436   "TARGET_USE_FANCY_MATH_387"
17437   "#"
17438   [(set_attr "type" "fpspc")
17439    (set_attr "mode" "<MODE>")])
17440
17441 (define_split
17442   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17443         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17444                            UNSPEC_FIST))
17445    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17446   "reload_completed"
17447   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17448    (set (match_dup 0) (match_dup 2))]
17449   "")
17450
17451 (define_split
17452   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17453         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17454                            UNSPEC_FIST))
17455    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17456   "reload_completed"
17457   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17458   "")
17459
17460 (define_expand "lrintxf<mode>2"
17461   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17462      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17463                       UNSPEC_FIST))]
17464   "TARGET_USE_FANCY_MATH_387"
17465   "")
17466
17467 (define_expand "lrint<SSEMODEF:mode><SSEMODEI24:mode>2"
17468   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17469      (unspec:SSEMODEI24 [(match_operand:SSEMODEF 1 "register_operand" "")]
17470                         UNSPEC_FIX_NOTRUNC))]
17471   "SSE_FLOAT_MODE_P (<SSEMODEF:MODE>mode) && TARGET_SSE_MATH
17472    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17473   "")
17474
17475 (define_expand "lround<SSEMODEF:mode><SSEMODEI24:mode>2"
17476   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17477    (match_operand:SSEMODEF 1 "register_operand" "")]
17478   "SSE_FLOAT_MODE_P (<SSEMODEF:MODE>mode) && TARGET_SSE_MATH
17479    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17480    && !flag_trapping_math && !flag_rounding_math
17481    && !optimize_size"
17482 {
17483   ix86_expand_lround (operand0, operand1);
17484   DONE;
17485 })
17486
17487 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17488 (define_insn_and_split "frndintxf2_floor"
17489   [(set (match_operand:XF 0 "register_operand" "=f")
17490         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17491          UNSPEC_FRNDINT_FLOOR))
17492    (clobber (reg:CC FLAGS_REG))]
17493   "TARGET_USE_FANCY_MATH_387
17494    && flag_unsafe_math_optimizations
17495    && !(reload_completed || reload_in_progress)"
17496   "#"
17497   "&& 1"
17498   [(const_int 0)]
17499 {
17500   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17501
17502   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17503   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17504
17505   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17506                                         operands[2], operands[3]));
17507   DONE;
17508 }
17509   [(set_attr "type" "frndint")
17510    (set_attr "i387_cw" "floor")
17511    (set_attr "mode" "XF")])
17512
17513 (define_insn "frndintxf2_floor_i387"
17514   [(set (match_operand:XF 0 "register_operand" "=f")
17515         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17516          UNSPEC_FRNDINT_FLOOR))
17517    (use (match_operand:HI 2 "memory_operand" "m"))
17518    (use (match_operand:HI 3 "memory_operand" "m"))]
17519   "TARGET_USE_FANCY_MATH_387
17520    && flag_unsafe_math_optimizations"
17521   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17522   [(set_attr "type" "frndint")
17523    (set_attr "i387_cw" "floor")
17524    (set_attr "mode" "XF")])
17525
17526 (define_expand "floorxf2"
17527   [(use (match_operand:XF 0 "register_operand" ""))
17528    (use (match_operand:XF 1 "register_operand" ""))]
17529   "TARGET_USE_FANCY_MATH_387
17530    && flag_unsafe_math_optimizations && !optimize_size"
17531 {
17532   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17533   DONE;
17534 })
17535
17536 (define_expand "floordf2"
17537   [(use (match_operand:DF 0 "register_operand" ""))
17538    (use (match_operand:DF 1 "register_operand" ""))]
17539   "((TARGET_USE_FANCY_MATH_387
17540      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17541      && flag_unsafe_math_optimizations)
17542     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17543         && !flag_trapping_math))
17544    && !optimize_size"
17545 {
17546   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17547       && !flag_trapping_math)
17548     {
17549       if (TARGET_64BIT)
17550         ix86_expand_floorceil (operand0, operand1, true);
17551       else
17552         ix86_expand_floorceildf_32 (operand0, operand1, true);
17553     }
17554   else
17555     {
17556       rtx op0 = gen_reg_rtx (XFmode);
17557       rtx op1 = gen_reg_rtx (XFmode);
17558
17559       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17560       emit_insn (gen_frndintxf2_floor (op0, op1));
17561
17562       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17563     }
17564   DONE;
17565 })
17566
17567 (define_expand "floorsf2"
17568   [(use (match_operand:SF 0 "register_operand" ""))
17569    (use (match_operand:SF 1 "register_operand" ""))]
17570   "((TARGET_USE_FANCY_MATH_387
17571      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17572      && flag_unsafe_math_optimizations)
17573     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17574         && !flag_trapping_math))
17575    && !optimize_size"
17576 {
17577   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17578       && !flag_trapping_math)
17579     ix86_expand_floorceil (operand0, operand1, true);
17580   else
17581     {
17582       rtx op0 = gen_reg_rtx (XFmode);
17583       rtx op1 = gen_reg_rtx (XFmode);
17584
17585       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17586       emit_insn (gen_frndintxf2_floor (op0, op1));
17587
17588       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17589     }
17590   DONE;
17591 })
17592
17593 (define_insn_and_split "*fist<mode>2_floor_1"
17594   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17595         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17596          UNSPEC_FIST_FLOOR))
17597    (clobber (reg:CC FLAGS_REG))]
17598   "TARGET_USE_FANCY_MATH_387
17599    && flag_unsafe_math_optimizations
17600    && !(reload_completed || reload_in_progress)"
17601   "#"
17602   "&& 1"
17603   [(const_int 0)]
17604 {
17605   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17606
17607   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17608   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17609   if (memory_operand (operands[0], VOIDmode))
17610     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17611                                       operands[2], operands[3]));
17612   else
17613     {
17614       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17615       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17616                                                   operands[2], operands[3],
17617                                                   operands[4]));
17618     }
17619   DONE;
17620 }
17621   [(set_attr "type" "fistp")
17622    (set_attr "i387_cw" "floor")
17623    (set_attr "mode" "<MODE>")])
17624
17625 (define_insn "fistdi2_floor"
17626   [(set (match_operand:DI 0 "memory_operand" "=m")
17627         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17628          UNSPEC_FIST_FLOOR))
17629    (use (match_operand:HI 2 "memory_operand" "m"))
17630    (use (match_operand:HI 3 "memory_operand" "m"))
17631    (clobber (match_scratch:XF 4 "=&1f"))]
17632   "TARGET_USE_FANCY_MATH_387
17633    && flag_unsafe_math_optimizations"
17634   "* return output_fix_trunc (insn, operands, 0);"
17635   [(set_attr "type" "fistp")
17636    (set_attr "i387_cw" "floor")
17637    (set_attr "mode" "DI")])
17638
17639 (define_insn "fistdi2_floor_with_temp"
17640   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17641         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17642          UNSPEC_FIST_FLOOR))
17643    (use (match_operand:HI 2 "memory_operand" "m,m"))
17644    (use (match_operand:HI 3 "memory_operand" "m,m"))
17645    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17646    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17647   "TARGET_USE_FANCY_MATH_387
17648    && flag_unsafe_math_optimizations"
17649   "#"
17650   [(set_attr "type" "fistp")
17651    (set_attr "i387_cw" "floor")
17652    (set_attr "mode" "DI")])
17653
17654 (define_split
17655   [(set (match_operand:DI 0 "register_operand" "")
17656         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17657          UNSPEC_FIST_FLOOR))
17658    (use (match_operand:HI 2 "memory_operand" ""))
17659    (use (match_operand:HI 3 "memory_operand" ""))
17660    (clobber (match_operand:DI 4 "memory_operand" ""))
17661    (clobber (match_scratch 5 ""))]
17662   "reload_completed"
17663   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17664               (use (match_dup 2))
17665               (use (match_dup 3))
17666               (clobber (match_dup 5))])
17667    (set (match_dup 0) (match_dup 4))]
17668   "")
17669
17670 (define_split
17671   [(set (match_operand:DI 0 "memory_operand" "")
17672         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17673          UNSPEC_FIST_FLOOR))
17674    (use (match_operand:HI 2 "memory_operand" ""))
17675    (use (match_operand:HI 3 "memory_operand" ""))
17676    (clobber (match_operand:DI 4 "memory_operand" ""))
17677    (clobber (match_scratch 5 ""))]
17678   "reload_completed"
17679   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17680               (use (match_dup 2))
17681               (use (match_dup 3))
17682               (clobber (match_dup 5))])]
17683   "")
17684
17685 (define_insn "fist<mode>2_floor"
17686   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17687         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17688          UNSPEC_FIST_FLOOR))
17689    (use (match_operand:HI 2 "memory_operand" "m"))
17690    (use (match_operand:HI 3 "memory_operand" "m"))]
17691   "TARGET_USE_FANCY_MATH_387
17692    && flag_unsafe_math_optimizations"
17693   "* return output_fix_trunc (insn, operands, 0);"
17694   [(set_attr "type" "fistp")
17695    (set_attr "i387_cw" "floor")
17696    (set_attr "mode" "<MODE>")])
17697
17698 (define_insn "fist<mode>2_floor_with_temp"
17699   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17700         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17701          UNSPEC_FIST_FLOOR))
17702    (use (match_operand:HI 2 "memory_operand" "m,m"))
17703    (use (match_operand:HI 3 "memory_operand" "m,m"))
17704    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17705   "TARGET_USE_FANCY_MATH_387
17706    && flag_unsafe_math_optimizations"
17707   "#"
17708   [(set_attr "type" "fistp")
17709    (set_attr "i387_cw" "floor")
17710    (set_attr "mode" "<MODE>")])
17711
17712 (define_split
17713   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17714         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17715          UNSPEC_FIST_FLOOR))
17716    (use (match_operand:HI 2 "memory_operand" ""))
17717    (use (match_operand:HI 3 "memory_operand" ""))
17718    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17719   "reload_completed"
17720   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17721                                   UNSPEC_FIST_FLOOR))
17722               (use (match_dup 2))
17723               (use (match_dup 3))])
17724    (set (match_dup 0) (match_dup 4))]
17725   "")
17726
17727 (define_split
17728   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17729         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17730          UNSPEC_FIST_FLOOR))
17731    (use (match_operand:HI 2 "memory_operand" ""))
17732    (use (match_operand:HI 3 "memory_operand" ""))
17733    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17734   "reload_completed"
17735   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17736                                   UNSPEC_FIST_FLOOR))
17737               (use (match_dup 2))
17738               (use (match_dup 3))])]
17739   "")
17740
17741 (define_expand "lfloorxf<mode>2"
17742   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17743                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17744                     UNSPEC_FIST_FLOOR))
17745               (clobber (reg:CC FLAGS_REG))])]
17746   "TARGET_USE_FANCY_MATH_387
17747    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17748    && flag_unsafe_math_optimizations"
17749   "")
17750
17751 (define_expand "lfloor<mode>di2"
17752   [(match_operand:DI 0 "nonimmediate_operand" "")
17753    (match_operand:SSEMODEF 1 "register_operand" "")]
17754   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17755    && !flag_trapping_math
17756    && !optimize_size"
17757 {
17758   ix86_expand_lfloorceil (operand0, operand1, true);
17759   DONE;
17760 })
17761
17762 (define_expand "lfloor<mode>si2"
17763   [(match_operand:SI 0 "nonimmediate_operand" "")
17764    (match_operand:SSEMODEF 1 "register_operand" "")]
17765   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17766    && !flag_trapping_math
17767    && (!optimize_size || !TARGET_64BIT)"
17768 {
17769   ix86_expand_lfloorceil (operand0, operand1, true);
17770   DONE;
17771 })
17772
17773 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17774 (define_insn_and_split "frndintxf2_ceil"
17775   [(set (match_operand:XF 0 "register_operand" "=f")
17776         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17777          UNSPEC_FRNDINT_CEIL))
17778    (clobber (reg:CC FLAGS_REG))]
17779   "TARGET_USE_FANCY_MATH_387
17780    && flag_unsafe_math_optimizations
17781    && !(reload_completed || reload_in_progress)"
17782   "#"
17783   "&& 1"
17784   [(const_int 0)]
17785 {
17786   ix86_optimize_mode_switching[I387_CEIL] = 1;
17787
17788   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17789   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17790
17791   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17792                                        operands[2], operands[3]));
17793   DONE;
17794 }
17795   [(set_attr "type" "frndint")
17796    (set_attr "i387_cw" "ceil")
17797    (set_attr "mode" "XF")])
17798
17799 (define_insn "frndintxf2_ceil_i387"
17800   [(set (match_operand:XF 0 "register_operand" "=f")
17801         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17802          UNSPEC_FRNDINT_CEIL))
17803    (use (match_operand:HI 2 "memory_operand" "m"))
17804    (use (match_operand:HI 3 "memory_operand" "m"))]
17805   "TARGET_USE_FANCY_MATH_387
17806    && flag_unsafe_math_optimizations"
17807   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17808   [(set_attr "type" "frndint")
17809    (set_attr "i387_cw" "ceil")
17810    (set_attr "mode" "XF")])
17811
17812 (define_expand "ceilxf2"
17813   [(use (match_operand:XF 0 "register_operand" ""))
17814    (use (match_operand:XF 1 "register_operand" ""))]
17815   "TARGET_USE_FANCY_MATH_387
17816    && flag_unsafe_math_optimizations && !optimize_size"
17817 {
17818   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17819   DONE;
17820 })
17821
17822 (define_expand "ceildf2"
17823   [(use (match_operand:DF 0 "register_operand" ""))
17824    (use (match_operand:DF 1 "register_operand" ""))]
17825   "((TARGET_USE_FANCY_MATH_387
17826      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17827      && flag_unsafe_math_optimizations)
17828     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17829         && !flag_trapping_math))
17830    && !optimize_size"
17831 {
17832   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17833       && !flag_trapping_math)
17834     {
17835       if (TARGET_64BIT)
17836         ix86_expand_floorceil (operand0, operand1, false);
17837       else
17838         ix86_expand_floorceildf_32 (operand0, operand1, false);
17839     }
17840   else
17841     {
17842       rtx op0 = gen_reg_rtx (XFmode);
17843       rtx op1 = gen_reg_rtx (XFmode);
17844
17845       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17846       emit_insn (gen_frndintxf2_ceil (op0, op1));
17847
17848       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17849     }
17850   DONE;
17851 })
17852
17853 (define_expand "ceilsf2"
17854   [(use (match_operand:SF 0 "register_operand" ""))
17855    (use (match_operand:SF 1 "register_operand" ""))]
17856   "((TARGET_USE_FANCY_MATH_387
17857      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17858      && flag_unsafe_math_optimizations)
17859     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17860         && !flag_trapping_math))
17861    && !optimize_size"
17862 {
17863   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17864       && !flag_trapping_math)
17865     ix86_expand_floorceil (operand0, operand1, false);
17866   else
17867     {
17868       rtx op0 = gen_reg_rtx (XFmode);
17869       rtx op1 = gen_reg_rtx (XFmode);
17870
17871       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17872       emit_insn (gen_frndintxf2_ceil (op0, op1));
17873
17874       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17875     }
17876   DONE;
17877 })
17878
17879 (define_insn_and_split "*fist<mode>2_ceil_1"
17880   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17881         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17882          UNSPEC_FIST_CEIL))
17883    (clobber (reg:CC FLAGS_REG))]
17884   "TARGET_USE_FANCY_MATH_387
17885    && flag_unsafe_math_optimizations
17886    && !(reload_completed || reload_in_progress)"
17887   "#"
17888   "&& 1"
17889   [(const_int 0)]
17890 {
17891   ix86_optimize_mode_switching[I387_CEIL] = 1;
17892
17893   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17894   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17895   if (memory_operand (operands[0], VOIDmode))
17896     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17897                                      operands[2], operands[3]));
17898   else
17899     {
17900       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17901       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17902                                                  operands[2], operands[3],
17903                                                  operands[4]));
17904     }
17905   DONE;
17906 }
17907   [(set_attr "type" "fistp")
17908    (set_attr "i387_cw" "ceil")
17909    (set_attr "mode" "<MODE>")])
17910
17911 (define_insn "fistdi2_ceil"
17912   [(set (match_operand:DI 0 "memory_operand" "=m")
17913         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17914          UNSPEC_FIST_CEIL))
17915    (use (match_operand:HI 2 "memory_operand" "m"))
17916    (use (match_operand:HI 3 "memory_operand" "m"))
17917    (clobber (match_scratch:XF 4 "=&1f"))]
17918   "TARGET_USE_FANCY_MATH_387
17919    && flag_unsafe_math_optimizations"
17920   "* return output_fix_trunc (insn, operands, 0);"
17921   [(set_attr "type" "fistp")
17922    (set_attr "i387_cw" "ceil")
17923    (set_attr "mode" "DI")])
17924
17925 (define_insn "fistdi2_ceil_with_temp"
17926   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17927         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17928          UNSPEC_FIST_CEIL))
17929    (use (match_operand:HI 2 "memory_operand" "m,m"))
17930    (use (match_operand:HI 3 "memory_operand" "m,m"))
17931    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17932    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17933   "TARGET_USE_FANCY_MATH_387
17934    && flag_unsafe_math_optimizations"
17935   "#"
17936   [(set_attr "type" "fistp")
17937    (set_attr "i387_cw" "ceil")
17938    (set_attr "mode" "DI")])
17939
17940 (define_split
17941   [(set (match_operand:DI 0 "register_operand" "")
17942         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17943          UNSPEC_FIST_CEIL))
17944    (use (match_operand:HI 2 "memory_operand" ""))
17945    (use (match_operand:HI 3 "memory_operand" ""))
17946    (clobber (match_operand:DI 4 "memory_operand" ""))
17947    (clobber (match_scratch 5 ""))]
17948   "reload_completed"
17949   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17950               (use (match_dup 2))
17951               (use (match_dup 3))
17952               (clobber (match_dup 5))])
17953    (set (match_dup 0) (match_dup 4))]
17954   "")
17955
17956 (define_split
17957   [(set (match_operand:DI 0 "memory_operand" "")
17958         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17959          UNSPEC_FIST_CEIL))
17960    (use (match_operand:HI 2 "memory_operand" ""))
17961    (use (match_operand:HI 3 "memory_operand" ""))
17962    (clobber (match_operand:DI 4 "memory_operand" ""))
17963    (clobber (match_scratch 5 ""))]
17964   "reload_completed"
17965   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17966               (use (match_dup 2))
17967               (use (match_dup 3))
17968               (clobber (match_dup 5))])]
17969   "")
17970
17971 (define_insn "fist<mode>2_ceil"
17972   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17973         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17974          UNSPEC_FIST_CEIL))
17975    (use (match_operand:HI 2 "memory_operand" "m"))
17976    (use (match_operand:HI 3 "memory_operand" "m"))]
17977   "TARGET_USE_FANCY_MATH_387
17978    && flag_unsafe_math_optimizations"
17979   "* return output_fix_trunc (insn, operands, 0);"
17980   [(set_attr "type" "fistp")
17981    (set_attr "i387_cw" "ceil")
17982    (set_attr "mode" "<MODE>")])
17983
17984 (define_insn "fist<mode>2_ceil_with_temp"
17985   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17986         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17987          UNSPEC_FIST_CEIL))
17988    (use (match_operand:HI 2 "memory_operand" "m,m"))
17989    (use (match_operand:HI 3 "memory_operand" "m,m"))
17990    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17991   "TARGET_USE_FANCY_MATH_387
17992    && flag_unsafe_math_optimizations"
17993   "#"
17994   [(set_attr "type" "fistp")
17995    (set_attr "i387_cw" "ceil")
17996    (set_attr "mode" "<MODE>")])
17997
17998 (define_split
17999   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18000         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18001          UNSPEC_FIST_CEIL))
18002    (use (match_operand:HI 2 "memory_operand" ""))
18003    (use (match_operand:HI 3 "memory_operand" ""))
18004    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18005   "reload_completed"
18006   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18007                                   UNSPEC_FIST_CEIL))
18008               (use (match_dup 2))
18009               (use (match_dup 3))])
18010    (set (match_dup 0) (match_dup 4))]
18011   "")
18012
18013 (define_split
18014   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18015         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18016          UNSPEC_FIST_CEIL))
18017    (use (match_operand:HI 2 "memory_operand" ""))
18018    (use (match_operand:HI 3 "memory_operand" ""))
18019    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18020   "reload_completed"
18021   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18022                                   UNSPEC_FIST_CEIL))
18023               (use (match_dup 2))
18024               (use (match_dup 3))])]
18025   "")
18026
18027 (define_expand "lceilxf<mode>2"
18028   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18029                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18030                     UNSPEC_FIST_CEIL))
18031               (clobber (reg:CC FLAGS_REG))])]
18032   "TARGET_USE_FANCY_MATH_387
18033    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18034    && flag_unsafe_math_optimizations"
18035   "")
18036
18037 (define_expand "lceil<mode>di2"
18038   [(match_operand:DI 0 "nonimmediate_operand" "")
18039    (match_operand:SSEMODEF 1 "register_operand" "")]
18040   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18041    && !flag_trapping_math"
18042 {
18043   ix86_expand_lfloorceil (operand0, operand1, false);
18044   DONE;
18045 })
18046
18047 (define_expand "lceil<mode>si2"
18048   [(match_operand:SI 0 "nonimmediate_operand" "")
18049    (match_operand:SSEMODEF 1 "register_operand" "")]
18050   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18051    && !flag_trapping_math"
18052 {
18053   ix86_expand_lfloorceil (operand0, operand1, false);
18054   DONE;
18055 })
18056
18057 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18058 (define_insn_and_split "frndintxf2_trunc"
18059   [(set (match_operand:XF 0 "register_operand" "=f")
18060         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18061          UNSPEC_FRNDINT_TRUNC))
18062    (clobber (reg:CC FLAGS_REG))]
18063   "TARGET_USE_FANCY_MATH_387
18064    && flag_unsafe_math_optimizations
18065    && !(reload_completed || reload_in_progress)"
18066   "#"
18067   "&& 1"
18068   [(const_int 0)]
18069 {
18070   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18071
18072   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18073   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18074
18075   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18076                                         operands[2], operands[3]));
18077   DONE;
18078 }
18079   [(set_attr "type" "frndint")
18080    (set_attr "i387_cw" "trunc")
18081    (set_attr "mode" "XF")])
18082
18083 (define_insn "frndintxf2_trunc_i387"
18084   [(set (match_operand:XF 0 "register_operand" "=f")
18085         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18086          UNSPEC_FRNDINT_TRUNC))
18087    (use (match_operand:HI 2 "memory_operand" "m"))
18088    (use (match_operand:HI 3 "memory_operand" "m"))]
18089   "TARGET_USE_FANCY_MATH_387
18090    && flag_unsafe_math_optimizations"
18091   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18092   [(set_attr "type" "frndint")
18093    (set_attr "i387_cw" "trunc")
18094    (set_attr "mode" "XF")])
18095
18096 (define_expand "btruncxf2"
18097   [(use (match_operand:XF 0 "register_operand" ""))
18098    (use (match_operand:XF 1 "register_operand" ""))]
18099   "TARGET_USE_FANCY_MATH_387
18100    && flag_unsafe_math_optimizations && !optimize_size"
18101 {
18102   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18103   DONE;
18104 })
18105
18106 (define_expand "btruncdf2"
18107   [(use (match_operand:DF 0 "register_operand" ""))
18108    (use (match_operand:DF 1 "register_operand" ""))]
18109   "((TARGET_USE_FANCY_MATH_387
18110      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18111      && flag_unsafe_math_optimizations)
18112     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18113         && !flag_trapping_math))
18114    && !optimize_size"
18115 {
18116   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18117       && !flag_trapping_math)
18118     {
18119       if (TARGET_64BIT)
18120         ix86_expand_trunc (operand0, operand1);
18121       else
18122         ix86_expand_truncdf_32 (operand0, operand1);
18123     }
18124   else
18125     {
18126       rtx op0 = gen_reg_rtx (XFmode);
18127       rtx op1 = gen_reg_rtx (XFmode);
18128
18129       emit_insn (gen_extenddfxf2 (op1, operands[1]));
18130       emit_insn (gen_frndintxf2_trunc (op0, op1));
18131
18132       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18133     }
18134   DONE;
18135 })
18136
18137 (define_expand "btruncsf2"
18138   [(use (match_operand:SF 0 "register_operand" ""))
18139    (use (match_operand:SF 1 "register_operand" ""))]
18140   "((TARGET_USE_FANCY_MATH_387
18141      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18142      && flag_unsafe_math_optimizations)
18143     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18144         && !flag_trapping_math))
18145    && !optimize_size"
18146 {
18147   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18148       && !flag_trapping_math)
18149     ix86_expand_trunc (operand0, operand1);
18150   else
18151     {
18152       rtx op0 = gen_reg_rtx (XFmode);
18153       rtx op1 = gen_reg_rtx (XFmode);
18154
18155       emit_insn (gen_extendsfxf2 (op1, operands[1]));
18156       emit_insn (gen_frndintxf2_trunc (op0, op1));
18157
18158       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18159     }
18160   DONE;
18161 })
18162
18163 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18164 (define_insn_and_split "frndintxf2_mask_pm"
18165   [(set (match_operand:XF 0 "register_operand" "=f")
18166         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18167          UNSPEC_FRNDINT_MASK_PM))
18168    (clobber (reg:CC FLAGS_REG))]
18169   "TARGET_USE_FANCY_MATH_387
18170    && flag_unsafe_math_optimizations
18171    && !(reload_completed || reload_in_progress)"
18172   "#"
18173   "&& 1"
18174   [(const_int 0)]
18175 {
18176   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18177
18178   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18179   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18180
18181   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18182                                           operands[2], operands[3]));
18183   DONE;
18184 }
18185   [(set_attr "type" "frndint")
18186    (set_attr "i387_cw" "mask_pm")
18187    (set_attr "mode" "XF")])
18188
18189 (define_insn "frndintxf2_mask_pm_i387"
18190   [(set (match_operand:XF 0 "register_operand" "=f")
18191         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18192          UNSPEC_FRNDINT_MASK_PM))
18193    (use (match_operand:HI 2 "memory_operand" "m"))
18194    (use (match_operand:HI 3 "memory_operand" "m"))]
18195   "TARGET_USE_FANCY_MATH_387
18196    && flag_unsafe_math_optimizations"
18197   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18198   [(set_attr "type" "frndint")
18199    (set_attr "i387_cw" "mask_pm")
18200    (set_attr "mode" "XF")])
18201
18202 (define_expand "nearbyintxf2"
18203   [(use (match_operand:XF 0 "register_operand" ""))
18204    (use (match_operand:XF 1 "register_operand" ""))]
18205   "TARGET_USE_FANCY_MATH_387
18206    && flag_unsafe_math_optimizations"
18207 {
18208   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18209
18210   DONE;
18211 })
18212
18213 (define_expand "nearbyintdf2"
18214   [(use (match_operand:DF 0 "register_operand" ""))
18215    (use (match_operand:DF 1 "register_operand" ""))]
18216   "TARGET_USE_FANCY_MATH_387
18217    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18218    && flag_unsafe_math_optimizations"
18219 {
18220   rtx op0 = gen_reg_rtx (XFmode);
18221   rtx op1 = gen_reg_rtx (XFmode);
18222
18223   emit_insn (gen_extenddfxf2 (op1, operands[1]));
18224   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18225
18226   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18227   DONE;
18228 })
18229
18230 (define_expand "nearbyintsf2"
18231   [(use (match_operand:SF 0 "register_operand" ""))
18232    (use (match_operand:SF 1 "register_operand" ""))]
18233   "TARGET_USE_FANCY_MATH_387
18234    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18235    && flag_unsafe_math_optimizations"
18236 {
18237   rtx op0 = gen_reg_rtx (XFmode);
18238   rtx op1 = gen_reg_rtx (XFmode);
18239
18240   emit_insn (gen_extendsfxf2 (op1, operands[1]));
18241   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18242
18243   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18244   DONE;
18245 })
18246
18247 (define_insn "fxam<mode>2_i387"
18248   [(set (match_operand:HI 0 "register_operand" "=a")
18249         (unspec:HI
18250           [(match_operand:X87MODEF 1 "register_operand" "f")]
18251           UNSPEC_FXAM))]
18252   "TARGET_USE_FANCY_MATH_387"
18253   "fxam\n\tfnstsw\t%0"
18254   [(set_attr "type" "multi")
18255    (set_attr "unit" "i387")
18256    (set_attr "mode" "<MODE>")])
18257
18258 (define_expand "isinf<mode>2"
18259   [(use (match_operand:SI 0 "register_operand" ""))
18260    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18261   "TARGET_USE_FANCY_MATH_387
18262   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18263       || TARGET_MIX_SSE_I387)"
18264 {
18265   rtx mask = GEN_INT (0x45);
18266   rtx val = GEN_INT (0x05);
18267
18268   rtx cond;
18269
18270   rtx scratch = gen_reg_rtx (HImode);
18271   rtx res = gen_reg_rtx (QImode);
18272
18273   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18274   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18275   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18276   cond = gen_rtx_fmt_ee (EQ, QImode,
18277                          gen_rtx_REG (CCmode, FLAGS_REG),
18278                          const0_rtx);
18279   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18280   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18281   DONE;
18282 })
18283
18284 \f
18285 ;; Block operation instructions
18286
18287 (define_expand "movmemsi"
18288   [(use (match_operand:BLK 0 "memory_operand" ""))
18289    (use (match_operand:BLK 1 "memory_operand" ""))
18290    (use (match_operand:SI 2 "nonmemory_operand" ""))
18291    (use (match_operand:SI 3 "const_int_operand" ""))
18292    (use (match_operand:SI 4 "const_int_operand" ""))
18293    (use (match_operand:SI 5 "const_int_operand" ""))]
18294   ""
18295 {
18296  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18297                          operands[4], operands[5]))
18298    DONE;
18299  else
18300    FAIL;
18301 })
18302
18303 (define_expand "movmemdi"
18304   [(use (match_operand:BLK 0 "memory_operand" ""))
18305    (use (match_operand:BLK 1 "memory_operand" ""))
18306    (use (match_operand:DI 2 "nonmemory_operand" ""))
18307    (use (match_operand:DI 3 "const_int_operand" ""))
18308    (use (match_operand:SI 4 "const_int_operand" ""))
18309    (use (match_operand:SI 5 "const_int_operand" ""))]
18310   "TARGET_64BIT"
18311 {
18312  if (ix86_expand_movmem (operands[0], operands[1], 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 "strmov"
18323   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18324    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18325    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18326               (clobber (reg:CC FLAGS_REG))])
18327    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18328               (clobber (reg:CC FLAGS_REG))])]
18329   ""
18330 {
18331   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18332
18333   /* If .md ever supports :P for Pmode, these can be directly
18334      in the pattern above.  */
18335   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18336   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18337
18338   if (TARGET_SINGLE_STRINGOP || optimize_size)
18339     {
18340       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18341                                       operands[2], operands[3],
18342                                       operands[5], operands[6]));
18343       DONE;
18344     }
18345
18346   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18347 })
18348
18349 (define_expand "strmov_singleop"
18350   [(parallel [(set (match_operand 1 "memory_operand" "")
18351                    (match_operand 3 "memory_operand" ""))
18352               (set (match_operand 0 "register_operand" "")
18353                    (match_operand 4 "" ""))
18354               (set (match_operand 2 "register_operand" "")
18355                    (match_operand 5 "" ""))])]
18356   "TARGET_SINGLE_STRINGOP || optimize_size"
18357   "")
18358
18359 (define_insn "*strmovdi_rex_1"
18360   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18361         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18362    (set (match_operand:DI 0 "register_operand" "=D")
18363         (plus:DI (match_dup 2)
18364                  (const_int 8)))
18365    (set (match_operand:DI 1 "register_operand" "=S")
18366         (plus:DI (match_dup 3)
18367                  (const_int 8)))]
18368   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18369   "movsq"
18370   [(set_attr "type" "str")
18371    (set_attr "mode" "DI")
18372    (set_attr "memory" "both")])
18373
18374 (define_insn "*strmovsi_1"
18375   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18376         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18377    (set (match_operand:SI 0 "register_operand" "=D")
18378         (plus:SI (match_dup 2)
18379                  (const_int 4)))
18380    (set (match_operand:SI 1 "register_operand" "=S")
18381         (plus:SI (match_dup 3)
18382                  (const_int 4)))]
18383   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18384   "{movsl|movsd}"
18385   [(set_attr "type" "str")
18386    (set_attr "mode" "SI")
18387    (set_attr "memory" "both")])
18388
18389 (define_insn "*strmovsi_rex_1"
18390   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18391         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18392    (set (match_operand:DI 0 "register_operand" "=D")
18393         (plus:DI (match_dup 2)
18394                  (const_int 4)))
18395    (set (match_operand:DI 1 "register_operand" "=S")
18396         (plus:DI (match_dup 3)
18397                  (const_int 4)))]
18398   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18399   "{movsl|movsd}"
18400   [(set_attr "type" "str")
18401    (set_attr "mode" "SI")
18402    (set_attr "memory" "both")])
18403
18404 (define_insn "*strmovhi_1"
18405   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18406         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18407    (set (match_operand:SI 0 "register_operand" "=D")
18408         (plus:SI (match_dup 2)
18409                  (const_int 2)))
18410    (set (match_operand:SI 1 "register_operand" "=S")
18411         (plus:SI (match_dup 3)
18412                  (const_int 2)))]
18413   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18414   "movsw"
18415   [(set_attr "type" "str")
18416    (set_attr "memory" "both")
18417    (set_attr "mode" "HI")])
18418
18419 (define_insn "*strmovhi_rex_1"
18420   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18421         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18422    (set (match_operand:DI 0 "register_operand" "=D")
18423         (plus:DI (match_dup 2)
18424                  (const_int 2)))
18425    (set (match_operand:DI 1 "register_operand" "=S")
18426         (plus:DI (match_dup 3)
18427                  (const_int 2)))]
18428   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18429   "movsw"
18430   [(set_attr "type" "str")
18431    (set_attr "memory" "both")
18432    (set_attr "mode" "HI")])
18433
18434 (define_insn "*strmovqi_1"
18435   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18436         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18437    (set (match_operand:SI 0 "register_operand" "=D")
18438         (plus:SI (match_dup 2)
18439                  (const_int 1)))
18440    (set (match_operand:SI 1 "register_operand" "=S")
18441         (plus:SI (match_dup 3)
18442                  (const_int 1)))]
18443   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18444   "movsb"
18445   [(set_attr "type" "str")
18446    (set_attr "memory" "both")
18447    (set_attr "mode" "QI")])
18448
18449 (define_insn "*strmovqi_rex_1"
18450   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18451         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18452    (set (match_operand:DI 0 "register_operand" "=D")
18453         (plus:DI (match_dup 2)
18454                  (const_int 1)))
18455    (set (match_operand:DI 1 "register_operand" "=S")
18456         (plus:DI (match_dup 3)
18457                  (const_int 1)))]
18458   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18459   "movsb"
18460   [(set_attr "type" "str")
18461    (set_attr "memory" "both")
18462    (set_attr "mode" "QI")])
18463
18464 (define_expand "rep_mov"
18465   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18466               (set (match_operand 0 "register_operand" "")
18467                    (match_operand 5 "" ""))
18468               (set (match_operand 2 "register_operand" "")
18469                    (match_operand 6 "" ""))
18470               (set (match_operand 1 "memory_operand" "")
18471                    (match_operand 3 "memory_operand" ""))
18472               (use (match_dup 4))])]
18473   ""
18474   "")
18475
18476 (define_insn "*rep_movdi_rex64"
18477   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18478    (set (match_operand:DI 0 "register_operand" "=D")
18479         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18480                             (const_int 3))
18481                  (match_operand:DI 3 "register_operand" "0")))
18482    (set (match_operand:DI 1 "register_operand" "=S")
18483         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18484                  (match_operand:DI 4 "register_operand" "1")))
18485    (set (mem:BLK (match_dup 3))
18486         (mem:BLK (match_dup 4)))
18487    (use (match_dup 5))]
18488   "TARGET_64BIT"
18489   "{rep\;movsq|rep movsq}"
18490   [(set_attr "type" "str")
18491    (set_attr "prefix_rep" "1")
18492    (set_attr "memory" "both")
18493    (set_attr "mode" "DI")])
18494
18495 (define_insn "*rep_movsi"
18496   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18497    (set (match_operand:SI 0 "register_operand" "=D")
18498         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18499                             (const_int 2))
18500                  (match_operand:SI 3 "register_operand" "0")))
18501    (set (match_operand:SI 1 "register_operand" "=S")
18502         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18503                  (match_operand:SI 4 "register_operand" "1")))
18504    (set (mem:BLK (match_dup 3))
18505         (mem:BLK (match_dup 4)))
18506    (use (match_dup 5))]
18507   "!TARGET_64BIT"
18508   "{rep\;movsl|rep movsd}"
18509   [(set_attr "type" "str")
18510    (set_attr "prefix_rep" "1")
18511    (set_attr "memory" "both")
18512    (set_attr "mode" "SI")])
18513
18514 (define_insn "*rep_movsi_rex64"
18515   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18516    (set (match_operand:DI 0 "register_operand" "=D")
18517         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18518                             (const_int 2))
18519                  (match_operand:DI 3 "register_operand" "0")))
18520    (set (match_operand:DI 1 "register_operand" "=S")
18521         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18522                  (match_operand:DI 4 "register_operand" "1")))
18523    (set (mem:BLK (match_dup 3))
18524         (mem:BLK (match_dup 4)))
18525    (use (match_dup 5))]
18526   "TARGET_64BIT"
18527   "{rep\;movsl|rep movsd}"
18528   [(set_attr "type" "str")
18529    (set_attr "prefix_rep" "1")
18530    (set_attr "memory" "both")
18531    (set_attr "mode" "SI")])
18532
18533 (define_insn "*rep_movqi"
18534   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18535    (set (match_operand:SI 0 "register_operand" "=D")
18536         (plus:SI (match_operand:SI 3 "register_operand" "0")
18537                  (match_operand:SI 5 "register_operand" "2")))
18538    (set (match_operand:SI 1 "register_operand" "=S")
18539         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18540    (set (mem:BLK (match_dup 3))
18541         (mem:BLK (match_dup 4)))
18542    (use (match_dup 5))]
18543   "!TARGET_64BIT"
18544   "{rep\;movsb|rep movsb}"
18545   [(set_attr "type" "str")
18546    (set_attr "prefix_rep" "1")
18547    (set_attr "memory" "both")
18548    (set_attr "mode" "SI")])
18549
18550 (define_insn "*rep_movqi_rex64"
18551   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18552    (set (match_operand:DI 0 "register_operand" "=D")
18553         (plus:DI (match_operand:DI 3 "register_operand" "0")
18554                  (match_operand:DI 5 "register_operand" "2")))
18555    (set (match_operand:DI 1 "register_operand" "=S")
18556         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18557    (set (mem:BLK (match_dup 3))
18558         (mem:BLK (match_dup 4)))
18559    (use (match_dup 5))]
18560   "TARGET_64BIT"
18561   "{rep\;movsb|rep movsb}"
18562   [(set_attr "type" "str")
18563    (set_attr "prefix_rep" "1")
18564    (set_attr "memory" "both")
18565    (set_attr "mode" "SI")])
18566
18567 (define_expand "setmemsi"
18568    [(use (match_operand:BLK 0 "memory_operand" ""))
18569     (use (match_operand:SI 1 "nonmemory_operand" ""))
18570     (use (match_operand 2 "const_int_operand" ""))
18571     (use (match_operand 3 "const_int_operand" ""))
18572     (use (match_operand:SI 4 "const_int_operand" ""))
18573     (use (match_operand:SI 5 "const_int_operand" ""))]
18574   ""
18575 {
18576  if (ix86_expand_setmem (operands[0], operands[1],
18577                          operands[2], operands[3],
18578                          operands[4], operands[5]))
18579    DONE;
18580  else
18581    FAIL;
18582 })
18583
18584 (define_expand "setmemdi"
18585    [(use (match_operand:BLK 0 "memory_operand" ""))
18586     (use (match_operand:DI 1 "nonmemory_operand" ""))
18587     (use (match_operand 2 "const_int_operand" ""))
18588     (use (match_operand 3 "const_int_operand" ""))
18589     (use (match_operand 4 "const_int_operand" ""))
18590     (use (match_operand 5 "const_int_operand" ""))]
18591   "TARGET_64BIT"
18592 {
18593  if (ix86_expand_setmem (operands[0], operands[1],
18594                          operands[2], operands[3],
18595                          operands[4], operands[5]))
18596    DONE;
18597  else
18598    FAIL;
18599 })
18600
18601 ;; Most CPUs don't like single string operations
18602 ;; Handle this case here to simplify previous expander.
18603
18604 (define_expand "strset"
18605   [(set (match_operand 1 "memory_operand" "")
18606         (match_operand 2 "register_operand" ""))
18607    (parallel [(set (match_operand 0 "register_operand" "")
18608                    (match_dup 3))
18609               (clobber (reg:CC FLAGS_REG))])]
18610   ""
18611 {
18612   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18613     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18614
18615   /* If .md ever supports :P for Pmode, this can be directly
18616      in the pattern above.  */
18617   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18618                               GEN_INT (GET_MODE_SIZE (GET_MODE
18619                                                       (operands[2]))));
18620   if (TARGET_SINGLE_STRINGOP || optimize_size)
18621     {
18622       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18623                                       operands[3]));
18624       DONE;
18625     }
18626 })
18627
18628 (define_expand "strset_singleop"
18629   [(parallel [(set (match_operand 1 "memory_operand" "")
18630                    (match_operand 2 "register_operand" ""))
18631               (set (match_operand 0 "register_operand" "")
18632                    (match_operand 3 "" ""))])]
18633   "TARGET_SINGLE_STRINGOP || optimize_size"
18634   "")
18635
18636 (define_insn "*strsetdi_rex_1"
18637   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18638         (match_operand:DI 2 "register_operand" "a"))
18639    (set (match_operand:DI 0 "register_operand" "=D")
18640         (plus:DI (match_dup 1)
18641                  (const_int 8)))]
18642   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18643   "stosq"
18644   [(set_attr "type" "str")
18645    (set_attr "memory" "store")
18646    (set_attr "mode" "DI")])
18647
18648 (define_insn "*strsetsi_1"
18649   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18650         (match_operand:SI 2 "register_operand" "a"))
18651    (set (match_operand:SI 0 "register_operand" "=D")
18652         (plus:SI (match_dup 1)
18653                  (const_int 4)))]
18654   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18655   "{stosl|stosd}"
18656   [(set_attr "type" "str")
18657    (set_attr "memory" "store")
18658    (set_attr "mode" "SI")])
18659
18660 (define_insn "*strsetsi_rex_1"
18661   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18662         (match_operand:SI 2 "register_operand" "a"))
18663    (set (match_operand:DI 0 "register_operand" "=D")
18664         (plus:DI (match_dup 1)
18665                  (const_int 4)))]
18666   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18667   "{stosl|stosd}"
18668   [(set_attr "type" "str")
18669    (set_attr "memory" "store")
18670    (set_attr "mode" "SI")])
18671
18672 (define_insn "*strsethi_1"
18673   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18674         (match_operand:HI 2 "register_operand" "a"))
18675    (set (match_operand:SI 0 "register_operand" "=D")
18676         (plus:SI (match_dup 1)
18677                  (const_int 2)))]
18678   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18679   "stosw"
18680   [(set_attr "type" "str")
18681    (set_attr "memory" "store")
18682    (set_attr "mode" "HI")])
18683
18684 (define_insn "*strsethi_rex_1"
18685   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18686         (match_operand:HI 2 "register_operand" "a"))
18687    (set (match_operand:DI 0 "register_operand" "=D")
18688         (plus:DI (match_dup 1)
18689                  (const_int 2)))]
18690   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18691   "stosw"
18692   [(set_attr "type" "str")
18693    (set_attr "memory" "store")
18694    (set_attr "mode" "HI")])
18695
18696 (define_insn "*strsetqi_1"
18697   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18698         (match_operand:QI 2 "register_operand" "a"))
18699    (set (match_operand:SI 0 "register_operand" "=D")
18700         (plus:SI (match_dup 1)
18701                  (const_int 1)))]
18702   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18703   "stosb"
18704   [(set_attr "type" "str")
18705    (set_attr "memory" "store")
18706    (set_attr "mode" "QI")])
18707
18708 (define_insn "*strsetqi_rex_1"
18709   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18710         (match_operand:QI 2 "register_operand" "a"))
18711    (set (match_operand:DI 0 "register_operand" "=D")
18712         (plus:DI (match_dup 1)
18713                  (const_int 1)))]
18714   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18715   "stosb"
18716   [(set_attr "type" "str")
18717    (set_attr "memory" "store")
18718    (set_attr "mode" "QI")])
18719
18720 (define_expand "rep_stos"
18721   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18722               (set (match_operand 0 "register_operand" "")
18723                    (match_operand 4 "" ""))
18724               (set (match_operand 2 "memory_operand" "") (const_int 0))
18725               (use (match_operand 3 "register_operand" ""))
18726               (use (match_dup 1))])]
18727   ""
18728   "")
18729
18730 (define_insn "*rep_stosdi_rex64"
18731   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18732    (set (match_operand:DI 0 "register_operand" "=D")
18733         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18734                             (const_int 3))
18735                  (match_operand:DI 3 "register_operand" "0")))
18736    (set (mem:BLK (match_dup 3))
18737         (const_int 0))
18738    (use (match_operand:DI 2 "register_operand" "a"))
18739    (use (match_dup 4))]
18740   "TARGET_64BIT"
18741   "{rep\;stosq|rep stosq}"
18742   [(set_attr "type" "str")
18743    (set_attr "prefix_rep" "1")
18744    (set_attr "memory" "store")
18745    (set_attr "mode" "DI")])
18746
18747 (define_insn "*rep_stossi"
18748   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18749    (set (match_operand:SI 0 "register_operand" "=D")
18750         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18751                             (const_int 2))
18752                  (match_operand:SI 3 "register_operand" "0")))
18753    (set (mem:BLK (match_dup 3))
18754         (const_int 0))
18755    (use (match_operand:SI 2 "register_operand" "a"))
18756    (use (match_dup 4))]
18757   "!TARGET_64BIT"
18758   "{rep\;stosl|rep stosd}"
18759   [(set_attr "type" "str")
18760    (set_attr "prefix_rep" "1")
18761    (set_attr "memory" "store")
18762    (set_attr "mode" "SI")])
18763
18764 (define_insn "*rep_stossi_rex64"
18765   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18766    (set (match_operand:DI 0 "register_operand" "=D")
18767         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18768                             (const_int 2))
18769                  (match_operand:DI 3 "register_operand" "0")))
18770    (set (mem:BLK (match_dup 3))
18771         (const_int 0))
18772    (use (match_operand:SI 2 "register_operand" "a"))
18773    (use (match_dup 4))]
18774   "TARGET_64BIT"
18775   "{rep\;stosl|rep stosd}"
18776   [(set_attr "type" "str")
18777    (set_attr "prefix_rep" "1")
18778    (set_attr "memory" "store")
18779    (set_attr "mode" "SI")])
18780
18781 (define_insn "*rep_stosqi"
18782   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18783    (set (match_operand:SI 0 "register_operand" "=D")
18784         (plus:SI (match_operand:SI 3 "register_operand" "0")
18785                  (match_operand:SI 4 "register_operand" "1")))
18786    (set (mem:BLK (match_dup 3))
18787         (const_int 0))
18788    (use (match_operand:QI 2 "register_operand" "a"))
18789    (use (match_dup 4))]
18790   "!TARGET_64BIT"
18791   "{rep\;stosb|rep stosb}"
18792   [(set_attr "type" "str")
18793    (set_attr "prefix_rep" "1")
18794    (set_attr "memory" "store")
18795    (set_attr "mode" "QI")])
18796
18797 (define_insn "*rep_stosqi_rex64"
18798   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18799    (set (match_operand:DI 0 "register_operand" "=D")
18800         (plus:DI (match_operand:DI 3 "register_operand" "0")
18801                  (match_operand:DI 4 "register_operand" "1")))
18802    (set (mem:BLK (match_dup 3))
18803         (const_int 0))
18804    (use (match_operand:QI 2 "register_operand" "a"))
18805    (use (match_dup 4))]
18806   "TARGET_64BIT"
18807   "{rep\;stosb|rep stosb}"
18808   [(set_attr "type" "str")
18809    (set_attr "prefix_rep" "1")
18810    (set_attr "memory" "store")
18811    (set_attr "mode" "QI")])
18812
18813 (define_expand "cmpstrnsi"
18814   [(set (match_operand:SI 0 "register_operand" "")
18815         (compare:SI (match_operand:BLK 1 "general_operand" "")
18816                     (match_operand:BLK 2 "general_operand" "")))
18817    (use (match_operand 3 "general_operand" ""))
18818    (use (match_operand 4 "immediate_operand" ""))]
18819   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18820 {
18821   rtx addr1, addr2, out, outlow, count, countreg, align;
18822
18823   /* Can't use this if the user has appropriated esi or edi.  */
18824   if (global_regs[4] || global_regs[5])
18825     FAIL;
18826
18827   out = operands[0];
18828   if (!REG_P (out))
18829     out = gen_reg_rtx (SImode);
18830
18831   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18832   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18833   if (addr1 != XEXP (operands[1], 0))
18834     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18835   if (addr2 != XEXP (operands[2], 0))
18836     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18837
18838   count = operands[3];
18839   countreg = ix86_zero_extend_to_Pmode (count);
18840
18841   /* %%% Iff we are testing strict equality, we can use known alignment
18842      to good advantage.  This may be possible with combine, particularly
18843      once cc0 is dead.  */
18844   align = operands[4];
18845
18846   if (CONST_INT_P (count))
18847     {
18848       if (INTVAL (count) == 0)
18849         {
18850           emit_move_insn (operands[0], const0_rtx);
18851           DONE;
18852         }
18853       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18854                                      operands[1], operands[2]));
18855     }
18856   else
18857     {
18858       if (TARGET_64BIT)
18859         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18860       else
18861         emit_insn (gen_cmpsi_1 (countreg, countreg));
18862       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18863                                   operands[1], operands[2]));
18864     }
18865
18866   outlow = gen_lowpart (QImode, out);
18867   emit_insn (gen_cmpintqi (outlow));
18868   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18869
18870   if (operands[0] != out)
18871     emit_move_insn (operands[0], out);
18872
18873   DONE;
18874 })
18875
18876 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18877
18878 (define_expand "cmpintqi"
18879   [(set (match_dup 1)
18880         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18881    (set (match_dup 2)
18882         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18883    (parallel [(set (match_operand:QI 0 "register_operand" "")
18884                    (minus:QI (match_dup 1)
18885                              (match_dup 2)))
18886               (clobber (reg:CC FLAGS_REG))])]
18887   ""
18888   "operands[1] = gen_reg_rtx (QImode);
18889    operands[2] = gen_reg_rtx (QImode);")
18890
18891 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18892 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18893
18894 (define_expand "cmpstrnqi_nz_1"
18895   [(parallel [(set (reg:CC FLAGS_REG)
18896                    (compare:CC (match_operand 4 "memory_operand" "")
18897                                (match_operand 5 "memory_operand" "")))
18898               (use (match_operand 2 "register_operand" ""))
18899               (use (match_operand:SI 3 "immediate_operand" ""))
18900               (clobber (match_operand 0 "register_operand" ""))
18901               (clobber (match_operand 1 "register_operand" ""))
18902               (clobber (match_dup 2))])]
18903   ""
18904   "")
18905
18906 (define_insn "*cmpstrnqi_nz_1"
18907   [(set (reg:CC FLAGS_REG)
18908         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18909                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18910    (use (match_operand:SI 6 "register_operand" "2"))
18911    (use (match_operand:SI 3 "immediate_operand" "i"))
18912    (clobber (match_operand:SI 0 "register_operand" "=S"))
18913    (clobber (match_operand:SI 1 "register_operand" "=D"))
18914    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18915   "!TARGET_64BIT"
18916   "repz{\;| }cmpsb"
18917   [(set_attr "type" "str")
18918    (set_attr "mode" "QI")
18919    (set_attr "prefix_rep" "1")])
18920
18921 (define_insn "*cmpstrnqi_nz_rex_1"
18922   [(set (reg:CC FLAGS_REG)
18923         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18924                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18925    (use (match_operand:DI 6 "register_operand" "2"))
18926    (use (match_operand:SI 3 "immediate_operand" "i"))
18927    (clobber (match_operand:DI 0 "register_operand" "=S"))
18928    (clobber (match_operand:DI 1 "register_operand" "=D"))
18929    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18930   "TARGET_64BIT"
18931   "repz{\;| }cmpsb"
18932   [(set_attr "type" "str")
18933    (set_attr "mode" "QI")
18934    (set_attr "prefix_rep" "1")])
18935
18936 ;; The same, but the count is not known to not be zero.
18937
18938 (define_expand "cmpstrnqi_1"
18939   [(parallel [(set (reg:CC FLAGS_REG)
18940                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18941                                      (const_int 0))
18942                   (compare:CC (match_operand 4 "memory_operand" "")
18943                               (match_operand 5 "memory_operand" ""))
18944                   (const_int 0)))
18945               (use (match_operand:SI 3 "immediate_operand" ""))
18946               (use (reg:CC FLAGS_REG))
18947               (clobber (match_operand 0 "register_operand" ""))
18948               (clobber (match_operand 1 "register_operand" ""))
18949               (clobber (match_dup 2))])]
18950   ""
18951   "")
18952
18953 (define_insn "*cmpstrnqi_1"
18954   [(set (reg:CC FLAGS_REG)
18955         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18956                              (const_int 0))
18957           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18958                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18959           (const_int 0)))
18960    (use (match_operand:SI 3 "immediate_operand" "i"))
18961    (use (reg:CC FLAGS_REG))
18962    (clobber (match_operand:SI 0 "register_operand" "=S"))
18963    (clobber (match_operand:SI 1 "register_operand" "=D"))
18964    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18965   "!TARGET_64BIT"
18966   "repz{\;| }cmpsb"
18967   [(set_attr "type" "str")
18968    (set_attr "mode" "QI")
18969    (set_attr "prefix_rep" "1")])
18970
18971 (define_insn "*cmpstrnqi_rex_1"
18972   [(set (reg:CC FLAGS_REG)
18973         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18974                              (const_int 0))
18975           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18976                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18977           (const_int 0)))
18978    (use (match_operand:SI 3 "immediate_operand" "i"))
18979    (use (reg:CC FLAGS_REG))
18980    (clobber (match_operand:DI 0 "register_operand" "=S"))
18981    (clobber (match_operand:DI 1 "register_operand" "=D"))
18982    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18983   "TARGET_64BIT"
18984   "repz{\;| }cmpsb"
18985   [(set_attr "type" "str")
18986    (set_attr "mode" "QI")
18987    (set_attr "prefix_rep" "1")])
18988
18989 (define_expand "strlensi"
18990   [(set (match_operand:SI 0 "register_operand" "")
18991         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18992                     (match_operand:QI 2 "immediate_operand" "")
18993                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18994   ""
18995 {
18996  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18997    DONE;
18998  else
18999    FAIL;
19000 })
19001
19002 (define_expand "strlendi"
19003   [(set (match_operand:DI 0 "register_operand" "")
19004         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19005                     (match_operand:QI 2 "immediate_operand" "")
19006                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19007   ""
19008 {
19009  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19010    DONE;
19011  else
19012    FAIL;
19013 })
19014
19015 (define_expand "strlenqi_1"
19016   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19017               (clobber (match_operand 1 "register_operand" ""))
19018               (clobber (reg:CC FLAGS_REG))])]
19019   ""
19020   "")
19021
19022 (define_insn "*strlenqi_1"
19023   [(set (match_operand:SI 0 "register_operand" "=&c")
19024         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19025                     (match_operand:QI 2 "register_operand" "a")
19026                     (match_operand:SI 3 "immediate_operand" "i")
19027                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19028    (clobber (match_operand:SI 1 "register_operand" "=D"))
19029    (clobber (reg:CC FLAGS_REG))]
19030   "!TARGET_64BIT"
19031   "repnz{\;| }scasb"
19032   [(set_attr "type" "str")
19033    (set_attr "mode" "QI")
19034    (set_attr "prefix_rep" "1")])
19035
19036 (define_insn "*strlenqi_rex_1"
19037   [(set (match_operand:DI 0 "register_operand" "=&c")
19038         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19039                     (match_operand:QI 2 "register_operand" "a")
19040                     (match_operand:DI 3 "immediate_operand" "i")
19041                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19042    (clobber (match_operand:DI 1 "register_operand" "=D"))
19043    (clobber (reg:CC FLAGS_REG))]
19044   "TARGET_64BIT"
19045   "repnz{\;| }scasb"
19046   [(set_attr "type" "str")
19047    (set_attr "mode" "QI")
19048    (set_attr "prefix_rep" "1")])
19049
19050 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19051 ;; handled in combine, but it is not currently up to the task.
19052 ;; When used for their truth value, the cmpstrn* expanders generate
19053 ;; code like this:
19054 ;;
19055 ;;   repz cmpsb
19056 ;;   seta       %al
19057 ;;   setb       %dl
19058 ;;   cmpb       %al, %dl
19059 ;;   jcc        label
19060 ;;
19061 ;; The intermediate three instructions are unnecessary.
19062
19063 ;; This one handles cmpstrn*_nz_1...
19064 (define_peephole2
19065   [(parallel[
19066      (set (reg:CC FLAGS_REG)
19067           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19068                       (mem:BLK (match_operand 5 "register_operand" ""))))
19069      (use (match_operand 6 "register_operand" ""))
19070      (use (match_operand:SI 3 "immediate_operand" ""))
19071      (clobber (match_operand 0 "register_operand" ""))
19072      (clobber (match_operand 1 "register_operand" ""))
19073      (clobber (match_operand 2 "register_operand" ""))])
19074    (set (match_operand:QI 7 "register_operand" "")
19075         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19076    (set (match_operand:QI 8 "register_operand" "")
19077         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19078    (set (reg FLAGS_REG)
19079         (compare (match_dup 7) (match_dup 8)))
19080   ]
19081   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19082   [(parallel[
19083      (set (reg:CC FLAGS_REG)
19084           (compare:CC (mem:BLK (match_dup 4))
19085                       (mem:BLK (match_dup 5))))
19086      (use (match_dup 6))
19087      (use (match_dup 3))
19088      (clobber (match_dup 0))
19089      (clobber (match_dup 1))
19090      (clobber (match_dup 2))])]
19091   "")
19092
19093 ;; ...and this one handles cmpstrn*_1.
19094 (define_peephole2
19095   [(parallel[
19096      (set (reg:CC FLAGS_REG)
19097           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19098                                (const_int 0))
19099             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19100                         (mem:BLK (match_operand 5 "register_operand" "")))
19101             (const_int 0)))
19102      (use (match_operand:SI 3 "immediate_operand" ""))
19103      (use (reg:CC FLAGS_REG))
19104      (clobber (match_operand 0 "register_operand" ""))
19105      (clobber (match_operand 1 "register_operand" ""))
19106      (clobber (match_operand 2 "register_operand" ""))])
19107    (set (match_operand:QI 7 "register_operand" "")
19108         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19109    (set (match_operand:QI 8 "register_operand" "")
19110         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19111    (set (reg FLAGS_REG)
19112         (compare (match_dup 7) (match_dup 8)))
19113   ]
19114   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19115   [(parallel[
19116      (set (reg:CC FLAGS_REG)
19117           (if_then_else:CC (ne (match_dup 6)
19118                                (const_int 0))
19119             (compare:CC (mem:BLK (match_dup 4))
19120                         (mem:BLK (match_dup 5)))
19121             (const_int 0)))
19122      (use (match_dup 3))
19123      (use (reg:CC FLAGS_REG))
19124      (clobber (match_dup 0))
19125      (clobber (match_dup 1))
19126      (clobber (match_dup 2))])]
19127   "")
19128
19129
19130 \f
19131 ;; Conditional move instructions.
19132
19133 (define_expand "movdicc"
19134   [(set (match_operand:DI 0 "register_operand" "")
19135         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19136                          (match_operand:DI 2 "general_operand" "")
19137                          (match_operand:DI 3 "general_operand" "")))]
19138   "TARGET_64BIT"
19139   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19140
19141 (define_insn "x86_movdicc_0_m1_rex64"
19142   [(set (match_operand:DI 0 "register_operand" "=r")
19143         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19144           (const_int -1)
19145           (const_int 0)))
19146    (clobber (reg:CC FLAGS_REG))]
19147   "TARGET_64BIT"
19148   "sbb{q}\t%0, %0"
19149   ; Since we don't have the proper number of operands for an alu insn,
19150   ; fill in all the blanks.
19151   [(set_attr "type" "alu")
19152    (set_attr "pent_pair" "pu")
19153    (set_attr "memory" "none")
19154    (set_attr "imm_disp" "false")
19155    (set_attr "mode" "DI")
19156    (set_attr "length_immediate" "0")])
19157
19158 (define_insn "*movdicc_c_rex64"
19159   [(set (match_operand:DI 0 "register_operand" "=r,r")
19160         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19161                                 [(reg FLAGS_REG) (const_int 0)])
19162                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19163                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19164   "TARGET_64BIT && TARGET_CMOVE
19165    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19166   "@
19167    cmov%O2%C1\t{%2, %0|%0, %2}
19168    cmov%O2%c1\t{%3, %0|%0, %3}"
19169   [(set_attr "type" "icmov")
19170    (set_attr "mode" "DI")])
19171
19172 (define_expand "movsicc"
19173   [(set (match_operand:SI 0 "register_operand" "")
19174         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19175                          (match_operand:SI 2 "general_operand" "")
19176                          (match_operand:SI 3 "general_operand" "")))]
19177   ""
19178   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19179
19180 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19181 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19182 ;; So just document what we're doing explicitly.
19183
19184 (define_insn "x86_movsicc_0_m1"
19185   [(set (match_operand:SI 0 "register_operand" "=r")
19186         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19187           (const_int -1)
19188           (const_int 0)))
19189    (clobber (reg:CC FLAGS_REG))]
19190   ""
19191   "sbb{l}\t%0, %0"
19192   ; Since we don't have the proper number of operands for an alu insn,
19193   ; fill in all the blanks.
19194   [(set_attr "type" "alu")
19195    (set_attr "pent_pair" "pu")
19196    (set_attr "memory" "none")
19197    (set_attr "imm_disp" "false")
19198    (set_attr "mode" "SI")
19199    (set_attr "length_immediate" "0")])
19200
19201 (define_insn "*movsicc_noc"
19202   [(set (match_operand:SI 0 "register_operand" "=r,r")
19203         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19204                                 [(reg FLAGS_REG) (const_int 0)])
19205                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19206                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19207   "TARGET_CMOVE
19208    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19209   "@
19210    cmov%O2%C1\t{%2, %0|%0, %2}
19211    cmov%O2%c1\t{%3, %0|%0, %3}"
19212   [(set_attr "type" "icmov")
19213    (set_attr "mode" "SI")])
19214
19215 (define_expand "movhicc"
19216   [(set (match_operand:HI 0 "register_operand" "")
19217         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19218                          (match_operand:HI 2 "general_operand" "")
19219                          (match_operand:HI 3 "general_operand" "")))]
19220   "TARGET_HIMODE_MATH"
19221   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19222
19223 (define_insn "*movhicc_noc"
19224   [(set (match_operand:HI 0 "register_operand" "=r,r")
19225         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19226                                 [(reg FLAGS_REG) (const_int 0)])
19227                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19228                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19229   "TARGET_CMOVE
19230    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19231   "@
19232    cmov%O2%C1\t{%2, %0|%0, %2}
19233    cmov%O2%c1\t{%3, %0|%0, %3}"
19234   [(set_attr "type" "icmov")
19235    (set_attr "mode" "HI")])
19236
19237 (define_expand "movqicc"
19238   [(set (match_operand:QI 0 "register_operand" "")
19239         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19240                          (match_operand:QI 2 "general_operand" "")
19241                          (match_operand:QI 3 "general_operand" "")))]
19242   "TARGET_QIMODE_MATH"
19243   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19244
19245 (define_insn_and_split "*movqicc_noc"
19246   [(set (match_operand:QI 0 "register_operand" "=r,r")
19247         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19248                                 [(match_operand 4 "flags_reg_operand" "")
19249                                  (const_int 0)])
19250                       (match_operand:QI 2 "register_operand" "r,0")
19251                       (match_operand:QI 3 "register_operand" "0,r")))]
19252   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19253   "#"
19254   "&& reload_completed"
19255   [(set (match_dup 0)
19256         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19257                       (match_dup 2)
19258                       (match_dup 3)))]
19259   "operands[0] = gen_lowpart (SImode, operands[0]);
19260    operands[2] = gen_lowpart (SImode, operands[2]);
19261    operands[3] = gen_lowpart (SImode, operands[3]);"
19262   [(set_attr "type" "icmov")
19263    (set_attr "mode" "SI")])
19264
19265 (define_expand "movsfcc"
19266   [(set (match_operand:SF 0 "register_operand" "")
19267         (if_then_else:SF (match_operand 1 "comparison_operator" "")
19268                          (match_operand:SF 2 "register_operand" "")
19269                          (match_operand:SF 3 "register_operand" "")))]
19270   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19271   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19272
19273 (define_insn "*movsfcc_1_387"
19274   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19275         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19276                                 [(reg FLAGS_REG) (const_int 0)])
19277                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19278                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19279   "TARGET_80387 && TARGET_CMOVE
19280    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19281   "@
19282    fcmov%F1\t{%2, %0|%0, %2}
19283    fcmov%f1\t{%3, %0|%0, %3}
19284    cmov%O2%C1\t{%2, %0|%0, %2}
19285    cmov%O2%c1\t{%3, %0|%0, %3}"
19286   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19287    (set_attr "mode" "SF,SF,SI,SI")])
19288
19289 (define_expand "movdfcc"
19290   [(set (match_operand:DF 0 "register_operand" "")
19291         (if_then_else:DF (match_operand 1 "comparison_operator" "")
19292                          (match_operand:DF 2 "register_operand" "")
19293                          (match_operand:DF 3 "register_operand" "")))]
19294   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19295   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19296
19297 (define_insn "*movdfcc_1"
19298   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19299         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19300                                 [(reg FLAGS_REG) (const_int 0)])
19301                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19302                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19303   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19304    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19305   "@
19306    fcmov%F1\t{%2, %0|%0, %2}
19307    fcmov%f1\t{%3, %0|%0, %3}
19308    #
19309    #"
19310   [(set_attr "type" "fcmov,fcmov,multi,multi")
19311    (set_attr "mode" "DF")])
19312
19313 (define_insn "*movdfcc_1_rex64"
19314   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19315         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19316                                 [(reg FLAGS_REG) (const_int 0)])
19317                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19318                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19319   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19320    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19321   "@
19322    fcmov%F1\t{%2, %0|%0, %2}
19323    fcmov%f1\t{%3, %0|%0, %3}
19324    cmov%O2%C1\t{%2, %0|%0, %2}
19325    cmov%O2%c1\t{%3, %0|%0, %3}"
19326   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19327    (set_attr "mode" "DF")])
19328
19329 (define_split
19330   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19331         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19332                                 [(match_operand 4 "flags_reg_operand" "")
19333                                  (const_int 0)])
19334                       (match_operand:DF 2 "nonimmediate_operand" "")
19335                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19336   "!TARGET_64BIT && reload_completed"
19337   [(set (match_dup 2)
19338         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19339                       (match_dup 5)
19340                       (match_dup 7)))
19341    (set (match_dup 3)
19342         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19343                       (match_dup 6)
19344                       (match_dup 8)))]
19345   "split_di (operands+2, 1, operands+5, operands+6);
19346    split_di (operands+3, 1, operands+7, operands+8);
19347    split_di (operands, 1, operands+2, operands+3);")
19348
19349 (define_expand "movxfcc"
19350   [(set (match_operand:XF 0 "register_operand" "")
19351         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19352                          (match_operand:XF 2 "register_operand" "")
19353                          (match_operand:XF 3 "register_operand" "")))]
19354   "TARGET_80387 && TARGET_CMOVE"
19355   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19356
19357 (define_insn "*movxfcc_1"
19358   [(set (match_operand:XF 0 "register_operand" "=f,f")
19359         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19360                                 [(reg FLAGS_REG) (const_int 0)])
19361                       (match_operand:XF 2 "register_operand" "f,0")
19362                       (match_operand:XF 3 "register_operand" "0,f")))]
19363   "TARGET_80387 && TARGET_CMOVE"
19364   "@
19365    fcmov%F1\t{%2, %0|%0, %2}
19366    fcmov%f1\t{%3, %0|%0, %3}"
19367   [(set_attr "type" "fcmov")
19368    (set_attr "mode" "XF")])
19369
19370 ;; These versions of the min/max patterns are intentionally ignorant of
19371 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19372 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19373 ;; are undefined in this condition, we're certain this is correct.
19374
19375 (define_insn "sminsf3"
19376   [(set (match_operand:SF 0 "register_operand" "=x")
19377         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19378                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19379   "TARGET_SSE_MATH"
19380   "minss\t{%2, %0|%0, %2}"
19381   [(set_attr "type" "sseadd")
19382    (set_attr "mode" "SF")])
19383
19384 (define_insn "smaxsf3"
19385   [(set (match_operand:SF 0 "register_operand" "=x")
19386         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19387                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19388   "TARGET_SSE_MATH"
19389   "maxss\t{%2, %0|%0, %2}"
19390   [(set_attr "type" "sseadd")
19391    (set_attr "mode" "SF")])
19392
19393 (define_insn "smindf3"
19394   [(set (match_operand:DF 0 "register_operand" "=x")
19395         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19396                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19397   "TARGET_SSE2 && TARGET_SSE_MATH"
19398   "minsd\t{%2, %0|%0, %2}"
19399   [(set_attr "type" "sseadd")
19400    (set_attr "mode" "DF")])
19401
19402 (define_insn "smaxdf3"
19403   [(set (match_operand:DF 0 "register_operand" "=x")
19404         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19405                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19406   "TARGET_SSE2 && TARGET_SSE_MATH"
19407   "maxsd\t{%2, %0|%0, %2}"
19408   [(set_attr "type" "sseadd")
19409    (set_attr "mode" "DF")])
19410
19411 ;; These versions of the min/max patterns implement exactly the operations
19412 ;;   min = (op1 < op2 ? op1 : op2)
19413 ;;   max = (!(op1 < op2) ? op1 : op2)
19414 ;; Their operands are not commutative, and thus they may be used in the
19415 ;; presence of -0.0 and NaN.
19416
19417 (define_insn "*ieee_sminsf3"
19418   [(set (match_operand:SF 0 "register_operand" "=x")
19419         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19420                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19421                    UNSPEC_IEEE_MIN))]
19422   "TARGET_SSE_MATH"
19423   "minss\t{%2, %0|%0, %2}"
19424   [(set_attr "type" "sseadd")
19425    (set_attr "mode" "SF")])
19426
19427 (define_insn "*ieee_smaxsf3"
19428   [(set (match_operand:SF 0 "register_operand" "=x")
19429         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19430                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19431                    UNSPEC_IEEE_MAX))]
19432   "TARGET_SSE_MATH"
19433   "maxss\t{%2, %0|%0, %2}"
19434   [(set_attr "type" "sseadd")
19435    (set_attr "mode" "SF")])
19436
19437 (define_insn "*ieee_smindf3"
19438   [(set (match_operand:DF 0 "register_operand" "=x")
19439         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19440                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19441                    UNSPEC_IEEE_MIN))]
19442   "TARGET_SSE2 && TARGET_SSE_MATH"
19443   "minsd\t{%2, %0|%0, %2}"
19444   [(set_attr "type" "sseadd")
19445    (set_attr "mode" "DF")])
19446
19447 (define_insn "*ieee_smaxdf3"
19448   [(set (match_operand:DF 0 "register_operand" "=x")
19449         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19450                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19451                    UNSPEC_IEEE_MAX))]
19452   "TARGET_SSE2 && TARGET_SSE_MATH"
19453   "maxsd\t{%2, %0|%0, %2}"
19454   [(set_attr "type" "sseadd")
19455    (set_attr "mode" "DF")])
19456
19457 ;; Make two stack loads independent:
19458 ;;   fld aa              fld aa
19459 ;;   fld %st(0)     ->   fld bb
19460 ;;   fmul bb             fmul %st(1), %st
19461 ;;
19462 ;; Actually we only match the last two instructions for simplicity.
19463 (define_peephole2
19464   [(set (match_operand 0 "fp_register_operand" "")
19465         (match_operand 1 "fp_register_operand" ""))
19466    (set (match_dup 0)
19467         (match_operator 2 "binary_fp_operator"
19468            [(match_dup 0)
19469             (match_operand 3 "memory_operand" "")]))]
19470   "REGNO (operands[0]) != REGNO (operands[1])"
19471   [(set (match_dup 0) (match_dup 3))
19472    (set (match_dup 0) (match_dup 4))]
19473
19474   ;; The % modifier is not operational anymore in peephole2's, so we have to
19475   ;; swap the operands manually in the case of addition and multiplication.
19476   "if (COMMUTATIVE_ARITH_P (operands[2]))
19477      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19478                                  operands[0], operands[1]);
19479    else
19480      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19481                                  operands[1], operands[0]);")
19482
19483 ;; Conditional addition patterns
19484 (define_expand "addqicc"
19485   [(match_operand:QI 0 "register_operand" "")
19486    (match_operand 1 "comparison_operator" "")
19487    (match_operand:QI 2 "register_operand" "")
19488    (match_operand:QI 3 "const_int_operand" "")]
19489   ""
19490   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19491
19492 (define_expand "addhicc"
19493   [(match_operand:HI 0 "register_operand" "")
19494    (match_operand 1 "comparison_operator" "")
19495    (match_operand:HI 2 "register_operand" "")
19496    (match_operand:HI 3 "const_int_operand" "")]
19497   ""
19498   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19499
19500 (define_expand "addsicc"
19501   [(match_operand:SI 0 "register_operand" "")
19502    (match_operand 1 "comparison_operator" "")
19503    (match_operand:SI 2 "register_operand" "")
19504    (match_operand:SI 3 "const_int_operand" "")]
19505   ""
19506   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19507
19508 (define_expand "adddicc"
19509   [(match_operand:DI 0 "register_operand" "")
19510    (match_operand 1 "comparison_operator" "")
19511    (match_operand:DI 2 "register_operand" "")
19512    (match_operand:DI 3 "const_int_operand" "")]
19513   "TARGET_64BIT"
19514   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19515
19516 \f
19517 ;; Misc patterns (?)
19518
19519 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19520 ;; Otherwise there will be nothing to keep
19521 ;;
19522 ;; [(set (reg ebp) (reg esp))]
19523 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19524 ;;  (clobber (eflags)]
19525 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19526 ;;
19527 ;; in proper program order.
19528 (define_insn "pro_epilogue_adjust_stack_1"
19529   [(set (match_operand:SI 0 "register_operand" "=r,r")
19530         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19531                  (match_operand:SI 2 "immediate_operand" "i,i")))
19532    (clobber (reg:CC FLAGS_REG))
19533    (clobber (mem:BLK (scratch)))]
19534   "!TARGET_64BIT"
19535 {
19536   switch (get_attr_type (insn))
19537     {
19538     case TYPE_IMOV:
19539       return "mov{l}\t{%1, %0|%0, %1}";
19540
19541     case TYPE_ALU:
19542       if (CONST_INT_P (operands[2])
19543           && (INTVAL (operands[2]) == 128
19544               || (INTVAL (operands[2]) < 0
19545                   && INTVAL (operands[2]) != -128)))
19546         {
19547           operands[2] = GEN_INT (-INTVAL (operands[2]));
19548           return "sub{l}\t{%2, %0|%0, %2}";
19549         }
19550       return "add{l}\t{%2, %0|%0, %2}";
19551
19552     case TYPE_LEA:
19553       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19554       return "lea{l}\t{%a2, %0|%0, %a2}";
19555
19556     default:
19557       gcc_unreachable ();
19558     }
19559 }
19560   [(set (attr "type")
19561         (cond [(eq_attr "alternative" "0")
19562                  (const_string "alu")
19563                (match_operand:SI 2 "const0_operand" "")
19564                  (const_string "imov")
19565               ]
19566               (const_string "lea")))
19567    (set_attr "mode" "SI")])
19568
19569 (define_insn "pro_epilogue_adjust_stack_rex64"
19570   [(set (match_operand:DI 0 "register_operand" "=r,r")
19571         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19572                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19573    (clobber (reg:CC FLAGS_REG))
19574    (clobber (mem:BLK (scratch)))]
19575   "TARGET_64BIT"
19576 {
19577   switch (get_attr_type (insn))
19578     {
19579     case TYPE_IMOV:
19580       return "mov{q}\t{%1, %0|%0, %1}";
19581
19582     case TYPE_ALU:
19583       if (CONST_INT_P (operands[2])
19584           /* Avoid overflows.  */
19585           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19586           && (INTVAL (operands[2]) == 128
19587               || (INTVAL (operands[2]) < 0
19588                   && INTVAL (operands[2]) != -128)))
19589         {
19590           operands[2] = GEN_INT (-INTVAL (operands[2]));
19591           return "sub{q}\t{%2, %0|%0, %2}";
19592         }
19593       return "add{q}\t{%2, %0|%0, %2}";
19594
19595     case TYPE_LEA:
19596       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19597       return "lea{q}\t{%a2, %0|%0, %a2}";
19598
19599     default:
19600       gcc_unreachable ();
19601     }
19602 }
19603   [(set (attr "type")
19604         (cond [(eq_attr "alternative" "0")
19605                  (const_string "alu")
19606                (match_operand:DI 2 "const0_operand" "")
19607                  (const_string "imov")
19608               ]
19609               (const_string "lea")))
19610    (set_attr "mode" "DI")])
19611
19612 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19613   [(set (match_operand:DI 0 "register_operand" "=r,r")
19614         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19615                  (match_operand:DI 3 "immediate_operand" "i,i")))
19616    (use (match_operand:DI 2 "register_operand" "r,r"))
19617    (clobber (reg:CC FLAGS_REG))
19618    (clobber (mem:BLK (scratch)))]
19619   "TARGET_64BIT"
19620 {
19621   switch (get_attr_type (insn))
19622     {
19623     case TYPE_ALU:
19624       return "add{q}\t{%2, %0|%0, %2}";
19625
19626     case TYPE_LEA:
19627       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19628       return "lea{q}\t{%a2, %0|%0, %a2}";
19629
19630     default:
19631       gcc_unreachable ();
19632     }
19633 }
19634   [(set_attr "type" "alu,lea")
19635    (set_attr "mode" "DI")])
19636
19637 (define_expand "allocate_stack_worker"
19638   [(match_operand:SI 0 "register_operand" "")]
19639   "TARGET_STACK_PROBE"
19640 {
19641   if (reload_completed)
19642     {
19643       if (TARGET_64BIT)
19644         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19645       else
19646         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19647     }
19648   else
19649     {
19650       if (TARGET_64BIT)
19651         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19652       else
19653         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19654     }
19655   DONE;
19656 })
19657
19658 (define_insn "allocate_stack_worker_1"
19659   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19660     UNSPECV_STACK_PROBE)
19661    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19662    (clobber (match_scratch:SI 1 "=0"))
19663    (clobber (reg:CC FLAGS_REG))]
19664   "!TARGET_64BIT && TARGET_STACK_PROBE"
19665   "call\t__alloca"
19666   [(set_attr "type" "multi")
19667    (set_attr "length" "5")])
19668
19669 (define_expand "allocate_stack_worker_postreload"
19670   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19671                                     UNSPECV_STACK_PROBE)
19672               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19673               (clobber (match_dup 0))
19674               (clobber (reg:CC FLAGS_REG))])]
19675   ""
19676   "")
19677
19678 (define_insn "allocate_stack_worker_rex64"
19679   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19680     UNSPECV_STACK_PROBE)
19681    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19682    (clobber (match_scratch:DI 1 "=0"))
19683    (clobber (reg:CC FLAGS_REG))]
19684   "TARGET_64BIT && TARGET_STACK_PROBE"
19685   "call\t__alloca"
19686   [(set_attr "type" "multi")
19687    (set_attr "length" "5")])
19688
19689 (define_expand "allocate_stack_worker_rex64_postreload"
19690   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19691                                     UNSPECV_STACK_PROBE)
19692               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19693               (clobber (match_dup 0))
19694               (clobber (reg:CC FLAGS_REG))])]
19695   ""
19696   "")
19697
19698 (define_expand "allocate_stack"
19699   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19700                    (minus:SI (reg:SI SP_REG)
19701                              (match_operand:SI 1 "general_operand" "")))
19702               (clobber (reg:CC FLAGS_REG))])
19703    (parallel [(set (reg:SI SP_REG)
19704                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
19705               (clobber (reg:CC FLAGS_REG))])]
19706   "TARGET_STACK_PROBE"
19707 {
19708 #ifdef CHECK_STACK_LIMIT
19709   if (CONST_INT_P (operands[1])
19710       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19711     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19712                            operands[1]));
19713   else
19714 #endif
19715     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19716                                                             operands[1])));
19717
19718   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19719   DONE;
19720 })
19721
19722 (define_expand "builtin_setjmp_receiver"
19723   [(label_ref (match_operand 0 "" ""))]
19724   "!TARGET_64BIT && flag_pic"
19725 {
19726   if (TARGET_MACHO)
19727     {
19728       rtx xops[3];
19729       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19730       rtx label_rtx = gen_label_rtx ();
19731       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19732       xops[0] = xops[1] = picreg;
19733       xops[2] = gen_rtx_CONST (SImode,
19734                   gen_rtx_MINUS (SImode,
19735                     gen_rtx_LABEL_REF (SImode, label_rtx),
19736                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19737       ix86_expand_binary_operator (MINUS, SImode, xops);
19738     }
19739   else
19740     emit_insn (gen_set_got (pic_offset_table_rtx));
19741   DONE;
19742 })
19743 \f
19744 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19745
19746 (define_split
19747   [(set (match_operand 0 "register_operand" "")
19748         (match_operator 3 "promotable_binary_operator"
19749            [(match_operand 1 "register_operand" "")
19750             (match_operand 2 "aligned_operand" "")]))
19751    (clobber (reg:CC FLAGS_REG))]
19752   "! TARGET_PARTIAL_REG_STALL && reload_completed
19753    && ((GET_MODE (operands[0]) == HImode
19754         && ((!optimize_size && !TARGET_FAST_PREFIX)
19755             /* ??? next two lines just !satisfies_constraint_K (...) */
19756             || !CONST_INT_P (operands[2])
19757             || satisfies_constraint_K (operands[2])))
19758        || (GET_MODE (operands[0]) == QImode
19759            && (TARGET_PROMOTE_QImode || optimize_size)))"
19760   [(parallel [(set (match_dup 0)
19761                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19762               (clobber (reg:CC FLAGS_REG))])]
19763   "operands[0] = gen_lowpart (SImode, operands[0]);
19764    operands[1] = gen_lowpart (SImode, operands[1]);
19765    if (GET_CODE (operands[3]) != ASHIFT)
19766      operands[2] = gen_lowpart (SImode, operands[2]);
19767    PUT_MODE (operands[3], SImode);")
19768
19769 ; Promote the QImode tests, as i386 has encoding of the AND
19770 ; instruction with 32-bit sign-extended immediate and thus the
19771 ; instruction size is unchanged, except in the %eax case for
19772 ; which it is increased by one byte, hence the ! optimize_size.
19773 (define_split
19774   [(set (match_operand 0 "flags_reg_operand" "")
19775         (match_operator 2 "compare_operator"
19776           [(and (match_operand 3 "aligned_operand" "")
19777                 (match_operand 4 "const_int_operand" ""))
19778            (const_int 0)]))
19779    (set (match_operand 1 "register_operand" "")
19780         (and (match_dup 3) (match_dup 4)))]
19781   "! TARGET_PARTIAL_REG_STALL && reload_completed
19782    /* Ensure that the operand will remain sign-extended immediate.  */
19783    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19784    && ! optimize_size
19785    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19786        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19787   [(parallel [(set (match_dup 0)
19788                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19789                                     (const_int 0)]))
19790               (set (match_dup 1)
19791                    (and:SI (match_dup 3) (match_dup 4)))])]
19792 {
19793   operands[4]
19794     = gen_int_mode (INTVAL (operands[4])
19795                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19796   operands[1] = gen_lowpart (SImode, operands[1]);
19797   operands[3] = gen_lowpart (SImode, operands[3]);
19798 })
19799
19800 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19801 ; the TEST instruction with 32-bit sign-extended immediate and thus
19802 ; the instruction size would at least double, which is not what we
19803 ; want even with ! optimize_size.
19804 (define_split
19805   [(set (match_operand 0 "flags_reg_operand" "")
19806         (match_operator 1 "compare_operator"
19807           [(and (match_operand:HI 2 "aligned_operand" "")
19808                 (match_operand:HI 3 "const_int_operand" ""))
19809            (const_int 0)]))]
19810   "! TARGET_PARTIAL_REG_STALL && reload_completed
19811    /* Ensure that the operand will remain sign-extended immediate.  */
19812    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19813    && ! TARGET_FAST_PREFIX
19814    && ! optimize_size"
19815   [(set (match_dup 0)
19816         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19817                          (const_int 0)]))]
19818 {
19819   operands[3]
19820     = gen_int_mode (INTVAL (operands[3])
19821                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19822   operands[2] = gen_lowpart (SImode, operands[2]);
19823 })
19824
19825 (define_split
19826   [(set (match_operand 0 "register_operand" "")
19827         (neg (match_operand 1 "register_operand" "")))
19828    (clobber (reg:CC FLAGS_REG))]
19829   "! TARGET_PARTIAL_REG_STALL && reload_completed
19830    && (GET_MODE (operands[0]) == HImode
19831        || (GET_MODE (operands[0]) == QImode
19832            && (TARGET_PROMOTE_QImode || optimize_size)))"
19833   [(parallel [(set (match_dup 0)
19834                    (neg:SI (match_dup 1)))
19835               (clobber (reg:CC FLAGS_REG))])]
19836   "operands[0] = gen_lowpart (SImode, operands[0]);
19837    operands[1] = gen_lowpart (SImode, operands[1]);")
19838
19839 (define_split
19840   [(set (match_operand 0 "register_operand" "")
19841         (not (match_operand 1 "register_operand" "")))]
19842   "! TARGET_PARTIAL_REG_STALL && reload_completed
19843    && (GET_MODE (operands[0]) == HImode
19844        || (GET_MODE (operands[0]) == QImode
19845            && (TARGET_PROMOTE_QImode || optimize_size)))"
19846   [(set (match_dup 0)
19847         (not:SI (match_dup 1)))]
19848   "operands[0] = gen_lowpart (SImode, operands[0]);
19849    operands[1] = gen_lowpart (SImode, operands[1]);")
19850
19851 (define_split
19852   [(set (match_operand 0 "register_operand" "")
19853         (if_then_else (match_operator 1 "comparison_operator"
19854                                 [(reg FLAGS_REG) (const_int 0)])
19855                       (match_operand 2 "register_operand" "")
19856                       (match_operand 3 "register_operand" "")))]
19857   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19858    && (GET_MODE (operands[0]) == HImode
19859        || (GET_MODE (operands[0]) == QImode
19860            && (TARGET_PROMOTE_QImode || optimize_size)))"
19861   [(set (match_dup 0)
19862         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19863   "operands[0] = gen_lowpart (SImode, operands[0]);
19864    operands[2] = gen_lowpart (SImode, operands[2]);
19865    operands[3] = gen_lowpart (SImode, operands[3]);")
19866
19867 \f
19868 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19869 ;; transform a complex memory operation into two memory to register operations.
19870
19871 ;; Don't push memory operands
19872 (define_peephole2
19873   [(set (match_operand:SI 0 "push_operand" "")
19874         (match_operand:SI 1 "memory_operand" ""))
19875    (match_scratch:SI 2 "r")]
19876   "!optimize_size && !TARGET_PUSH_MEMORY
19877    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19878   [(set (match_dup 2) (match_dup 1))
19879    (set (match_dup 0) (match_dup 2))]
19880   "")
19881
19882 (define_peephole2
19883   [(set (match_operand:DI 0 "push_operand" "")
19884         (match_operand:DI 1 "memory_operand" ""))
19885    (match_scratch:DI 2 "r")]
19886   "!optimize_size && !TARGET_PUSH_MEMORY
19887    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19888   [(set (match_dup 2) (match_dup 1))
19889    (set (match_dup 0) (match_dup 2))]
19890   "")
19891
19892 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19893 ;; SImode pushes.
19894 (define_peephole2
19895   [(set (match_operand:SF 0 "push_operand" "")
19896         (match_operand:SF 1 "memory_operand" ""))
19897    (match_scratch:SF 2 "r")]
19898   "!optimize_size && !TARGET_PUSH_MEMORY
19899    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19900   [(set (match_dup 2) (match_dup 1))
19901    (set (match_dup 0) (match_dup 2))]
19902   "")
19903
19904 (define_peephole2
19905   [(set (match_operand:HI 0 "push_operand" "")
19906         (match_operand:HI 1 "memory_operand" ""))
19907    (match_scratch:HI 2 "r")]
19908   "!optimize_size && !TARGET_PUSH_MEMORY
19909    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19910   [(set (match_dup 2) (match_dup 1))
19911    (set (match_dup 0) (match_dup 2))]
19912   "")
19913
19914 (define_peephole2
19915   [(set (match_operand:QI 0 "push_operand" "")
19916         (match_operand:QI 1 "memory_operand" ""))
19917    (match_scratch:QI 2 "q")]
19918   "!optimize_size && !TARGET_PUSH_MEMORY
19919    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19920   [(set (match_dup 2) (match_dup 1))
19921    (set (match_dup 0) (match_dup 2))]
19922   "")
19923
19924 ;; Don't move an immediate directly to memory when the instruction
19925 ;; gets too big.
19926 (define_peephole2
19927   [(match_scratch:SI 1 "r")
19928    (set (match_operand:SI 0 "memory_operand" "")
19929         (const_int 0))]
19930   "! optimize_size
19931    && ! TARGET_USE_MOV0
19932    && TARGET_SPLIT_LONG_MOVES
19933    && get_attr_length (insn) >= ix86_cost->large_insn
19934    && peep2_regno_dead_p (0, FLAGS_REG)"
19935   [(parallel [(set (match_dup 1) (const_int 0))
19936               (clobber (reg:CC FLAGS_REG))])
19937    (set (match_dup 0) (match_dup 1))]
19938   "")
19939
19940 (define_peephole2
19941   [(match_scratch:HI 1 "r")
19942    (set (match_operand:HI 0 "memory_operand" "")
19943         (const_int 0))]
19944   "! optimize_size
19945    && ! TARGET_USE_MOV0
19946    && TARGET_SPLIT_LONG_MOVES
19947    && get_attr_length (insn) >= ix86_cost->large_insn
19948    && peep2_regno_dead_p (0, FLAGS_REG)"
19949   [(parallel [(set (match_dup 2) (const_int 0))
19950               (clobber (reg:CC FLAGS_REG))])
19951    (set (match_dup 0) (match_dup 1))]
19952   "operands[2] = gen_lowpart (SImode, operands[1]);")
19953
19954 (define_peephole2
19955   [(match_scratch:QI 1 "q")
19956    (set (match_operand:QI 0 "memory_operand" "")
19957         (const_int 0))]
19958   "! optimize_size
19959    && ! TARGET_USE_MOV0
19960    && TARGET_SPLIT_LONG_MOVES
19961    && get_attr_length (insn) >= ix86_cost->large_insn
19962    && peep2_regno_dead_p (0, FLAGS_REG)"
19963   [(parallel [(set (match_dup 2) (const_int 0))
19964               (clobber (reg:CC FLAGS_REG))])
19965    (set (match_dup 0) (match_dup 1))]
19966   "operands[2] = gen_lowpart (SImode, operands[1]);")
19967
19968 (define_peephole2
19969   [(match_scratch:SI 2 "r")
19970    (set (match_operand:SI 0 "memory_operand" "")
19971         (match_operand:SI 1 "immediate_operand" ""))]
19972   "! optimize_size
19973    && get_attr_length (insn) >= ix86_cost->large_insn
19974    && TARGET_SPLIT_LONG_MOVES"
19975   [(set (match_dup 2) (match_dup 1))
19976    (set (match_dup 0) (match_dup 2))]
19977   "")
19978
19979 (define_peephole2
19980   [(match_scratch:HI 2 "r")
19981    (set (match_operand:HI 0 "memory_operand" "")
19982         (match_operand:HI 1 "immediate_operand" ""))]
19983   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19984   && TARGET_SPLIT_LONG_MOVES"
19985   [(set (match_dup 2) (match_dup 1))
19986    (set (match_dup 0) (match_dup 2))]
19987   "")
19988
19989 (define_peephole2
19990   [(match_scratch:QI 2 "q")
19991    (set (match_operand:QI 0 "memory_operand" "")
19992         (match_operand:QI 1 "immediate_operand" ""))]
19993   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19994   && TARGET_SPLIT_LONG_MOVES"
19995   [(set (match_dup 2) (match_dup 1))
19996    (set (match_dup 0) (match_dup 2))]
19997   "")
19998
19999 ;; Don't compare memory with zero, load and use a test instead.
20000 (define_peephole2
20001   [(set (match_operand 0 "flags_reg_operand" "")
20002         (match_operator 1 "compare_operator"
20003           [(match_operand:SI 2 "memory_operand" "")
20004            (const_int 0)]))
20005    (match_scratch:SI 3 "r")]
20006   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
20007   [(set (match_dup 3) (match_dup 2))
20008    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20009   "")
20010
20011 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20012 ;; Don't split NOTs with a displacement operand, because resulting XOR
20013 ;; will not be pairable anyway.
20014 ;;
20015 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20016 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20017 ;; so this split helps here as well.
20018 ;;
20019 ;; Note: Can't do this as a regular split because we can't get proper
20020 ;; lifetime information then.
20021
20022 (define_peephole2
20023   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20024         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20025   "!optimize_size
20026    && peep2_regno_dead_p (0, FLAGS_REG)
20027    && ((TARGET_PENTIUM
20028         && (!MEM_P (operands[0])
20029             || !memory_displacement_operand (operands[0], SImode)))
20030        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
20031   [(parallel [(set (match_dup 0)
20032                    (xor:SI (match_dup 1) (const_int -1)))
20033               (clobber (reg:CC FLAGS_REG))])]
20034   "")
20035
20036 (define_peephole2
20037   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20038         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20039   "!optimize_size
20040    && peep2_regno_dead_p (0, FLAGS_REG)
20041    && ((TARGET_PENTIUM
20042         && (!MEM_P (operands[0])
20043             || !memory_displacement_operand (operands[0], HImode)))
20044        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
20045   [(parallel [(set (match_dup 0)
20046                    (xor:HI (match_dup 1) (const_int -1)))
20047               (clobber (reg:CC FLAGS_REG))])]
20048   "")
20049
20050 (define_peephole2
20051   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20052         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20053   "!optimize_size
20054    && peep2_regno_dead_p (0, FLAGS_REG)
20055    && ((TARGET_PENTIUM
20056         && (!MEM_P (operands[0])
20057             || !memory_displacement_operand (operands[0], QImode)))
20058        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
20059   [(parallel [(set (match_dup 0)
20060                    (xor:QI (match_dup 1) (const_int -1)))
20061               (clobber (reg:CC FLAGS_REG))])]
20062   "")
20063
20064 ;; Non pairable "test imm, reg" instructions can be translated to
20065 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20066 ;; byte opcode instead of two, have a short form for byte operands),
20067 ;; so do it for other CPUs as well.  Given that the value was dead,
20068 ;; this should not create any new dependencies.  Pass on the sub-word
20069 ;; versions if we're concerned about partial register stalls.
20070
20071 (define_peephole2
20072   [(set (match_operand 0 "flags_reg_operand" "")
20073         (match_operator 1 "compare_operator"
20074           [(and:SI (match_operand:SI 2 "register_operand" "")
20075                    (match_operand:SI 3 "immediate_operand" ""))
20076            (const_int 0)]))]
20077   "ix86_match_ccmode (insn, CCNOmode)
20078    && (true_regnum (operands[2]) != 0
20079        || satisfies_constraint_K (operands[3]))
20080    && peep2_reg_dead_p (1, operands[2])"
20081   [(parallel
20082      [(set (match_dup 0)
20083            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20084                             (const_int 0)]))
20085       (set (match_dup 2)
20086            (and:SI (match_dup 2) (match_dup 3)))])]
20087   "")
20088
20089 ;; We don't need to handle HImode case, because it will be promoted to SImode
20090 ;; on ! TARGET_PARTIAL_REG_STALL
20091
20092 (define_peephole2
20093   [(set (match_operand 0 "flags_reg_operand" "")
20094         (match_operator 1 "compare_operator"
20095           [(and:QI (match_operand:QI 2 "register_operand" "")
20096                    (match_operand:QI 3 "immediate_operand" ""))
20097            (const_int 0)]))]
20098   "! TARGET_PARTIAL_REG_STALL
20099    && ix86_match_ccmode (insn, CCNOmode)
20100    && true_regnum (operands[2]) != 0
20101    && peep2_reg_dead_p (1, operands[2])"
20102   [(parallel
20103      [(set (match_dup 0)
20104            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20105                             (const_int 0)]))
20106       (set (match_dup 2)
20107            (and:QI (match_dup 2) (match_dup 3)))])]
20108   "")
20109
20110 (define_peephole2
20111   [(set (match_operand 0 "flags_reg_operand" "")
20112         (match_operator 1 "compare_operator"
20113           [(and:SI
20114              (zero_extract:SI
20115                (match_operand 2 "ext_register_operand" "")
20116                (const_int 8)
20117                (const_int 8))
20118              (match_operand 3 "const_int_operand" ""))
20119            (const_int 0)]))]
20120   "! TARGET_PARTIAL_REG_STALL
20121    && ix86_match_ccmode (insn, CCNOmode)
20122    && true_regnum (operands[2]) != 0
20123    && peep2_reg_dead_p (1, operands[2])"
20124   [(parallel [(set (match_dup 0)
20125                    (match_op_dup 1
20126                      [(and:SI
20127                         (zero_extract:SI
20128                           (match_dup 2)
20129                           (const_int 8)
20130                           (const_int 8))
20131                         (match_dup 3))
20132                       (const_int 0)]))
20133               (set (zero_extract:SI (match_dup 2)
20134                                     (const_int 8)
20135                                     (const_int 8))
20136                    (and:SI
20137                      (zero_extract:SI
20138                        (match_dup 2)
20139                        (const_int 8)
20140                        (const_int 8))
20141                      (match_dup 3)))])]
20142   "")
20143
20144 ;; Don't do logical operations with memory inputs.
20145 (define_peephole2
20146   [(match_scratch:SI 2 "r")
20147    (parallel [(set (match_operand:SI 0 "register_operand" "")
20148                    (match_operator:SI 3 "arith_or_logical_operator"
20149                      [(match_dup 0)
20150                       (match_operand:SI 1 "memory_operand" "")]))
20151               (clobber (reg:CC FLAGS_REG))])]
20152   "! optimize_size && ! TARGET_READ_MODIFY"
20153   [(set (match_dup 2) (match_dup 1))
20154    (parallel [(set (match_dup 0)
20155                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20156               (clobber (reg:CC FLAGS_REG))])]
20157   "")
20158
20159 (define_peephole2
20160   [(match_scratch:SI 2 "r")
20161    (parallel [(set (match_operand:SI 0 "register_operand" "")
20162                    (match_operator:SI 3 "arith_or_logical_operator"
20163                      [(match_operand:SI 1 "memory_operand" "")
20164                       (match_dup 0)]))
20165               (clobber (reg:CC FLAGS_REG))])]
20166   "! optimize_size && ! TARGET_READ_MODIFY"
20167   [(set (match_dup 2) (match_dup 1))
20168    (parallel [(set (match_dup 0)
20169                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20170               (clobber (reg:CC FLAGS_REG))])]
20171   "")
20172
20173 ; Don't do logical operations with memory outputs
20174 ;
20175 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20176 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20177 ; the same decoder scheduling characteristics as the original.
20178
20179 (define_peephole2
20180   [(match_scratch:SI 2 "r")
20181    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20182                    (match_operator:SI 3 "arith_or_logical_operator"
20183                      [(match_dup 0)
20184                       (match_operand:SI 1 "nonmemory_operand" "")]))
20185               (clobber (reg:CC FLAGS_REG))])]
20186   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20187   [(set (match_dup 2) (match_dup 0))
20188    (parallel [(set (match_dup 2)
20189                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20190               (clobber (reg:CC FLAGS_REG))])
20191    (set (match_dup 0) (match_dup 2))]
20192   "")
20193
20194 (define_peephole2
20195   [(match_scratch:SI 2 "r")
20196    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20197                    (match_operator:SI 3 "arith_or_logical_operator"
20198                      [(match_operand:SI 1 "nonmemory_operand" "")
20199                       (match_dup 0)]))
20200               (clobber (reg:CC FLAGS_REG))])]
20201   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20202   [(set (match_dup 2) (match_dup 0))
20203    (parallel [(set (match_dup 2)
20204                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20205               (clobber (reg:CC FLAGS_REG))])
20206    (set (match_dup 0) (match_dup 2))]
20207   "")
20208
20209 ;; Attempt to always use XOR for zeroing registers.
20210 (define_peephole2
20211   [(set (match_operand 0 "register_operand" "")
20212         (match_operand 1 "const0_operand" ""))]
20213   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20214    && (! TARGET_USE_MOV0 || optimize_size)
20215    && GENERAL_REG_P (operands[0])
20216    && peep2_regno_dead_p (0, FLAGS_REG)"
20217   [(parallel [(set (match_dup 0) (const_int 0))
20218               (clobber (reg:CC FLAGS_REG))])]
20219 {
20220   operands[0] = gen_lowpart (word_mode, operands[0]);
20221 })
20222
20223 (define_peephole2
20224   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20225         (const_int 0))]
20226   "(GET_MODE (operands[0]) == QImode
20227     || GET_MODE (operands[0]) == HImode)
20228    && (! TARGET_USE_MOV0 || optimize_size)
20229    && peep2_regno_dead_p (0, FLAGS_REG)"
20230   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20231               (clobber (reg:CC FLAGS_REG))])])
20232
20233 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20234 (define_peephole2
20235   [(set (match_operand 0 "register_operand" "")
20236         (const_int -1))]
20237   "(GET_MODE (operands[0]) == HImode
20238     || GET_MODE (operands[0]) == SImode
20239     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20240    && (optimize_size || TARGET_PENTIUM)
20241    && peep2_regno_dead_p (0, FLAGS_REG)"
20242   [(parallel [(set (match_dup 0) (const_int -1))
20243               (clobber (reg:CC FLAGS_REG))])]
20244   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20245                               operands[0]);")
20246
20247 ;; Attempt to convert simple leas to adds. These can be created by
20248 ;; move expanders.
20249 (define_peephole2
20250   [(set (match_operand:SI 0 "register_operand" "")
20251         (plus:SI (match_dup 0)
20252                  (match_operand:SI 1 "nonmemory_operand" "")))]
20253   "peep2_regno_dead_p (0, FLAGS_REG)"
20254   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20255               (clobber (reg:CC FLAGS_REG))])]
20256   "")
20257
20258 (define_peephole2
20259   [(set (match_operand:SI 0 "register_operand" "")
20260         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20261                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20262   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20263   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20264               (clobber (reg:CC FLAGS_REG))])]
20265   "operands[2] = gen_lowpart (SImode, operands[2]);")
20266
20267 (define_peephole2
20268   [(set (match_operand:DI 0 "register_operand" "")
20269         (plus:DI (match_dup 0)
20270                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20271   "peep2_regno_dead_p (0, FLAGS_REG)"
20272   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20273               (clobber (reg:CC FLAGS_REG))])]
20274   "")
20275
20276 (define_peephole2
20277   [(set (match_operand:SI 0 "register_operand" "")
20278         (mult:SI (match_dup 0)
20279                  (match_operand:SI 1 "const_int_operand" "")))]
20280   "exact_log2 (INTVAL (operands[1])) >= 0
20281    && peep2_regno_dead_p (0, FLAGS_REG)"
20282   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20283               (clobber (reg:CC FLAGS_REG))])]
20284   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20285
20286 (define_peephole2
20287   [(set (match_operand:DI 0 "register_operand" "")
20288         (mult:DI (match_dup 0)
20289                  (match_operand:DI 1 "const_int_operand" "")))]
20290   "exact_log2 (INTVAL (operands[1])) >= 0
20291    && peep2_regno_dead_p (0, FLAGS_REG)"
20292   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20293               (clobber (reg:CC FLAGS_REG))])]
20294   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20295
20296 (define_peephole2
20297   [(set (match_operand:SI 0 "register_operand" "")
20298         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20299                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20300   "exact_log2 (INTVAL (operands[2])) >= 0
20301    && REGNO (operands[0]) == REGNO (operands[1])
20302    && peep2_regno_dead_p (0, FLAGS_REG)"
20303   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20304               (clobber (reg:CC FLAGS_REG))])]
20305   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20306
20307 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20308 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20309 ;; many CPUs it is also faster, since special hardware to avoid esp
20310 ;; dependencies is present.
20311
20312 ;; While some of these conversions may be done using splitters, we use peepholes
20313 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20314
20315 ;; Convert prologue esp subtractions to push.
20316 ;; We need register to push.  In order to keep verify_flow_info happy we have
20317 ;; two choices
20318 ;; - use scratch and clobber it in order to avoid dependencies
20319 ;; - use already live register
20320 ;; We can't use the second way right now, since there is no reliable way how to
20321 ;; verify that given register is live.  First choice will also most likely in
20322 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20323 ;; call clobbered registers are dead.  We may want to use base pointer as an
20324 ;; alternative when no register is available later.
20325
20326 (define_peephole2
20327   [(match_scratch:SI 0 "r")
20328    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20329               (clobber (reg:CC FLAGS_REG))
20330               (clobber (mem:BLK (scratch)))])]
20331   "optimize_size || !TARGET_SUB_ESP_4"
20332   [(clobber (match_dup 0))
20333    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20334               (clobber (mem:BLK (scratch)))])])
20335
20336 (define_peephole2
20337   [(match_scratch:SI 0 "r")
20338    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20339               (clobber (reg:CC FLAGS_REG))
20340               (clobber (mem:BLK (scratch)))])]
20341   "optimize_size || !TARGET_SUB_ESP_8"
20342   [(clobber (match_dup 0))
20343    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20344    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20345               (clobber (mem:BLK (scratch)))])])
20346
20347 ;; Convert esp subtractions to push.
20348 (define_peephole2
20349   [(match_scratch:SI 0 "r")
20350    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20351               (clobber (reg:CC FLAGS_REG))])]
20352   "optimize_size || !TARGET_SUB_ESP_4"
20353   [(clobber (match_dup 0))
20354    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20355
20356 (define_peephole2
20357   [(match_scratch:SI 0 "r")
20358    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20359               (clobber (reg:CC FLAGS_REG))])]
20360   "optimize_size || !TARGET_SUB_ESP_8"
20361   [(clobber (match_dup 0))
20362    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20363    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20364
20365 ;; Convert epilogue deallocator to pop.
20366 (define_peephole2
20367   [(match_scratch:SI 0 "r")
20368    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20369               (clobber (reg:CC FLAGS_REG))
20370               (clobber (mem:BLK (scratch)))])]
20371   "optimize_size || !TARGET_ADD_ESP_4"
20372   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20373               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20374               (clobber (mem:BLK (scratch)))])]
20375   "")
20376
20377 ;; Two pops case is tricky, since pop causes dependency on destination register.
20378 ;; We use two registers if available.
20379 (define_peephole2
20380   [(match_scratch:SI 0 "r")
20381    (match_scratch:SI 1 "r")
20382    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20383               (clobber (reg:CC FLAGS_REG))
20384               (clobber (mem:BLK (scratch)))])]
20385   "optimize_size || !TARGET_ADD_ESP_8"
20386   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20387               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20388               (clobber (mem:BLK (scratch)))])
20389    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20390               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20391   "")
20392
20393 (define_peephole2
20394   [(match_scratch:SI 0 "r")
20395    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20396               (clobber (reg:CC FLAGS_REG))
20397               (clobber (mem:BLK (scratch)))])]
20398   "optimize_size"
20399   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20400               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20401               (clobber (mem:BLK (scratch)))])
20402    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20403               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20404   "")
20405
20406 ;; Convert esp additions to pop.
20407 (define_peephole2
20408   [(match_scratch:SI 0 "r")
20409    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20410               (clobber (reg:CC FLAGS_REG))])]
20411   ""
20412   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20413               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20414   "")
20415
20416 ;; Two pops case is tricky, since pop causes dependency on destination register.
20417 ;; We use two registers if available.
20418 (define_peephole2
20419   [(match_scratch:SI 0 "r")
20420    (match_scratch:SI 1 "r")
20421    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20422               (clobber (reg:CC FLAGS_REG))])]
20423   ""
20424   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20425               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20426    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20427               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20428   "")
20429
20430 (define_peephole2
20431   [(match_scratch:SI 0 "r")
20432    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20433               (clobber (reg:CC FLAGS_REG))])]
20434   "optimize_size"
20435   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20436               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20437    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20438               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20439   "")
20440 \f
20441 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20442 ;; required and register dies.  Similarly for 128 to plus -128.
20443 (define_peephole2
20444   [(set (match_operand 0 "flags_reg_operand" "")
20445         (match_operator 1 "compare_operator"
20446           [(match_operand 2 "register_operand" "")
20447            (match_operand 3 "const_int_operand" "")]))]
20448   "(INTVAL (operands[3]) == -1
20449     || INTVAL (operands[3]) == 1
20450     || INTVAL (operands[3]) == 128)
20451    && ix86_match_ccmode (insn, CCGCmode)
20452    && peep2_reg_dead_p (1, operands[2])"
20453   [(parallel [(set (match_dup 0)
20454                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20455               (clobber (match_dup 2))])]
20456   "")
20457 \f
20458 (define_peephole2
20459   [(match_scratch:DI 0 "r")
20460    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20461               (clobber (reg:CC FLAGS_REG))
20462               (clobber (mem:BLK (scratch)))])]
20463   "optimize_size || !TARGET_SUB_ESP_4"
20464   [(clobber (match_dup 0))
20465    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20466               (clobber (mem:BLK (scratch)))])])
20467
20468 (define_peephole2
20469   [(match_scratch:DI 0 "r")
20470    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20471               (clobber (reg:CC FLAGS_REG))
20472               (clobber (mem:BLK (scratch)))])]
20473   "optimize_size || !TARGET_SUB_ESP_8"
20474   [(clobber (match_dup 0))
20475    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20476    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20477               (clobber (mem:BLK (scratch)))])])
20478
20479 ;; Convert esp subtractions to push.
20480 (define_peephole2
20481   [(match_scratch:DI 0 "r")
20482    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20483               (clobber (reg:CC FLAGS_REG))])]
20484   "optimize_size || !TARGET_SUB_ESP_4"
20485   [(clobber (match_dup 0))
20486    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20487
20488 (define_peephole2
20489   [(match_scratch:DI 0 "r")
20490    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20491               (clobber (reg:CC FLAGS_REG))])]
20492   "optimize_size || !TARGET_SUB_ESP_8"
20493   [(clobber (match_dup 0))
20494    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20495    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20496
20497 ;; Convert epilogue deallocator to pop.
20498 (define_peephole2
20499   [(match_scratch:DI 0 "r")
20500    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20501               (clobber (reg:CC FLAGS_REG))
20502               (clobber (mem:BLK (scratch)))])]
20503   "optimize_size || !TARGET_ADD_ESP_4"
20504   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20505               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20506               (clobber (mem:BLK (scratch)))])]
20507   "")
20508
20509 ;; Two pops case is tricky, since pop causes dependency on destination register.
20510 ;; We use two registers if available.
20511 (define_peephole2
20512   [(match_scratch:DI 0 "r")
20513    (match_scratch:DI 1 "r")
20514    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20515               (clobber (reg:CC FLAGS_REG))
20516               (clobber (mem:BLK (scratch)))])]
20517   "optimize_size || !TARGET_ADD_ESP_8"
20518   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20519               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20520               (clobber (mem:BLK (scratch)))])
20521    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20522               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20523   "")
20524
20525 (define_peephole2
20526   [(match_scratch:DI 0 "r")
20527    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20528               (clobber (reg:CC FLAGS_REG))
20529               (clobber (mem:BLK (scratch)))])]
20530   "optimize_size"
20531   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20532               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20533               (clobber (mem:BLK (scratch)))])
20534    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20535               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20536   "")
20537
20538 ;; Convert esp additions to pop.
20539 (define_peephole2
20540   [(match_scratch:DI 0 "r")
20541    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20542               (clobber (reg:CC FLAGS_REG))])]
20543   ""
20544   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20545               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20546   "")
20547
20548 ;; Two pops case is tricky, since pop causes dependency on destination register.
20549 ;; We use two registers if available.
20550 (define_peephole2
20551   [(match_scratch:DI 0 "r")
20552    (match_scratch:DI 1 "r")
20553    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20554               (clobber (reg:CC FLAGS_REG))])]
20555   ""
20556   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20557               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20558    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20559               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20560   "")
20561
20562 (define_peephole2
20563   [(match_scratch:DI 0 "r")
20564    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20565               (clobber (reg:CC FLAGS_REG))])]
20566   "optimize_size"
20567   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20568               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20569    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20570               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20571   "")
20572 \f
20573 ;; Convert imul by three, five and nine into lea
20574 (define_peephole2
20575   [(parallel
20576     [(set (match_operand:SI 0 "register_operand" "")
20577           (mult:SI (match_operand:SI 1 "register_operand" "")
20578                    (match_operand:SI 2 "const_int_operand" "")))
20579      (clobber (reg:CC FLAGS_REG))])]
20580   "INTVAL (operands[2]) == 3
20581    || INTVAL (operands[2]) == 5
20582    || INTVAL (operands[2]) == 9"
20583   [(set (match_dup 0)
20584         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20585                  (match_dup 1)))]
20586   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20587
20588 (define_peephole2
20589   [(parallel
20590     [(set (match_operand:SI 0 "register_operand" "")
20591           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20592                    (match_operand:SI 2 "const_int_operand" "")))
20593      (clobber (reg:CC FLAGS_REG))])]
20594   "!optimize_size
20595    && (INTVAL (operands[2]) == 3
20596        || INTVAL (operands[2]) == 5
20597        || INTVAL (operands[2]) == 9)"
20598   [(set (match_dup 0) (match_dup 1))
20599    (set (match_dup 0)
20600         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20601                  (match_dup 0)))]
20602   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20603
20604 (define_peephole2
20605   [(parallel
20606     [(set (match_operand:DI 0 "register_operand" "")
20607           (mult:DI (match_operand:DI 1 "register_operand" "")
20608                    (match_operand:DI 2 "const_int_operand" "")))
20609      (clobber (reg:CC FLAGS_REG))])]
20610   "TARGET_64BIT
20611    && (INTVAL (operands[2]) == 3
20612        || INTVAL (operands[2]) == 5
20613        || INTVAL (operands[2]) == 9)"
20614   [(set (match_dup 0)
20615         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20616                  (match_dup 1)))]
20617   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20618
20619 (define_peephole2
20620   [(parallel
20621     [(set (match_operand:DI 0 "register_operand" "")
20622           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20623                    (match_operand:DI 2 "const_int_operand" "")))
20624      (clobber (reg:CC FLAGS_REG))])]
20625   "TARGET_64BIT
20626    && !optimize_size
20627    && (INTVAL (operands[2]) == 3
20628        || INTVAL (operands[2]) == 5
20629        || INTVAL (operands[2]) == 9)"
20630   [(set (match_dup 0) (match_dup 1))
20631    (set (match_dup 0)
20632         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20633                  (match_dup 0)))]
20634   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20635
20636 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20637 ;; imul $32bit_imm, reg, reg is direct decoded.
20638 (define_peephole2
20639   [(match_scratch:DI 3 "r")
20640    (parallel [(set (match_operand:DI 0 "register_operand" "")
20641                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20642                             (match_operand:DI 2 "immediate_operand" "")))
20643               (clobber (reg:CC FLAGS_REG))])]
20644   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20645    && !satisfies_constraint_K (operands[2])"
20646   [(set (match_dup 3) (match_dup 1))
20647    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20648               (clobber (reg:CC FLAGS_REG))])]
20649 "")
20650
20651 (define_peephole2
20652   [(match_scratch:SI 3 "r")
20653    (parallel [(set (match_operand:SI 0 "register_operand" "")
20654                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20655                             (match_operand:SI 2 "immediate_operand" "")))
20656               (clobber (reg:CC FLAGS_REG))])]
20657   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20658    && !satisfies_constraint_K (operands[2])"
20659   [(set (match_dup 3) (match_dup 1))
20660    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20661               (clobber (reg:CC FLAGS_REG))])]
20662 "")
20663
20664 (define_peephole2
20665   [(match_scratch:SI 3 "r")
20666    (parallel [(set (match_operand:DI 0 "register_operand" "")
20667                    (zero_extend:DI
20668                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20669                               (match_operand:SI 2 "immediate_operand" ""))))
20670               (clobber (reg:CC FLAGS_REG))])]
20671   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20672    && !satisfies_constraint_K (operands[2])"
20673   [(set (match_dup 3) (match_dup 1))
20674    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20675               (clobber (reg:CC FLAGS_REG))])]
20676 "")
20677
20678 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20679 ;; Convert it into imul reg, reg
20680 ;; It would be better to force assembler to encode instruction using long
20681 ;; immediate, but there is apparently no way to do so.
20682 (define_peephole2
20683   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20684                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20685                             (match_operand:DI 2 "const_int_operand" "")))
20686               (clobber (reg:CC FLAGS_REG))])
20687    (match_scratch:DI 3 "r")]
20688   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20689    && satisfies_constraint_K (operands[2])"
20690   [(set (match_dup 3) (match_dup 2))
20691    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20692               (clobber (reg:CC FLAGS_REG))])]
20693 {
20694   if (!rtx_equal_p (operands[0], operands[1]))
20695     emit_move_insn (operands[0], operands[1]);
20696 })
20697
20698 (define_peephole2
20699   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20700                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20701                             (match_operand:SI 2 "const_int_operand" "")))
20702               (clobber (reg:CC FLAGS_REG))])
20703    (match_scratch:SI 3 "r")]
20704   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20705    && satisfies_constraint_K (operands[2])"
20706   [(set (match_dup 3) (match_dup 2))
20707    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20708               (clobber (reg:CC FLAGS_REG))])]
20709 {
20710   if (!rtx_equal_p (operands[0], operands[1]))
20711     emit_move_insn (operands[0], operands[1]);
20712 })
20713
20714 (define_peephole2
20715   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20716                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20717                             (match_operand:HI 2 "immediate_operand" "")))
20718               (clobber (reg:CC FLAGS_REG))])
20719    (match_scratch:HI 3 "r")]
20720   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size"
20721   [(set (match_dup 3) (match_dup 2))
20722    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20723               (clobber (reg:CC FLAGS_REG))])]
20724 {
20725   if (!rtx_equal_p (operands[0], operands[1]))
20726     emit_move_insn (operands[0], operands[1]);
20727 })
20728
20729 ;; After splitting up read-modify operations, array accesses with memory
20730 ;; operands might end up in form:
20731 ;;  sall    $2, %eax
20732 ;;  movl    4(%esp), %edx
20733 ;;  addl    %edx, %eax
20734 ;; instead of pre-splitting:
20735 ;;  sall    $2, %eax
20736 ;;  addl    4(%esp), %eax
20737 ;; Turn it into:
20738 ;;  movl    4(%esp), %edx
20739 ;;  leal    (%edx,%eax,4), %eax
20740
20741 (define_peephole2
20742   [(parallel [(set (match_operand 0 "register_operand" "")
20743                    (ashift (match_operand 1 "register_operand" "")
20744                            (match_operand 2 "const_int_operand" "")))
20745                (clobber (reg:CC FLAGS_REG))])
20746    (set (match_operand 3 "register_operand")
20747         (match_operand 4 "x86_64_general_operand" ""))
20748    (parallel [(set (match_operand 5 "register_operand" "")
20749                    (plus (match_operand 6 "register_operand" "")
20750                          (match_operand 7 "register_operand" "")))
20751                    (clobber (reg:CC FLAGS_REG))])]
20752   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20753    /* Validate MODE for lea.  */
20754    && ((!TARGET_PARTIAL_REG_STALL
20755         && (GET_MODE (operands[0]) == QImode
20756             || GET_MODE (operands[0]) == HImode))
20757        || GET_MODE (operands[0]) == SImode
20758        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20759    /* We reorder load and the shift.  */
20760    && !rtx_equal_p (operands[1], operands[3])
20761    && !reg_overlap_mentioned_p (operands[0], operands[4])
20762    /* Last PLUS must consist of operand 0 and 3.  */
20763    && !rtx_equal_p (operands[0], operands[3])
20764    && (rtx_equal_p (operands[3], operands[6])
20765        || rtx_equal_p (operands[3], operands[7]))
20766    && (rtx_equal_p (operands[0], operands[6])
20767        || rtx_equal_p (operands[0], operands[7]))
20768    /* The intermediate operand 0 must die or be same as output.  */
20769    && (rtx_equal_p (operands[0], operands[5])
20770        || peep2_reg_dead_p (3, operands[0]))"
20771   [(set (match_dup 3) (match_dup 4))
20772    (set (match_dup 0) (match_dup 1))]
20773 {
20774   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20775   int scale = 1 << INTVAL (operands[2]);
20776   rtx index = gen_lowpart (Pmode, operands[1]);
20777   rtx base = gen_lowpart (Pmode, operands[3]);
20778   rtx dest = gen_lowpart (mode, operands[5]);
20779
20780   operands[1] = gen_rtx_PLUS (Pmode, base,
20781                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20782   if (mode != Pmode)
20783     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20784   operands[0] = dest;
20785 })
20786 \f
20787 ;; Call-value patterns last so that the wildcard operand does not
20788 ;; disrupt insn-recog's switch tables.
20789
20790 (define_insn "*call_value_pop_0"
20791   [(set (match_operand 0 "" "")
20792         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20793               (match_operand:SI 2 "" "")))
20794    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20795                             (match_operand:SI 3 "immediate_operand" "")))]
20796   "!TARGET_64BIT"
20797 {
20798   if (SIBLING_CALL_P (insn))
20799     return "jmp\t%P1";
20800   else
20801     return "call\t%P1";
20802 }
20803   [(set_attr "type" "callv")])
20804
20805 (define_insn "*call_value_pop_1"
20806   [(set (match_operand 0 "" "")
20807         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20808               (match_operand:SI 2 "" "")))
20809    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20810                             (match_operand:SI 3 "immediate_operand" "i")))]
20811   "!TARGET_64BIT"
20812 {
20813   if (constant_call_address_operand (operands[1], Pmode))
20814     {
20815       if (SIBLING_CALL_P (insn))
20816         return "jmp\t%P1";
20817       else
20818         return "call\t%P1";
20819     }
20820   if (SIBLING_CALL_P (insn))
20821     return "jmp\t%A1";
20822   else
20823     return "call\t%A1";
20824 }
20825   [(set_attr "type" "callv")])
20826
20827 (define_insn "*call_value_0"
20828   [(set (match_operand 0 "" "")
20829         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20830               (match_operand:SI 2 "" "")))]
20831   "!TARGET_64BIT"
20832 {
20833   if (SIBLING_CALL_P (insn))
20834     return "jmp\t%P1";
20835   else
20836     return "call\t%P1";
20837 }
20838   [(set_attr "type" "callv")])
20839
20840 (define_insn "*call_value_0_rex64"
20841   [(set (match_operand 0 "" "")
20842         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20843               (match_operand:DI 2 "const_int_operand" "")))]
20844   "TARGET_64BIT"
20845 {
20846   if (SIBLING_CALL_P (insn))
20847     return "jmp\t%P1";
20848   else
20849     return "call\t%P1";
20850 }
20851   [(set_attr "type" "callv")])
20852
20853 (define_insn "*call_value_1"
20854   [(set (match_operand 0 "" "")
20855         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20856               (match_operand:SI 2 "" "")))]
20857   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20858 {
20859   if (constant_call_address_operand (operands[1], Pmode))
20860     return "call\t%P1";
20861   return "call\t%A1";
20862 }
20863   [(set_attr "type" "callv")])
20864
20865 (define_insn "*sibcall_value_1"
20866   [(set (match_operand 0 "" "")
20867         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20868               (match_operand:SI 2 "" "")))]
20869   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20870 {
20871   if (constant_call_address_operand (operands[1], Pmode))
20872     return "jmp\t%P1";
20873   return "jmp\t%A1";
20874 }
20875   [(set_attr "type" "callv")])
20876
20877 (define_insn "*call_value_1_rex64"
20878   [(set (match_operand 0 "" "")
20879         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20880               (match_operand:DI 2 "" "")))]
20881   "!SIBLING_CALL_P (insn) && TARGET_64BIT
20882    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20883 {
20884   if (constant_call_address_operand (operands[1], Pmode))
20885     return "call\t%P1";
20886   return "call\t%A1";
20887 }
20888   [(set_attr "type" "callv")])
20889
20890 (define_insn "*call_value_1_rex64_large"
20891   [(set (match_operand 0 "" "")
20892         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20893               (match_operand:DI 2 "" "")))]
20894   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20895   "call\t%A1"
20896   [(set_attr "type" "callv")])
20897
20898 (define_insn "*sibcall_value_1_rex64"
20899   [(set (match_operand 0 "" "")
20900         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20901               (match_operand:DI 2 "" "")))]
20902   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20903   "jmp\t%P1"
20904   [(set_attr "type" "callv")])
20905
20906 (define_insn "*sibcall_value_1_rex64_v"
20907   [(set (match_operand 0 "" "")
20908         (call (mem:QI (reg:DI R11_REG))
20909               (match_operand:DI 1 "" "")))]
20910   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20911   "jmp\t*%%r11"
20912   [(set_attr "type" "callv")])
20913 \f
20914 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20915 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20916 ;; caught for use by garbage collectors and the like.  Using an insn that
20917 ;; maps to SIGILL makes it more likely the program will rightfully die.
20918 ;; Keeping with tradition, "6" is in honor of #UD.
20919 (define_insn "trap"
20920   [(trap_if (const_int 1) (const_int 6))]
20921   ""
20922   { return ASM_SHORT "0x0b0f"; }
20923   [(set_attr "length" "2")])
20924
20925 (define_expand "sse_prologue_save"
20926   [(parallel [(set (match_operand:BLK 0 "" "")
20927                    (unspec:BLK [(reg:DI 21)
20928                                 (reg:DI 22)
20929                                 (reg:DI 23)
20930                                 (reg:DI 24)
20931                                 (reg:DI 25)
20932                                 (reg:DI 26)
20933                                 (reg:DI 27)
20934                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20935               (use (match_operand:DI 1 "register_operand" ""))
20936               (use (match_operand:DI 2 "immediate_operand" ""))
20937               (use (label_ref:DI (match_operand 3 "" "")))])]
20938   "TARGET_64BIT"
20939   "")
20940
20941 (define_insn "*sse_prologue_save_insn"
20942   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20943                           (match_operand:DI 4 "const_int_operand" "n")))
20944         (unspec:BLK [(reg:DI 21)
20945                      (reg:DI 22)
20946                      (reg:DI 23)
20947                      (reg:DI 24)
20948                      (reg:DI 25)
20949                      (reg:DI 26)
20950                      (reg:DI 27)
20951                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20952    (use (match_operand:DI 1 "register_operand" "r"))
20953    (use (match_operand:DI 2 "const_int_operand" "i"))
20954    (use (label_ref:DI (match_operand 3 "" "X")))]
20955   "TARGET_64BIT
20956    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20957    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20958   "*
20959 {
20960   int i;
20961   operands[0] = gen_rtx_MEM (Pmode,
20962                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20963   output_asm_insn (\"jmp\\t%A1\", operands);
20964   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20965     {
20966       operands[4] = adjust_address (operands[0], DImode, i*16);
20967       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20968       PUT_MODE (operands[4], TImode);
20969       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20970         output_asm_insn (\"rex\", operands);
20971       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20972     }
20973   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20974                              CODE_LABEL_NUMBER (operands[3]));
20975   return \"\";
20976 }
20977   "
20978   [(set_attr "type" "other")
20979    (set_attr "length_immediate" "0")
20980    (set_attr "length_address" "0")
20981    (set_attr "length" "135")
20982    (set_attr "memory" "store")
20983    (set_attr "modrm" "0")
20984    (set_attr "mode" "DI")])
20985
20986 (define_expand "prefetch"
20987   [(prefetch (match_operand 0 "address_operand" "")
20988              (match_operand:SI 1 "const_int_operand" "")
20989              (match_operand:SI 2 "const_int_operand" ""))]
20990   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20991 {
20992   int rw = INTVAL (operands[1]);
20993   int locality = INTVAL (operands[2]);
20994
20995   gcc_assert (rw == 0 || rw == 1);
20996   gcc_assert (locality >= 0 && locality <= 3);
20997   gcc_assert (GET_MODE (operands[0]) == Pmode
20998               || GET_MODE (operands[0]) == VOIDmode);
20999
21000   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21001      supported by SSE counterpart or the SSE prefetch is not available
21002      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21003      of locality.  */
21004   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21005     operands[2] = GEN_INT (3);
21006   else
21007     operands[1] = const0_rtx;
21008 })
21009
21010 (define_insn "*prefetch_sse"
21011   [(prefetch (match_operand:SI 0 "address_operand" "p")
21012              (const_int 0)
21013              (match_operand:SI 1 "const_int_operand" ""))]
21014   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21015 {
21016   static const char * const patterns[4] = {
21017    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21018   };
21019
21020   int locality = INTVAL (operands[1]);
21021   gcc_assert (locality >= 0 && locality <= 3);
21022
21023   return patterns[locality];
21024 }
21025   [(set_attr "type" "sse")
21026    (set_attr "memory" "none")])
21027
21028 (define_insn "*prefetch_sse_rex"
21029   [(prefetch (match_operand:DI 0 "address_operand" "p")
21030              (const_int 0)
21031              (match_operand:SI 1 "const_int_operand" ""))]
21032   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21033 {
21034   static const char * const patterns[4] = {
21035    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21036   };
21037
21038   int locality = INTVAL (operands[1]);
21039   gcc_assert (locality >= 0 && locality <= 3);
21040
21041   return patterns[locality];
21042 }
21043   [(set_attr "type" "sse")
21044    (set_attr "memory" "none")])
21045
21046 (define_insn "*prefetch_3dnow"
21047   [(prefetch (match_operand:SI 0 "address_operand" "p")
21048              (match_operand:SI 1 "const_int_operand" "n")
21049              (const_int 3))]
21050   "TARGET_3DNOW && !TARGET_64BIT"
21051 {
21052   if (INTVAL (operands[1]) == 0)
21053     return "prefetch\t%a0";
21054   else
21055     return "prefetchw\t%a0";
21056 }
21057   [(set_attr "type" "mmx")
21058    (set_attr "memory" "none")])
21059
21060 (define_insn "*prefetch_3dnow_rex"
21061   [(prefetch (match_operand:DI 0 "address_operand" "p")
21062              (match_operand:SI 1 "const_int_operand" "n")
21063              (const_int 3))]
21064   "TARGET_3DNOW && TARGET_64BIT"
21065 {
21066   if (INTVAL (operands[1]) == 0)
21067     return "prefetch\t%a0";
21068   else
21069     return "prefetchw\t%a0";
21070 }
21071   [(set_attr "type" "mmx")
21072    (set_attr "memory" "none")])
21073
21074 (define_expand "stack_protect_set"
21075   [(match_operand 0 "memory_operand" "")
21076    (match_operand 1 "memory_operand" "")]
21077   ""
21078 {
21079 #ifdef TARGET_THREAD_SSP_OFFSET
21080   if (TARGET_64BIT)
21081     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21082                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21083   else
21084     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21085                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21086 #else
21087   if (TARGET_64BIT)
21088     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21089   else
21090     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21091 #endif
21092   DONE;
21093 })
21094
21095 (define_insn "stack_protect_set_si"
21096   [(set (match_operand:SI 0 "memory_operand" "=m")
21097         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21098    (set (match_scratch:SI 2 "=&r") (const_int 0))
21099    (clobber (reg:CC FLAGS_REG))]
21100   ""
21101   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21102   [(set_attr "type" "multi")])
21103
21104 (define_insn "stack_protect_set_di"
21105   [(set (match_operand:DI 0 "memory_operand" "=m")
21106         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21107    (set (match_scratch:DI 2 "=&r") (const_int 0))
21108    (clobber (reg:CC FLAGS_REG))]
21109   "TARGET_64BIT"
21110   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21111   [(set_attr "type" "multi")])
21112
21113 (define_insn "stack_tls_protect_set_si"
21114   [(set (match_operand:SI 0 "memory_operand" "=m")
21115         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21116    (set (match_scratch:SI 2 "=&r") (const_int 0))
21117    (clobber (reg:CC FLAGS_REG))]
21118   ""
21119   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21120   [(set_attr "type" "multi")])
21121
21122 (define_insn "stack_tls_protect_set_di"
21123   [(set (match_operand:DI 0 "memory_operand" "=m")
21124         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21125    (set (match_scratch:DI 2 "=&r") (const_int 0))
21126    (clobber (reg:CC FLAGS_REG))]
21127   "TARGET_64BIT"
21128   {
21129      /* The kernel uses a different segment register for performance reasons; a
21130         system call would not have to trash the userspace segment register,
21131         which would be expensive */
21132      if (ix86_cmodel != CM_KERNEL)
21133         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21134      else
21135         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21136   }
21137   [(set_attr "type" "multi")])
21138
21139 (define_expand "stack_protect_test"
21140   [(match_operand 0 "memory_operand" "")
21141    (match_operand 1 "memory_operand" "")
21142    (match_operand 2 "" "")]
21143   ""
21144 {
21145   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21146   ix86_compare_op0 = operands[0];
21147   ix86_compare_op1 = operands[1];
21148   ix86_compare_emitted = flags;
21149
21150 #ifdef TARGET_THREAD_SSP_OFFSET
21151   if (TARGET_64BIT)
21152     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21153                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21154   else
21155     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21156                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21157 #else
21158   if (TARGET_64BIT)
21159     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21160   else
21161     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21162 #endif
21163   emit_jump_insn (gen_beq (operands[2]));
21164   DONE;
21165 })
21166
21167 (define_insn "stack_protect_test_si"
21168   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21169         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21170                      (match_operand:SI 2 "memory_operand" "m")]
21171                     UNSPEC_SP_TEST))
21172    (clobber (match_scratch:SI 3 "=&r"))]
21173   ""
21174   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21175   [(set_attr "type" "multi")])
21176
21177 (define_insn "stack_protect_test_di"
21178   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21179         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21180                      (match_operand:DI 2 "memory_operand" "m")]
21181                     UNSPEC_SP_TEST))
21182    (clobber (match_scratch:DI 3 "=&r"))]
21183   "TARGET_64BIT"
21184   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21185   [(set_attr "type" "multi")])
21186
21187 (define_insn "stack_tls_protect_test_si"
21188   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21189         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21190                      (match_operand:SI 2 "const_int_operand" "i")]
21191                     UNSPEC_SP_TLS_TEST))
21192    (clobber (match_scratch:SI 3 "=r"))]
21193   ""
21194   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21195   [(set_attr "type" "multi")])
21196
21197 (define_insn "stack_tls_protect_test_di"
21198   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21199         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21200                      (match_operand:DI 2 "const_int_operand" "i")]
21201                     UNSPEC_SP_TLS_TEST))
21202    (clobber (match_scratch:DI 3 "=r"))]
21203   "TARGET_64BIT"
21204   {
21205      /* The kernel uses a different segment register for performance reasons; a
21206         system call would not have to trash the userspace segment register,
21207         which would be expensive */
21208      if (ix86_cmodel != CM_KERNEL)
21209         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21210      else
21211         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21212   }
21213   [(set_attr "type" "multi")])
21214
21215 (include "mmx.md")
21216 (include "sse.md")
21217 (include "sync.md")