OSDN Git Service

* config/i386/i386.c (output_387_reg_move): Handle memory operand[0].
[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 "cmp<mode>"
843   [(set (reg:CC FLAGS_REG)
844         (compare:CC (match_operand:SSEMODEF 0 "cmp_fp_expander_operand" "")
845                     (match_operand:SSEMODEF 1 "cmp_fp_expander_operand" "")))]
846   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
847 {
848   ix86_compare_op0 = operands[0];
849   ix86_compare_op1 = operands[1];
850   DONE;
851 })
852
853 ;; FP compares, step 1:
854 ;; Set the FP condition codes.
855 ;;
856 ;; CCFPmode     compare with exceptions
857 ;; CCFPUmode    compare with no exceptions
858
859 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
860 ;; used to manage the reg stack popping would not be preserved.
861
862 (define_insn "*cmpfp_0"
863   [(set (match_operand:HI 0 "register_operand" "=a")
864         (unspec:HI
865           [(compare:CCFP
866              (match_operand 1 "register_operand" "f")
867              (match_operand 2 "const0_operand" "X"))]
868         UNSPEC_FNSTSW))]
869   "TARGET_80387
870    && FLOAT_MODE_P (GET_MODE (operands[1]))
871    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
872   "* return output_fp_compare (insn, operands, 0, 0);"
873   [(set_attr "type" "multi")
874    (set_attr "unit" "i387")
875    (set (attr "mode")
876      (cond [(match_operand:SF 1 "" "")
877               (const_string "SF")
878             (match_operand:DF 1 "" "")
879               (const_string "DF")
880            ]
881            (const_string "XF")))])
882
883 (define_insn "*cmpfp_xf"
884   [(set (match_operand:HI 0 "register_operand" "=a")
885         (unspec:HI
886           [(compare:CCFP
887              (match_operand:XF 1 "register_operand" "f")
888              (match_operand:XF 2 "register_operand" "f"))]
889           UNSPEC_FNSTSW))]
890   "TARGET_80387"
891   "* return output_fp_compare (insn, operands, 0, 0);"
892   [(set_attr "type" "multi")
893    (set_attr "unit" "i387")
894    (set_attr "mode" "XF")])
895
896 (define_insn "*cmpfp_<mode>"
897   [(set (match_operand:HI 0 "register_operand" "=a")
898         (unspec:HI
899           [(compare:CCFP
900              (match_operand:X87MODEF12 1 "register_operand" "f")
901              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm"))]
902           UNSPEC_FNSTSW))]
903   "TARGET_80387"
904   "* return output_fp_compare (insn, operands, 0, 0);"
905   [(set_attr "type" "multi")
906    (set_attr "unit" "i387")
907    (set_attr "mode" "<MODE>")])
908
909 (define_insn "*cmpfp_u"
910   [(set (match_operand:HI 0 "register_operand" "=a")
911         (unspec:HI
912           [(compare:CCFPU
913              (match_operand 1 "register_operand" "f")
914              (match_operand 2 "register_operand" "f"))]
915           UNSPEC_FNSTSW))]
916   "TARGET_80387
917    && FLOAT_MODE_P (GET_MODE (operands[1]))
918    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
919   "* return output_fp_compare (insn, operands, 0, 1);"
920   [(set_attr "type" "multi")
921    (set_attr "unit" "i387")
922    (set (attr "mode")
923      (cond [(match_operand:SF 1 "" "")
924               (const_string "SF")
925             (match_operand:DF 1 "" "")
926               (const_string "DF")
927            ]
928            (const_string "XF")))])
929
930 (define_insn "*cmpfp_<mode>"
931   [(set (match_operand:HI 0 "register_operand" "=a")
932         (unspec:HI
933           [(compare:CCFP
934              (match_operand 1 "register_operand" "f")
935              (match_operator 3 "float_operator"
936                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
937           UNSPEC_FNSTSW))]
938   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
939    && FLOAT_MODE_P (GET_MODE (operands[1]))
940    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
941   "* return output_fp_compare (insn, operands, 0, 0);"
942   [(set_attr "type" "multi")
943    (set_attr "unit" "i387")
944    (set_attr "fp_int_src" "true")
945    (set_attr "mode" "<MODE>")])
946
947 ;; FP compares, step 2
948 ;; Move the fpsw to ax.
949
950 (define_insn "x86_fnstsw_1"
951   [(set (match_operand:HI 0 "register_operand" "=a")
952         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
953   "TARGET_80387"
954   "fnstsw\t%0"
955   [(set_attr "length" "2")
956    (set_attr "mode" "SI")
957    (set_attr "unit" "i387")])
958
959 ;; FP compares, step 3
960 ;; Get ax into flags, general case.
961
962 (define_insn "x86_sahf_1"
963   [(set (reg:CC FLAGS_REG)
964         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
965                    UNSPEC_SAHF))]
966   "TARGET_SAHF"
967 {
968 #ifdef HAVE_AS_IX86_SAHF
969   return "sahf";
970 #else
971   return ".byte\t0x9e";
972 #endif
973 }
974   [(set_attr "length" "1")
975    (set_attr "athlon_decode" "vector")
976    (set_attr "amdfam10_decode" "direct")
977    (set_attr "mode" "SI")])
978
979 ;; Pentium Pro can do steps 1 through 3 in one go.
980 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes) 
981 (define_insn "*cmpfp_i_mixed"
982   [(set (reg:CCFP FLAGS_REG)
983         (compare:CCFP (match_operand 0 "register_operand" "f,x")
984                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
985   "TARGET_MIX_SSE_I387
986    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
987    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
988   "* return output_fp_compare (insn, operands, 1, 0);"
989   [(set_attr "type" "fcmp,ssecomi")
990    (set (attr "mode")
991      (if_then_else (match_operand:SF 1 "" "")
992         (const_string "SF")
993         (const_string "DF")))
994    (set_attr "athlon_decode" "vector")
995    (set_attr "amdfam10_decode" "direct")])
996
997 (define_insn "*cmpfp_i_sse"
998   [(set (reg:CCFP FLAGS_REG)
999         (compare:CCFP (match_operand 0 "register_operand" "x")
1000                       (match_operand 1 "nonimmediate_operand" "xm")))]
1001   "TARGET_SSE_MATH
1002    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1003    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1004   "* return output_fp_compare (insn, operands, 1, 0);"
1005   [(set_attr "type" "ssecomi")
1006    (set (attr "mode")
1007      (if_then_else (match_operand:SF 1 "" "")
1008         (const_string "SF")
1009         (const_string "DF")))
1010    (set_attr "athlon_decode" "vector")
1011    (set_attr "amdfam10_decode" "direct")])
1012
1013 (define_insn "*cmpfp_i_i387"
1014   [(set (reg:CCFP FLAGS_REG)
1015         (compare:CCFP (match_operand 0 "register_operand" "f")
1016                       (match_operand 1 "register_operand" "f")))]
1017   "TARGET_80387 && TARGET_CMOVE
1018    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1019    && FLOAT_MODE_P (GET_MODE (operands[0]))
1020    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1021   "* return output_fp_compare (insn, operands, 1, 0);"
1022   [(set_attr "type" "fcmp")
1023    (set (attr "mode")
1024      (cond [(match_operand:SF 1 "" "")
1025               (const_string "SF")
1026             (match_operand:DF 1 "" "")
1027               (const_string "DF")
1028            ]
1029            (const_string "XF")))
1030    (set_attr "athlon_decode" "vector")
1031    (set_attr "amdfam10_decode" "direct")])
1032
1033 (define_insn "*cmpfp_iu_mixed"
1034   [(set (reg:CCFPU FLAGS_REG)
1035         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1036                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1037   "TARGET_MIX_SSE_I387
1038    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1039    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1040   "* return output_fp_compare (insn, operands, 1, 1);"
1041   [(set_attr "type" "fcmp,ssecomi")
1042    (set (attr "mode")
1043      (if_then_else (match_operand:SF 1 "" "")
1044         (const_string "SF")
1045         (const_string "DF")))
1046    (set_attr "athlon_decode" "vector")
1047    (set_attr "amdfam10_decode" "direct")])
1048
1049 (define_insn "*cmpfp_iu_sse"
1050   [(set (reg:CCFPU FLAGS_REG)
1051         (compare:CCFPU (match_operand 0 "register_operand" "x")
1052                        (match_operand 1 "nonimmediate_operand" "xm")))]
1053   "TARGET_SSE_MATH
1054    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1055    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1056   "* return output_fp_compare (insn, operands, 1, 1);"
1057   [(set_attr "type" "ssecomi")
1058    (set (attr "mode")
1059      (if_then_else (match_operand:SF 1 "" "")
1060         (const_string "SF")
1061         (const_string "DF")))
1062    (set_attr "athlon_decode" "vector")
1063    (set_attr "amdfam10_decode" "direct")])
1064
1065 (define_insn "*cmpfp_iu_387"
1066   [(set (reg:CCFPU FLAGS_REG)
1067         (compare:CCFPU (match_operand 0 "register_operand" "f")
1068                        (match_operand 1 "register_operand" "f")))]
1069   "TARGET_80387 && TARGET_CMOVE
1070    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1071    && FLOAT_MODE_P (GET_MODE (operands[0]))
1072    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1073   "* return output_fp_compare (insn, operands, 1, 1);"
1074   [(set_attr "type" "fcmp")
1075    (set (attr "mode")
1076      (cond [(match_operand:SF 1 "" "")
1077               (const_string "SF")
1078             (match_operand:DF 1 "" "")
1079               (const_string "DF")
1080            ]
1081            (const_string "XF")))
1082    (set_attr "athlon_decode" "vector")
1083    (set_attr "amdfam10_decode" "direct")])
1084 \f
1085 ;; Move instructions.
1086
1087 ;; General case of fullword move.
1088
1089 (define_expand "movsi"
1090   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1091         (match_operand:SI 1 "general_operand" ""))]
1092   ""
1093   "ix86_expand_move (SImode, operands); DONE;")
1094
1095 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1096 ;; general_operand.
1097 ;;
1098 ;; %%% We don't use a post-inc memory reference because x86 is not a
1099 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1100 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1101 ;; targets without our curiosities, and it is just as easy to represent
1102 ;; this differently.
1103
1104 (define_insn "*pushsi2"
1105   [(set (match_operand:SI 0 "push_operand" "=<")
1106         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1107   "!TARGET_64BIT"
1108   "push{l}\t%1"
1109   [(set_attr "type" "push")
1110    (set_attr "mode" "SI")])
1111
1112 ;; For 64BIT abi we always round up to 8 bytes.
1113 (define_insn "*pushsi2_rex64"
1114   [(set (match_operand:SI 0 "push_operand" "=X")
1115         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1116   "TARGET_64BIT"
1117   "push{q}\t%q1"
1118   [(set_attr "type" "push")
1119    (set_attr "mode" "SI")])
1120
1121 (define_insn "*pushsi2_prologue"
1122   [(set (match_operand:SI 0 "push_operand" "=<")
1123         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1124    (clobber (mem:BLK (scratch)))]
1125   "!TARGET_64BIT"
1126   "push{l}\t%1"
1127   [(set_attr "type" "push")
1128    (set_attr "mode" "SI")])
1129
1130 (define_insn "*popsi1_epilogue"
1131   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1132         (mem:SI (reg:SI SP_REG)))
1133    (set (reg:SI SP_REG)
1134         (plus:SI (reg:SI SP_REG) (const_int 4)))
1135    (clobber (mem:BLK (scratch)))]
1136   "!TARGET_64BIT"
1137   "pop{l}\t%0"
1138   [(set_attr "type" "pop")
1139    (set_attr "mode" "SI")])
1140
1141 (define_insn "popsi1"
1142   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1143         (mem:SI (reg:SI SP_REG)))
1144    (set (reg:SI SP_REG)
1145         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1146   "!TARGET_64BIT"
1147   "pop{l}\t%0"
1148   [(set_attr "type" "pop")
1149    (set_attr "mode" "SI")])
1150
1151 (define_insn "*movsi_xor"
1152   [(set (match_operand:SI 0 "register_operand" "=r")
1153         (match_operand:SI 1 "const0_operand" "i"))
1154    (clobber (reg:CC FLAGS_REG))]
1155   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1156   "xor{l}\t%0, %0"
1157   [(set_attr "type" "alu1")
1158    (set_attr "mode" "SI")
1159    (set_attr "length_immediate" "0")])
1160
1161 (define_insn "*movsi_or"
1162   [(set (match_operand:SI 0 "register_operand" "=r")
1163         (match_operand:SI 1 "immediate_operand" "i"))
1164    (clobber (reg:CC FLAGS_REG))]
1165   "reload_completed
1166    && operands[1] == constm1_rtx
1167    && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1168 {
1169   operands[1] = constm1_rtx;
1170   return "or{l}\t{%1, %0|%0, %1}";
1171 }
1172   [(set_attr "type" "alu1")
1173    (set_attr "mode" "SI")
1174    (set_attr "length_immediate" "1")])
1175
1176 (define_insn "*movsi_1"
1177   [(set (match_operand:SI 0 "nonimmediate_operand"
1178                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1179         (match_operand:SI 1 "general_operand"
1180                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1181   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1182 {
1183   switch (get_attr_type (insn))
1184     {
1185     case TYPE_SSELOG1:
1186       if (get_attr_mode (insn) == MODE_TI)
1187         return "pxor\t%0, %0";
1188       return "xorps\t%0, %0";
1189
1190     case TYPE_SSEMOV:
1191       switch (get_attr_mode (insn))
1192         {
1193         case MODE_TI:
1194           return "movdqa\t{%1, %0|%0, %1}";
1195         case MODE_V4SF:
1196           return "movaps\t{%1, %0|%0, %1}";
1197         case MODE_SI:
1198           return "movd\t{%1, %0|%0, %1}";
1199         case MODE_SF:
1200           return "movss\t{%1, %0|%0, %1}";
1201         default:
1202           gcc_unreachable ();
1203         }
1204
1205     case TYPE_MMXADD:
1206       return "pxor\t%0, %0";
1207
1208     case TYPE_MMXMOV:
1209       if (get_attr_mode (insn) == MODE_DI)
1210         return "movq\t{%1, %0|%0, %1}";
1211       return "movd\t{%1, %0|%0, %1}";
1212
1213     case TYPE_LEA:
1214       return "lea{l}\t{%1, %0|%0, %1}";
1215
1216     default:
1217       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1218       return "mov{l}\t{%1, %0|%0, %1}";
1219     }
1220 }
1221   [(set (attr "type")
1222      (cond [(eq_attr "alternative" "2")
1223               (const_string "mmxadd")
1224             (eq_attr "alternative" "3,4,5")
1225               (const_string "mmxmov")
1226             (eq_attr "alternative" "6")
1227               (const_string "sselog1")
1228             (eq_attr "alternative" "7,8,9,10,11")
1229               (const_string "ssemov")
1230             (match_operand:DI 1 "pic_32bit_operand" "")
1231               (const_string "lea")
1232            ]
1233            (const_string "imov")))
1234    (set (attr "mode")
1235      (cond [(eq_attr "alternative" "2,3")
1236               (const_string "DI")
1237             (eq_attr "alternative" "6,7")
1238               (if_then_else
1239                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1240                 (const_string "V4SF")
1241                 (const_string "TI"))
1242             (and (eq_attr "alternative" "8,9,10,11")
1243                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1244               (const_string "SF")
1245            ]
1246            (const_string "SI")))])
1247
1248 ;; Stores and loads of ax to arbitrary constant address.
1249 ;; We fake an second form of instruction to force reload to load address
1250 ;; into register when rax is not available
1251 (define_insn "*movabssi_1_rex64"
1252   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1253         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1254   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1255   "@
1256    movabs{l}\t{%1, %P0|%P0, %1}
1257    mov{l}\t{%1, %a0|%a0, %1}"
1258   [(set_attr "type" "imov")
1259    (set_attr "modrm" "0,*")
1260    (set_attr "length_address" "8,0")
1261    (set_attr "length_immediate" "0,*")
1262    (set_attr "memory" "store")
1263    (set_attr "mode" "SI")])
1264
1265 (define_insn "*movabssi_2_rex64"
1266   [(set (match_operand:SI 0 "register_operand" "=a,r")
1267         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1268   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1269   "@
1270    movabs{l}\t{%P1, %0|%0, %P1}
1271    mov{l}\t{%a1, %0|%0, %a1}"
1272   [(set_attr "type" "imov")
1273    (set_attr "modrm" "0,*")
1274    (set_attr "length_address" "8,0")
1275    (set_attr "length_immediate" "0")
1276    (set_attr "memory" "load")
1277    (set_attr "mode" "SI")])
1278
1279 (define_insn "*swapsi"
1280   [(set (match_operand:SI 0 "register_operand" "+r")
1281         (match_operand:SI 1 "register_operand" "+r"))
1282    (set (match_dup 1)
1283         (match_dup 0))]
1284   ""
1285   "xchg{l}\t%1, %0"
1286   [(set_attr "type" "imov")
1287    (set_attr "mode" "SI")
1288    (set_attr "pent_pair" "np")
1289    (set_attr "athlon_decode" "vector")
1290    (set_attr "amdfam10_decode" "double")])   
1291
1292 (define_expand "movhi"
1293   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1294         (match_operand:HI 1 "general_operand" ""))]
1295   ""
1296   "ix86_expand_move (HImode, operands); DONE;")
1297
1298 (define_insn "*pushhi2"
1299   [(set (match_operand:HI 0 "push_operand" "=X")
1300         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1301   "!TARGET_64BIT"
1302   "push{l}\t%k1"
1303   [(set_attr "type" "push")
1304    (set_attr "mode" "SI")])
1305
1306 ;; For 64BIT abi we always round up to 8 bytes.
1307 (define_insn "*pushhi2_rex64"
1308   [(set (match_operand:HI 0 "push_operand" "=X")
1309         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1310   "TARGET_64BIT"
1311   "push{q}\t%q1"
1312   [(set_attr "type" "push")
1313    (set_attr "mode" "DI")])
1314
1315 (define_insn "*movhi_1"
1316   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1317         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1318   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1319 {
1320   switch (get_attr_type (insn))
1321     {
1322     case TYPE_IMOVX:
1323       /* movzwl is faster than movw on p2 due to partial word stalls,
1324          though not as fast as an aligned movl.  */
1325       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1326     default:
1327       if (get_attr_mode (insn) == MODE_SI)
1328         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1329       else
1330         return "mov{w}\t{%1, %0|%0, %1}";
1331     }
1332 }
1333   [(set (attr "type")
1334      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1335               (const_string "imov")
1336             (and (eq_attr "alternative" "0")
1337                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1338                           (const_int 0))
1339                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1340                           (const_int 0))))
1341               (const_string "imov")
1342             (and (eq_attr "alternative" "1,2")
1343                  (match_operand:HI 1 "aligned_operand" ""))
1344               (const_string "imov")
1345             (and (ne (symbol_ref "TARGET_MOVX")
1346                      (const_int 0))
1347                  (eq_attr "alternative" "0,2"))
1348               (const_string "imovx")
1349            ]
1350            (const_string "imov")))
1351     (set (attr "mode")
1352       (cond [(eq_attr "type" "imovx")
1353                (const_string "SI")
1354              (and (eq_attr "alternative" "1,2")
1355                   (match_operand:HI 1 "aligned_operand" ""))
1356                (const_string "SI")
1357              (and (eq_attr "alternative" "0")
1358                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1359                            (const_int 0))
1360                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1361                            (const_int 0))))
1362                (const_string "SI")
1363             ]
1364             (const_string "HI")))])
1365
1366 ;; Stores and loads of ax to arbitrary constant address.
1367 ;; We fake an second form of instruction to force reload to load address
1368 ;; into register when rax is not available
1369 (define_insn "*movabshi_1_rex64"
1370   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1371         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1372   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1373   "@
1374    movabs{w}\t{%1, %P0|%P0, %1}
1375    mov{w}\t{%1, %a0|%a0, %1}"
1376   [(set_attr "type" "imov")
1377    (set_attr "modrm" "0,*")
1378    (set_attr "length_address" "8,0")
1379    (set_attr "length_immediate" "0,*")
1380    (set_attr "memory" "store")
1381    (set_attr "mode" "HI")])
1382
1383 (define_insn "*movabshi_2_rex64"
1384   [(set (match_operand:HI 0 "register_operand" "=a,r")
1385         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1386   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1387   "@
1388    movabs{w}\t{%P1, %0|%0, %P1}
1389    mov{w}\t{%a1, %0|%0, %a1}"
1390   [(set_attr "type" "imov")
1391    (set_attr "modrm" "0,*")
1392    (set_attr "length_address" "8,0")
1393    (set_attr "length_immediate" "0")
1394    (set_attr "memory" "load")
1395    (set_attr "mode" "HI")])
1396
1397 (define_insn "*swaphi_1"
1398   [(set (match_operand:HI 0 "register_operand" "+r")
1399         (match_operand:HI 1 "register_operand" "+r"))
1400    (set (match_dup 1)
1401         (match_dup 0))]
1402   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1403   "xchg{l}\t%k1, %k0"
1404   [(set_attr "type" "imov")
1405    (set_attr "mode" "SI")
1406    (set_attr "pent_pair" "np")
1407    (set_attr "athlon_decode" "vector")
1408    (set_attr "amdfam10_decode" "double")])   
1409
1410 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1411 (define_insn "*swaphi_2"
1412   [(set (match_operand:HI 0 "register_operand" "+r")
1413         (match_operand:HI 1 "register_operand" "+r"))
1414    (set (match_dup 1)
1415         (match_dup 0))]
1416   "TARGET_PARTIAL_REG_STALL"
1417   "xchg{w}\t%1, %0"
1418   [(set_attr "type" "imov")
1419    (set_attr "mode" "HI")
1420    (set_attr "pent_pair" "np")
1421    (set_attr "athlon_decode" "vector")])
1422
1423 (define_expand "movstricthi"
1424   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1425         (match_operand:HI 1 "general_operand" ""))]
1426   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1427 {
1428   /* Don't generate memory->memory moves, go through a register */
1429   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1430     operands[1] = force_reg (HImode, operands[1]);
1431 })
1432
1433 (define_insn "*movstricthi_1"
1434   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1435         (match_operand:HI 1 "general_operand" "rn,m"))]
1436   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1437    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1438   "mov{w}\t{%1, %0|%0, %1}"
1439   [(set_attr "type" "imov")
1440    (set_attr "mode" "HI")])
1441
1442 (define_insn "*movstricthi_xor"
1443   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1444         (match_operand:HI 1 "const0_operand" "i"))
1445    (clobber (reg:CC FLAGS_REG))]
1446   "reload_completed
1447    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1448   "xor{w}\t%0, %0"
1449   [(set_attr "type" "alu1")
1450    (set_attr "mode" "HI")
1451    (set_attr "length_immediate" "0")])
1452
1453 (define_expand "movqi"
1454   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1455         (match_operand:QI 1 "general_operand" ""))]
1456   ""
1457   "ix86_expand_move (QImode, operands); DONE;")
1458
1459 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1460 ;; "push a byte".  But actually we use pushl, which has the effect
1461 ;; of rounding the amount pushed up to a word.
1462
1463 (define_insn "*pushqi2"
1464   [(set (match_operand:QI 0 "push_operand" "=X")
1465         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1466   "!TARGET_64BIT"
1467   "push{l}\t%k1"
1468   [(set_attr "type" "push")
1469    (set_attr "mode" "SI")])
1470
1471 ;; For 64BIT abi we always round up to 8 bytes.
1472 (define_insn "*pushqi2_rex64"
1473   [(set (match_operand:QI 0 "push_operand" "=X")
1474         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1475   "TARGET_64BIT"
1476   "push{q}\t%q1"
1477   [(set_attr "type" "push")
1478    (set_attr "mode" "DI")])
1479
1480 ;; Situation is quite tricky about when to choose full sized (SImode) move
1481 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1482 ;; partial register dependency machines (such as AMD Athlon), where QImode
1483 ;; moves issue extra dependency and for partial register stalls machines
1484 ;; that don't use QImode patterns (and QImode move cause stall on the next
1485 ;; instruction).
1486 ;;
1487 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1488 ;; register stall machines with, where we use QImode instructions, since
1489 ;; partial register stall can be caused there.  Then we use movzx.
1490 (define_insn "*movqi_1"
1491   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1492         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1493   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1494 {
1495   switch (get_attr_type (insn))
1496     {
1497     case TYPE_IMOVX:
1498       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1499       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1500     default:
1501       if (get_attr_mode (insn) == MODE_SI)
1502         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1503       else
1504         return "mov{b}\t{%1, %0|%0, %1}";
1505     }
1506 }
1507   [(set (attr "type")
1508      (cond [(and (eq_attr "alternative" "5")
1509                  (not (match_operand:QI 1 "aligned_operand" "")))
1510               (const_string "imovx")
1511             (ne (symbol_ref "optimize_size") (const_int 0))
1512               (const_string "imov")
1513             (and (eq_attr "alternative" "3")
1514                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1515                           (const_int 0))
1516                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1517                           (const_int 0))))
1518               (const_string "imov")
1519             (eq_attr "alternative" "3,5")
1520               (const_string "imovx")
1521             (and (ne (symbol_ref "TARGET_MOVX")
1522                      (const_int 0))
1523                  (eq_attr "alternative" "2"))
1524               (const_string "imovx")
1525            ]
1526            (const_string "imov")))
1527    (set (attr "mode")
1528       (cond [(eq_attr "alternative" "3,4,5")
1529                (const_string "SI")
1530              (eq_attr "alternative" "6")
1531                (const_string "QI")
1532              (eq_attr "type" "imovx")
1533                (const_string "SI")
1534              (and (eq_attr "type" "imov")
1535                   (and (eq_attr "alternative" "0,1")
1536                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1537                                 (const_int 0))
1538                             (and (eq (symbol_ref "optimize_size")
1539                                      (const_int 0))
1540                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1541                                      (const_int 0))))))
1542                (const_string "SI")
1543              ;; Avoid partial register stalls when not using QImode arithmetic
1544              (and (eq_attr "type" "imov")
1545                   (and (eq_attr "alternative" "0,1")
1546                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1547                                 (const_int 0))
1548                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1549                                 (const_int 0)))))
1550                (const_string "SI")
1551            ]
1552            (const_string "QI")))])
1553
1554 (define_expand "reload_outqi"
1555   [(parallel [(match_operand:QI 0 "" "=m")
1556               (match_operand:QI 1 "register_operand" "r")
1557               (match_operand:QI 2 "register_operand" "=&q")])]
1558   ""
1559 {
1560   rtx op0, op1, op2;
1561   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1562
1563   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1564   if (! q_regs_operand (op1, QImode))
1565     {
1566       emit_insn (gen_movqi (op2, op1));
1567       op1 = op2;
1568     }
1569   emit_insn (gen_movqi (op0, op1));
1570   DONE;
1571 })
1572
1573 (define_insn "*swapqi_1"
1574   [(set (match_operand:QI 0 "register_operand" "+r")
1575         (match_operand:QI 1 "register_operand" "+r"))
1576    (set (match_dup 1)
1577         (match_dup 0))]
1578   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1579   "xchg{l}\t%k1, %k0"
1580   [(set_attr "type" "imov")
1581    (set_attr "mode" "SI")
1582    (set_attr "pent_pair" "np")
1583    (set_attr "athlon_decode" "vector")
1584    (set_attr "amdfam10_decode" "vector")])   
1585
1586 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1587 (define_insn "*swapqi_2"
1588   [(set (match_operand:QI 0 "register_operand" "+q")
1589         (match_operand:QI 1 "register_operand" "+q"))
1590    (set (match_dup 1)
1591         (match_dup 0))]
1592   "TARGET_PARTIAL_REG_STALL"
1593   "xchg{b}\t%1, %0"
1594   [(set_attr "type" "imov")
1595    (set_attr "mode" "QI")
1596    (set_attr "pent_pair" "np")
1597    (set_attr "athlon_decode" "vector")])
1598
1599 (define_expand "movstrictqi"
1600   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1601         (match_operand:QI 1 "general_operand" ""))]
1602   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1603 {
1604   /* Don't generate memory->memory moves, go through a register.  */
1605   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1606     operands[1] = force_reg (QImode, operands[1]);
1607 })
1608
1609 (define_insn "*movstrictqi_1"
1610   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1611         (match_operand:QI 1 "general_operand" "*qn,m"))]
1612   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1613    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1614   "mov{b}\t{%1, %0|%0, %1}"
1615   [(set_attr "type" "imov")
1616    (set_attr "mode" "QI")])
1617
1618 (define_insn "*movstrictqi_xor"
1619   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1620         (match_operand:QI 1 "const0_operand" "i"))
1621    (clobber (reg:CC FLAGS_REG))]
1622   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1623   "xor{b}\t%0, %0"
1624   [(set_attr "type" "alu1")
1625    (set_attr "mode" "QI")
1626    (set_attr "length_immediate" "0")])
1627
1628 (define_insn "*movsi_extv_1"
1629   [(set (match_operand:SI 0 "register_operand" "=R")
1630         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1631                          (const_int 8)
1632                          (const_int 8)))]
1633   ""
1634   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1635   [(set_attr "type" "imovx")
1636    (set_attr "mode" "SI")])
1637
1638 (define_insn "*movhi_extv_1"
1639   [(set (match_operand:HI 0 "register_operand" "=R")
1640         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1641                          (const_int 8)
1642                          (const_int 8)))]
1643   ""
1644   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1645   [(set_attr "type" "imovx")
1646    (set_attr "mode" "SI")])
1647
1648 (define_insn "*movqi_extv_1"
1649   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1650         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1651                          (const_int 8)
1652                          (const_int 8)))]
1653   "!TARGET_64BIT"
1654 {
1655   switch (get_attr_type (insn))
1656     {
1657     case TYPE_IMOVX:
1658       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1659     default:
1660       return "mov{b}\t{%h1, %0|%0, %h1}";
1661     }
1662 }
1663   [(set (attr "type")
1664      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1665                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1666                              (ne (symbol_ref "TARGET_MOVX")
1667                                  (const_int 0))))
1668         (const_string "imovx")
1669         (const_string "imov")))
1670    (set (attr "mode")
1671      (if_then_else (eq_attr "type" "imovx")
1672         (const_string "SI")
1673         (const_string "QI")))])
1674
1675 (define_insn "*movqi_extv_1_rex64"
1676   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1677         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1678                          (const_int 8)
1679                          (const_int 8)))]
1680   "TARGET_64BIT"
1681 {
1682   switch (get_attr_type (insn))
1683     {
1684     case TYPE_IMOVX:
1685       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1686     default:
1687       return "mov{b}\t{%h1, %0|%0, %h1}";
1688     }
1689 }
1690   [(set (attr "type")
1691      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1692                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1693                              (ne (symbol_ref "TARGET_MOVX")
1694                                  (const_int 0))))
1695         (const_string "imovx")
1696         (const_string "imov")))
1697    (set (attr "mode")
1698      (if_then_else (eq_attr "type" "imovx")
1699         (const_string "SI")
1700         (const_string "QI")))])
1701
1702 ;; Stores and loads of ax to arbitrary constant address.
1703 ;; We fake an second form of instruction to force reload to load address
1704 ;; into register when rax is not available
1705 (define_insn "*movabsqi_1_rex64"
1706   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1707         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1708   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1709   "@
1710    movabs{b}\t{%1, %P0|%P0, %1}
1711    mov{b}\t{%1, %a0|%a0, %1}"
1712   [(set_attr "type" "imov")
1713    (set_attr "modrm" "0,*")
1714    (set_attr "length_address" "8,0")
1715    (set_attr "length_immediate" "0,*")
1716    (set_attr "memory" "store")
1717    (set_attr "mode" "QI")])
1718
1719 (define_insn "*movabsqi_2_rex64"
1720   [(set (match_operand:QI 0 "register_operand" "=a,r")
1721         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1722   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1723   "@
1724    movabs{b}\t{%P1, %0|%0, %P1}
1725    mov{b}\t{%a1, %0|%0, %a1}"
1726   [(set_attr "type" "imov")
1727    (set_attr "modrm" "0,*")
1728    (set_attr "length_address" "8,0")
1729    (set_attr "length_immediate" "0")
1730    (set_attr "memory" "load")
1731    (set_attr "mode" "QI")])
1732
1733 (define_insn "*movdi_extzv_1"
1734   [(set (match_operand:DI 0 "register_operand" "=R")
1735         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1736                          (const_int 8)
1737                          (const_int 8)))]
1738   "TARGET_64BIT"
1739   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1740   [(set_attr "type" "imovx")
1741    (set_attr "mode" "DI")])
1742
1743 (define_insn "*movsi_extzv_1"
1744   [(set (match_operand:SI 0 "register_operand" "=R")
1745         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1746                          (const_int 8)
1747                          (const_int 8)))]
1748   ""
1749   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1750   [(set_attr "type" "imovx")
1751    (set_attr "mode" "SI")])
1752
1753 (define_insn "*movqi_extzv_2"
1754   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1755         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1756                                     (const_int 8)
1757                                     (const_int 8)) 0))]
1758   "!TARGET_64BIT"
1759 {
1760   switch (get_attr_type (insn))
1761     {
1762     case TYPE_IMOVX:
1763       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1764     default:
1765       return "mov{b}\t{%h1, %0|%0, %h1}";
1766     }
1767 }
1768   [(set (attr "type")
1769      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1770                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1771                              (ne (symbol_ref "TARGET_MOVX")
1772                                  (const_int 0))))
1773         (const_string "imovx")
1774         (const_string "imov")))
1775    (set (attr "mode")
1776      (if_then_else (eq_attr "type" "imovx")
1777         (const_string "SI")
1778         (const_string "QI")))])
1779
1780 (define_insn "*movqi_extzv_2_rex64"
1781   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1782         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1783                                     (const_int 8)
1784                                     (const_int 8)) 0))]
1785   "TARGET_64BIT"
1786 {
1787   switch (get_attr_type (insn))
1788     {
1789     case TYPE_IMOVX:
1790       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1791     default:
1792       return "mov{b}\t{%h1, %0|%0, %h1}";
1793     }
1794 }
1795   [(set (attr "type")
1796      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1797                         (ne (symbol_ref "TARGET_MOVX")
1798                             (const_int 0)))
1799         (const_string "imovx")
1800         (const_string "imov")))
1801    (set (attr "mode")
1802      (if_then_else (eq_attr "type" "imovx")
1803         (const_string "SI")
1804         (const_string "QI")))])
1805
1806 (define_insn "movsi_insv_1"
1807   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1808                          (const_int 8)
1809                          (const_int 8))
1810         (match_operand:SI 1 "general_operand" "Qmn"))]
1811   "!TARGET_64BIT"
1812   "mov{b}\t{%b1, %h0|%h0, %b1}"
1813   [(set_attr "type" "imov")
1814    (set_attr "mode" "QI")])
1815
1816 (define_insn "*movsi_insv_1_rex64"
1817   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1818                          (const_int 8)
1819                          (const_int 8))
1820         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1821   "TARGET_64BIT"
1822   "mov{b}\t{%b1, %h0|%h0, %b1}"
1823   [(set_attr "type" "imov")
1824    (set_attr "mode" "QI")])
1825
1826 (define_insn "movdi_insv_1_rex64"
1827   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1828                          (const_int 8)
1829                          (const_int 8))
1830         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1831   "TARGET_64BIT"
1832   "mov{b}\t{%b1, %h0|%h0, %b1}"
1833   [(set_attr "type" "imov")
1834    (set_attr "mode" "QI")])
1835
1836 (define_insn "*movqi_insv_2"
1837   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1838                          (const_int 8)
1839                          (const_int 8))
1840         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1841                      (const_int 8)))]
1842   ""
1843   "mov{b}\t{%h1, %h0|%h0, %h1}"
1844   [(set_attr "type" "imov")
1845    (set_attr "mode" "QI")])
1846
1847 (define_expand "movdi"
1848   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1849         (match_operand:DI 1 "general_operand" ""))]
1850   ""
1851   "ix86_expand_move (DImode, operands); DONE;")
1852
1853 (define_insn "*pushdi"
1854   [(set (match_operand:DI 0 "push_operand" "=<")
1855         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1856   "!TARGET_64BIT"
1857   "#")
1858
1859 (define_insn "*pushdi2_rex64"
1860   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1861         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1862   "TARGET_64BIT"
1863   "@
1864    push{q}\t%1
1865    #"
1866   [(set_attr "type" "push,multi")
1867    (set_attr "mode" "DI")])
1868
1869 ;; Convert impossible pushes of immediate to existing instructions.
1870 ;; First try to get scratch register and go through it.  In case this
1871 ;; fails, push sign extended lower part first and then overwrite
1872 ;; upper part by 32bit move.
1873 (define_peephole2
1874   [(match_scratch:DI 2 "r")
1875    (set (match_operand:DI 0 "push_operand" "")
1876         (match_operand:DI 1 "immediate_operand" ""))]
1877   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1878    && !x86_64_immediate_operand (operands[1], DImode)"
1879   [(set (match_dup 2) (match_dup 1))
1880    (set (match_dup 0) (match_dup 2))]
1881   "")
1882
1883 ;; We need to define this as both peepholer and splitter for case
1884 ;; peephole2 pass is not run.
1885 ;; "&& 1" is needed to keep it from matching the previous pattern.
1886 (define_peephole2
1887   [(set (match_operand:DI 0 "push_operand" "")
1888         (match_operand:DI 1 "immediate_operand" ""))]
1889   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1890    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1891   [(set (match_dup 0) (match_dup 1))
1892    (set (match_dup 2) (match_dup 3))]
1893   "split_di (operands + 1, 1, operands + 2, operands + 3);
1894    operands[1] = gen_lowpart (DImode, operands[2]);
1895    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1896                                                     GEN_INT (4)));
1897   ")
1898
1899 (define_split
1900   [(set (match_operand:DI 0 "push_operand" "")
1901         (match_operand:DI 1 "immediate_operand" ""))]
1902   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1903                     ? flow2_completed : reload_completed)
1904    && !symbolic_operand (operands[1], DImode)
1905    && !x86_64_immediate_operand (operands[1], DImode)"
1906   [(set (match_dup 0) (match_dup 1))
1907    (set (match_dup 2) (match_dup 3))]
1908   "split_di (operands + 1, 1, operands + 2, operands + 3);
1909    operands[1] = gen_lowpart (DImode, operands[2]);
1910    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1911                                                     GEN_INT (4)));
1912   ")
1913
1914 (define_insn "*pushdi2_prologue_rex64"
1915   [(set (match_operand:DI 0 "push_operand" "=<")
1916         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1917    (clobber (mem:BLK (scratch)))]
1918   "TARGET_64BIT"
1919   "push{q}\t%1"
1920   [(set_attr "type" "push")
1921    (set_attr "mode" "DI")])
1922
1923 (define_insn "*popdi1_epilogue_rex64"
1924   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1925         (mem:DI (reg:DI SP_REG)))
1926    (set (reg:DI SP_REG)
1927         (plus:DI (reg:DI SP_REG) (const_int 8)))
1928    (clobber (mem:BLK (scratch)))]
1929   "TARGET_64BIT"
1930   "pop{q}\t%0"
1931   [(set_attr "type" "pop")
1932    (set_attr "mode" "DI")])
1933
1934 (define_insn "popdi1"
1935   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1936         (mem:DI (reg:DI SP_REG)))
1937    (set (reg:DI SP_REG)
1938         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1939   "TARGET_64BIT"
1940   "pop{q}\t%0"
1941   [(set_attr "type" "pop")
1942    (set_attr "mode" "DI")])
1943
1944 (define_insn "*movdi_xor_rex64"
1945   [(set (match_operand:DI 0 "register_operand" "=r")
1946         (match_operand:DI 1 "const0_operand" "i"))
1947    (clobber (reg:CC FLAGS_REG))]
1948   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1949    && reload_completed"
1950   "xor{l}\t%k0, %k0";
1951   [(set_attr "type" "alu1")
1952    (set_attr "mode" "SI")
1953    (set_attr "length_immediate" "0")])
1954
1955 (define_insn "*movdi_or_rex64"
1956   [(set (match_operand:DI 0 "register_operand" "=r")
1957         (match_operand:DI 1 "const_int_operand" "i"))
1958    (clobber (reg:CC FLAGS_REG))]
1959   "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
1960    && reload_completed
1961    && operands[1] == constm1_rtx"
1962 {
1963   operands[1] = constm1_rtx;
1964   return "or{q}\t{%1, %0|%0, %1}";
1965 }
1966   [(set_attr "type" "alu1")
1967    (set_attr "mode" "DI")
1968    (set_attr "length_immediate" "1")])
1969
1970 (define_insn "*movdi_2"
1971   [(set (match_operand:DI 0 "nonimmediate_operand"
1972                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
1973         (match_operand:DI 1 "general_operand"
1974                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
1975   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1976   "@
1977    #
1978    #
1979    pxor\t%0, %0
1980    movq\t{%1, %0|%0, %1}
1981    movq\t{%1, %0|%0, %1}
1982    pxor\t%0, %0
1983    movq\t{%1, %0|%0, %1}
1984    movdqa\t{%1, %0|%0, %1}
1985    movq\t{%1, %0|%0, %1}
1986    xorps\t%0, %0
1987    movlps\t{%1, %0|%0, %1}
1988    movaps\t{%1, %0|%0, %1}
1989    movlps\t{%1, %0|%0, %1}"
1990   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1991    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1992
1993 (define_split
1994   [(set (match_operand:DI 0 "push_operand" "")
1995         (match_operand:DI 1 "general_operand" ""))]
1996   "!TARGET_64BIT && reload_completed
1997    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1998   [(const_int 0)]
1999   "ix86_split_long_move (operands); DONE;")
2000
2001 ;; %%% This multiword shite has got to go.
2002 (define_split
2003   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2004         (match_operand:DI 1 "general_operand" ""))]
2005   "!TARGET_64BIT && reload_completed
2006    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2007    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2008   [(const_int 0)]
2009   "ix86_split_long_move (operands); DONE;")
2010
2011 (define_insn "*movdi_1_rex64"
2012   [(set (match_operand:DI 0 "nonimmediate_operand"
2013           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2014         (match_operand:DI 1 "general_operand"
2015           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2016   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2017 {
2018   switch (get_attr_type (insn))
2019     {
2020     case TYPE_SSECVT:
2021       if (SSE_REG_P (operands[0]))
2022         return "movq2dq\t{%1, %0|%0, %1}";
2023       else
2024         return "movdq2q\t{%1, %0|%0, %1}";
2025
2026     case TYPE_SSEMOV:
2027       if (get_attr_mode (insn) == MODE_TI)
2028         return "movdqa\t{%1, %0|%0, %1}";
2029       /* FALLTHRU */
2030
2031     case TYPE_MMXMOV:
2032       /* Moves from and into integer register is done using movd
2033          opcode with REX prefix.  */
2034       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2035         return "movd\t{%1, %0|%0, %1}";
2036       return "movq\t{%1, %0|%0, %1}";
2037
2038     case TYPE_SSELOG1:
2039     case TYPE_MMXADD:
2040       return "pxor\t%0, %0";
2041
2042     case TYPE_MULTI:
2043       return "#";
2044
2045     case TYPE_LEA:
2046       return "lea{q}\t{%a1, %0|%0, %a1}";
2047
2048     default:
2049       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2050       if (get_attr_mode (insn) == MODE_SI)
2051         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2052       else if (which_alternative == 2)
2053         return "movabs{q}\t{%1, %0|%0, %1}";
2054       else
2055         return "mov{q}\t{%1, %0|%0, %1}";
2056     }
2057 }
2058   [(set (attr "type")
2059      (cond [(eq_attr "alternative" "5")
2060               (const_string "mmxadd")
2061             (eq_attr "alternative" "6,7,8,9,10")
2062               (const_string "mmxmov")
2063             (eq_attr "alternative" "11")
2064               (const_string "sselog1")
2065             (eq_attr "alternative" "12,13,14,15,16")
2066               (const_string "ssemov")
2067             (eq_attr "alternative" "17,18")
2068               (const_string "ssecvt")
2069             (eq_attr "alternative" "4")
2070               (const_string "multi")
2071             (match_operand:DI 1 "pic_32bit_operand" "")
2072               (const_string "lea")
2073            ]
2074            (const_string "imov")))
2075    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2076    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2077    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2078
2079 ;; Stores and loads of ax to arbitrary constant address.
2080 ;; We fake an second form of instruction to force reload to load address
2081 ;; into register when rax is not available
2082 (define_insn "*movabsdi_1_rex64"
2083   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2084         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2085   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2086   "@
2087    movabs{q}\t{%1, %P0|%P0, %1}
2088    mov{q}\t{%1, %a0|%a0, %1}"
2089   [(set_attr "type" "imov")
2090    (set_attr "modrm" "0,*")
2091    (set_attr "length_address" "8,0")
2092    (set_attr "length_immediate" "0,*")
2093    (set_attr "memory" "store")
2094    (set_attr "mode" "DI")])
2095
2096 (define_insn "*movabsdi_2_rex64"
2097   [(set (match_operand:DI 0 "register_operand" "=a,r")
2098         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2099   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2100   "@
2101    movabs{q}\t{%P1, %0|%0, %P1}
2102    mov{q}\t{%a1, %0|%0, %a1}"
2103   [(set_attr "type" "imov")
2104    (set_attr "modrm" "0,*")
2105    (set_attr "length_address" "8,0")
2106    (set_attr "length_immediate" "0")
2107    (set_attr "memory" "load")
2108    (set_attr "mode" "DI")])
2109
2110 ;; Convert impossible stores of immediate to existing instructions.
2111 ;; First try to get scratch register and go through it.  In case this
2112 ;; fails, move by 32bit parts.
2113 (define_peephole2
2114   [(match_scratch:DI 2 "r")
2115    (set (match_operand:DI 0 "memory_operand" "")
2116         (match_operand:DI 1 "immediate_operand" ""))]
2117   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2118    && !x86_64_immediate_operand (operands[1], DImode)"
2119   [(set (match_dup 2) (match_dup 1))
2120    (set (match_dup 0) (match_dup 2))]
2121   "")
2122
2123 ;; We need to define this as both peepholer and splitter for case
2124 ;; peephole2 pass is not run.
2125 ;; "&& 1" is needed to keep it from matching the previous pattern.
2126 (define_peephole2
2127   [(set (match_operand:DI 0 "memory_operand" "")
2128         (match_operand:DI 1 "immediate_operand" ""))]
2129   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2130    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2131   [(set (match_dup 2) (match_dup 3))
2132    (set (match_dup 4) (match_dup 5))]
2133   "split_di (operands, 2, operands + 2, operands + 4);")
2134
2135 (define_split
2136   [(set (match_operand:DI 0 "memory_operand" "")
2137         (match_operand:DI 1 "immediate_operand" ""))]
2138   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2139                     ? flow2_completed : reload_completed)
2140    && !symbolic_operand (operands[1], DImode)
2141    && !x86_64_immediate_operand (operands[1], DImode)"
2142   [(set (match_dup 2) (match_dup 3))
2143    (set (match_dup 4) (match_dup 5))]
2144   "split_di (operands, 2, operands + 2, operands + 4);")
2145
2146 (define_insn "*swapdi_rex64"
2147   [(set (match_operand:DI 0 "register_operand" "+r")
2148         (match_operand:DI 1 "register_operand" "+r"))
2149    (set (match_dup 1)
2150         (match_dup 0))]
2151   "TARGET_64BIT"
2152   "xchg{q}\t%1, %0"
2153   [(set_attr "type" "imov")
2154    (set_attr "mode" "DI")
2155    (set_attr "pent_pair" "np")
2156    (set_attr "athlon_decode" "vector")
2157    (set_attr "amdfam10_decode" "double")])   
2158
2159 (define_expand "movti"
2160   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2161         (match_operand:TI 1 "nonimmediate_operand" ""))]
2162   "TARGET_SSE || TARGET_64BIT"
2163 {
2164   if (TARGET_64BIT)
2165     ix86_expand_move (TImode, operands);
2166   else
2167     ix86_expand_vector_move (TImode, operands);
2168   DONE;
2169 })
2170
2171 (define_insn "*movti_internal"
2172   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2173         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2174   "TARGET_SSE && !TARGET_64BIT
2175    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2176 {
2177   switch (which_alternative)
2178     {
2179     case 0:
2180       if (get_attr_mode (insn) == MODE_V4SF)
2181         return "xorps\t%0, %0";
2182       else
2183         return "pxor\t%0, %0";
2184     case 1:
2185     case 2:
2186       if (get_attr_mode (insn) == MODE_V4SF)
2187         return "movaps\t{%1, %0|%0, %1}";
2188       else
2189         return "movdqa\t{%1, %0|%0, %1}";
2190     default:
2191       gcc_unreachable ();
2192     }
2193 }
2194   [(set_attr "type" "sselog1,ssemov,ssemov")
2195    (set (attr "mode")
2196         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2197                     (ne (symbol_ref "optimize_size") (const_int 0)))
2198                  (const_string "V4SF")
2199                (and (eq_attr "alternative" "2")
2200                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2201                         (const_int 0)))
2202                  (const_string "V4SF")]
2203               (const_string "TI")))])
2204
2205 (define_insn "*movti_rex64"
2206   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2207         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2208   "TARGET_64BIT
2209    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2210 {
2211   switch (which_alternative)
2212     {
2213     case 0:
2214     case 1:
2215       return "#";
2216     case 2:
2217       if (get_attr_mode (insn) == MODE_V4SF)
2218         return "xorps\t%0, %0";
2219       else
2220         return "pxor\t%0, %0";
2221     case 3:
2222     case 4:
2223       if (get_attr_mode (insn) == MODE_V4SF)
2224         return "movaps\t{%1, %0|%0, %1}";
2225       else
2226         return "movdqa\t{%1, %0|%0, %1}";
2227     default:
2228       gcc_unreachable ();
2229     }
2230 }
2231   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2232    (set (attr "mode")
2233         (cond [(eq_attr "alternative" "2,3")
2234                  (if_then_else
2235                    (ne (symbol_ref "optimize_size")
2236                        (const_int 0))
2237                    (const_string "V4SF")
2238                    (const_string "TI"))
2239                (eq_attr "alternative" "4")
2240                  (if_then_else
2241                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2242                             (const_int 0))
2243                         (ne (symbol_ref "optimize_size")
2244                             (const_int 0)))
2245                    (const_string "V4SF")
2246                    (const_string "TI"))]
2247                (const_string "DI")))])
2248
2249 (define_split
2250   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2251         (match_operand:TI 1 "general_operand" ""))]
2252   "reload_completed && !SSE_REG_P (operands[0])
2253    && !SSE_REG_P (operands[1])"
2254   [(const_int 0)]
2255   "ix86_split_long_move (operands); DONE;")
2256
2257 ;; This expands to what emit_move_complex would generate if we didn't
2258 ;; have a movti pattern.  Having this avoids problems with reload on
2259 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2260 ;; to have around all the time.
2261 (define_expand "movcdi"
2262   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2263         (match_operand:CDI 1 "general_operand" ""))]
2264   ""
2265 {
2266   if (push_operand (operands[0], CDImode))
2267     emit_move_complex_push (CDImode, operands[0], operands[1]);
2268   else
2269     emit_move_complex_parts (operands[0], operands[1]);
2270   DONE;
2271 })
2272
2273 (define_expand "movsf"
2274   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2275         (match_operand:SF 1 "general_operand" ""))]
2276   ""
2277   "ix86_expand_move (SFmode, operands); DONE;")
2278
2279 (define_insn "*pushsf"
2280   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2281         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2282   "!TARGET_64BIT"
2283 {
2284   /* Anything else should be already split before reg-stack.  */
2285   gcc_assert (which_alternative == 1);
2286   return "push{l}\t%1";
2287 }
2288   [(set_attr "type" "multi,push,multi")
2289    (set_attr "unit" "i387,*,*")
2290    (set_attr "mode" "SF,SI,SF")])
2291
2292 (define_insn "*pushsf_rex64"
2293   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2294         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2295   "TARGET_64BIT"
2296 {
2297   /* Anything else should be already split before reg-stack.  */
2298   gcc_assert (which_alternative == 1);
2299   return "push{q}\t%q1";
2300 }
2301   [(set_attr "type" "multi,push,multi")
2302    (set_attr "unit" "i387,*,*")
2303    (set_attr "mode" "SF,DI,SF")])
2304
2305 (define_split
2306   [(set (match_operand:SF 0 "push_operand" "")
2307         (match_operand:SF 1 "memory_operand" ""))]
2308   "reload_completed
2309    && MEM_P (operands[1])
2310    && (operands[2] = find_constant_src (insn))"
2311   [(set (match_dup 0)
2312         (match_dup 2))])
2313
2314
2315 ;; %%% Kill this when call knows how to work this out.
2316 (define_split
2317   [(set (match_operand:SF 0 "push_operand" "")
2318         (match_operand:SF 1 "any_fp_register_operand" ""))]
2319   "!TARGET_64BIT"
2320   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2321    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2322
2323 (define_split
2324   [(set (match_operand:SF 0 "push_operand" "")
2325         (match_operand:SF 1 "any_fp_register_operand" ""))]
2326   "TARGET_64BIT"
2327   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2328    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2329
2330 (define_insn "*movsf_1"
2331   [(set (match_operand:SF 0 "nonimmediate_operand"
2332           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2333         (match_operand:SF 1 "general_operand"
2334           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2335   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2336    && (reload_in_progress || reload_completed
2337        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2338        || (!TARGET_SSE_MATH && optimize_size
2339            && standard_80387_constant_p (operands[1]))
2340        || GET_CODE (operands[1]) != CONST_DOUBLE
2341        || memory_operand (operands[0], SFmode))"
2342 {
2343   switch (which_alternative)
2344     {
2345     case 0:
2346     case 1:
2347       return output_387_reg_move (insn, operands);
2348
2349     case 2:
2350       return standard_80387_constant_opcode (operands[1]);
2351
2352     case 3:
2353     case 4:
2354       return "mov{l}\t{%1, %0|%0, %1}";
2355     case 5:
2356       if (get_attr_mode (insn) == MODE_TI)
2357         return "pxor\t%0, %0";
2358       else
2359         return "xorps\t%0, %0";
2360     case 6:
2361       if (get_attr_mode (insn) == MODE_V4SF)
2362         return "movaps\t{%1, %0|%0, %1}";
2363       else
2364         return "movss\t{%1, %0|%0, %1}";
2365     case 7: case 8:
2366       return "movss\t{%1, %0|%0, %1}";
2367
2368     case 9: case 10:
2369     case 12: case 13: case 14: case 15:
2370       return "movd\t{%1, %0|%0, %1}";
2371
2372     case 11:
2373       return "movq\t{%1, %0|%0, %1}";
2374
2375     default:
2376       gcc_unreachable ();
2377     }
2378 }
2379   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2380    (set (attr "mode")
2381         (cond [(eq_attr "alternative" "3,4,9,10")
2382                  (const_string "SI")
2383                (eq_attr "alternative" "5")
2384                  (if_then_else
2385                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2386                                  (const_int 0))
2387                              (ne (symbol_ref "TARGET_SSE2")
2388                                  (const_int 0)))
2389                         (eq (symbol_ref "optimize_size")
2390                             (const_int 0)))
2391                    (const_string "TI")
2392                    (const_string "V4SF"))
2393                /* For architectures resolving dependencies on
2394                   whole SSE registers use APS move to break dependency
2395                   chains, otherwise use short move to avoid extra work.
2396
2397                   Do the same for architectures resolving dependencies on
2398                   the parts.  While in DF mode it is better to always handle
2399                   just register parts, the SF mode is different due to lack
2400                   of instructions to load just part of the register.  It is
2401                   better to maintain the whole registers in single format
2402                   to avoid problems on using packed logical operations.  */
2403                (eq_attr "alternative" "6")
2404                  (if_then_else
2405                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2406                             (const_int 0))
2407                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2408                             (const_int 0)))
2409                    (const_string "V4SF")
2410                    (const_string "SF"))
2411                (eq_attr "alternative" "11")
2412                  (const_string "DI")]
2413                (const_string "SF")))])
2414
2415 (define_insn "*swapsf"
2416   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2417         (match_operand:SF 1 "fp_register_operand" "+f"))
2418    (set (match_dup 1)
2419         (match_dup 0))]
2420   "reload_completed || TARGET_80387"
2421 {
2422   if (STACK_TOP_P (operands[0]))
2423     return "fxch\t%1";
2424   else
2425     return "fxch\t%0";
2426 }
2427   [(set_attr "type" "fxch")
2428    (set_attr "mode" "SF")])
2429
2430 (define_expand "movdf"
2431   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2432         (match_operand:DF 1 "general_operand" ""))]
2433   ""
2434   "ix86_expand_move (DFmode, operands); DONE;")
2435
2436 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2437 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2438 ;; On the average, pushdf using integers can be still shorter.  Allow this
2439 ;; pattern for optimize_size too.
2440
2441 (define_insn "*pushdf_nointeger"
2442   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2443         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2444   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2445 {
2446   /* This insn should be already split before reg-stack.  */
2447   gcc_unreachable ();
2448 }
2449   [(set_attr "type" "multi")
2450    (set_attr "unit" "i387,*,*,*")
2451    (set_attr "mode" "DF,SI,SI,DF")])
2452
2453 (define_insn "*pushdf_integer"
2454   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2455         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2456   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2457 {
2458   /* This insn should be already split before reg-stack.  */
2459   gcc_unreachable ();
2460 }
2461   [(set_attr "type" "multi")
2462    (set_attr "unit" "i387,*,*")
2463    (set_attr "mode" "DF,SI,DF")])
2464
2465 ;; %%% Kill this when call knows how to work this out.
2466 (define_split
2467   [(set (match_operand:DF 0 "push_operand" "")
2468         (match_operand:DF 1 "any_fp_register_operand" ""))]
2469   "!TARGET_64BIT && reload_completed"
2470   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2471    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2472   "")
2473
2474 (define_split
2475   [(set (match_operand:DF 0 "push_operand" "")
2476         (match_operand:DF 1 "any_fp_register_operand" ""))]
2477   "TARGET_64BIT && reload_completed"
2478   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2479    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2480   "")
2481
2482 (define_split
2483   [(set (match_operand:DF 0 "push_operand" "")
2484         (match_operand:DF 1 "general_operand" ""))]
2485   "reload_completed"
2486   [(const_int 0)]
2487   "ix86_split_long_move (operands); DONE;")
2488
2489 ;; Moving is usually shorter when only FP registers are used. This separate
2490 ;; movdf pattern avoids the use of integer registers for FP operations
2491 ;; when optimizing for size.
2492
2493 (define_insn "*movdf_nointeger"
2494   [(set (match_operand:DF 0 "nonimmediate_operand"
2495                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2496         (match_operand:DF 1 "general_operand"
2497                         "fm,f,G,*roF,F*r,C   ,Y2*x,mY2*x,Y2*x"))]
2498   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2499    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2500    && (reload_in_progress || reload_completed
2501        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2502        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2503            && standard_80387_constant_p (operands[1]))
2504        || GET_CODE (operands[1]) != CONST_DOUBLE
2505        || memory_operand (operands[0], DFmode))"
2506 {
2507   switch (which_alternative)
2508     {
2509     case 0:
2510     case 1:
2511       return output_387_reg_move (insn, operands);
2512
2513     case 2:
2514       return standard_80387_constant_opcode (operands[1]);
2515
2516     case 3:
2517     case 4:
2518       return "#";
2519     case 5:
2520       switch (get_attr_mode (insn))
2521         {
2522         case MODE_V4SF:
2523           return "xorps\t%0, %0";
2524         case MODE_V2DF:
2525           return "xorpd\t%0, %0";
2526         case MODE_TI:
2527           return "pxor\t%0, %0";
2528         default:
2529           gcc_unreachable ();
2530         }
2531     case 6:
2532     case 7:
2533     case 8:
2534       switch (get_attr_mode (insn))
2535         {
2536         case MODE_V4SF:
2537           return "movaps\t{%1, %0|%0, %1}";
2538         case MODE_V2DF:
2539           return "movapd\t{%1, %0|%0, %1}";
2540         case MODE_TI:
2541           return "movdqa\t{%1, %0|%0, %1}";
2542         case MODE_DI:
2543           return "movq\t{%1, %0|%0, %1}";
2544         case MODE_DF:
2545           return "movsd\t{%1, %0|%0, %1}";
2546         case MODE_V1DF:
2547           return "movlpd\t{%1, %0|%0, %1}";
2548         case MODE_V2SF:
2549           return "movlps\t{%1, %0|%0, %1}";
2550         default:
2551           gcc_unreachable ();
2552         }
2553
2554     default:
2555       gcc_unreachable ();
2556     }
2557 }
2558   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2559    (set (attr "mode")
2560         (cond [(eq_attr "alternative" "0,1,2")
2561                  (const_string "DF")
2562                (eq_attr "alternative" "3,4")
2563                  (const_string "SI")
2564
2565                /* For SSE1, we have many fewer alternatives.  */
2566                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2567                  (cond [(eq_attr "alternative" "5,6")
2568                           (const_string "V4SF")
2569                        ]
2570                    (const_string "V2SF"))
2571
2572                /* xorps is one byte shorter.  */
2573                (eq_attr "alternative" "5")
2574                  (cond [(ne (symbol_ref "optimize_size")
2575                             (const_int 0))
2576                           (const_string "V4SF")
2577                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2578                             (const_int 0))
2579                           (const_string "TI")
2580                        ]
2581                        (const_string "V2DF"))
2582
2583                /* For architectures resolving dependencies on
2584                   whole SSE registers use APD move to break dependency
2585                   chains, otherwise use short move to avoid extra work.
2586
2587                   movaps encodes one byte shorter.  */
2588                (eq_attr "alternative" "6")
2589                  (cond
2590                    [(ne (symbol_ref "optimize_size")
2591                         (const_int 0))
2592                       (const_string "V4SF")
2593                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2594                         (const_int 0))
2595                       (const_string "V2DF")
2596                    ]
2597                    (const_string "DF"))
2598                /* For architectures resolving dependencies on register
2599                   parts we may avoid extra work to zero out upper part
2600                   of register.  */
2601                (eq_attr "alternative" "7")
2602                  (if_then_else
2603                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2604                        (const_int 0))
2605                    (const_string "V1DF")
2606                    (const_string "DF"))
2607               ]
2608               (const_string "DF")))])
2609
2610 (define_insn "*movdf_integer_rex64"
2611   [(set (match_operand:DF 0 "nonimmediate_operand"
2612                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2613         (match_operand:DF 1 "general_operand"
2614                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2615   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2616    && (reload_in_progress || reload_completed
2617        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2618        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2619            && standard_80387_constant_p (operands[1]))
2620        || GET_CODE (operands[1]) != CONST_DOUBLE
2621        || memory_operand (operands[0], DFmode))"
2622 {
2623   switch (which_alternative)
2624     {
2625     case 0:
2626     case 1:
2627       return output_387_reg_move (insn, operands);
2628
2629     case 2:
2630       return standard_80387_constant_opcode (operands[1]);
2631
2632     case 3:
2633     case 4:
2634       return "#";
2635
2636     case 5:
2637       switch (get_attr_mode (insn))
2638         {
2639         case MODE_V4SF:
2640           return "xorps\t%0, %0";
2641         case MODE_V2DF:
2642           return "xorpd\t%0, %0";
2643         case MODE_TI:
2644           return "pxor\t%0, %0";
2645         default:
2646           gcc_unreachable ();
2647         }
2648     case 6:
2649     case 7:
2650     case 8:
2651       switch (get_attr_mode (insn))
2652         {
2653         case MODE_V4SF:
2654           return "movaps\t{%1, %0|%0, %1}";
2655         case MODE_V2DF:
2656           return "movapd\t{%1, %0|%0, %1}";
2657         case MODE_TI:
2658           return "movdqa\t{%1, %0|%0, %1}";
2659         case MODE_DI:
2660           return "movq\t{%1, %0|%0, %1}";
2661         case MODE_DF:
2662           return "movsd\t{%1, %0|%0, %1}";
2663         case MODE_V1DF:
2664           return "movlpd\t{%1, %0|%0, %1}";
2665         case MODE_V2SF:
2666           return "movlps\t{%1, %0|%0, %1}";
2667         default:
2668           gcc_unreachable ();
2669         }
2670
2671     case 9:
2672     case 10:
2673       return "movd\t{%1, %0|%0, %1}";
2674
2675     default:
2676       gcc_unreachable();
2677     }
2678 }
2679   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2680    (set (attr "mode")
2681         (cond [(eq_attr "alternative" "0,1,2")
2682                  (const_string "DF")
2683                (eq_attr "alternative" "3,4,9,10")
2684                  (const_string "DI")
2685
2686                /* For SSE1, we have many fewer alternatives.  */
2687                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2688                  (cond [(eq_attr "alternative" "5,6")
2689                           (const_string "V4SF")
2690                        ]
2691                    (const_string "V2SF"))
2692
2693                /* xorps is one byte shorter.  */
2694                (eq_attr "alternative" "5")
2695                  (cond [(ne (symbol_ref "optimize_size")
2696                             (const_int 0))
2697                           (const_string "V4SF")
2698                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2699                             (const_int 0))
2700                           (const_string "TI")
2701                        ]
2702                        (const_string "V2DF"))
2703
2704                /* For architectures resolving dependencies on
2705                   whole SSE registers use APD move to break dependency
2706                   chains, otherwise use short move to avoid extra work.
2707
2708                   movaps encodes one byte shorter.  */
2709                (eq_attr "alternative" "6")
2710                  (cond
2711                    [(ne (symbol_ref "optimize_size")
2712                         (const_int 0))
2713                       (const_string "V4SF")
2714                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2715                         (const_int 0))
2716                       (const_string "V2DF")
2717                    ]
2718                    (const_string "DF"))
2719                /* For architectures resolving dependencies on register
2720                   parts we may avoid extra work to zero out upper part
2721                   of register.  */
2722                (eq_attr "alternative" "7")
2723                  (if_then_else
2724                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2725                        (const_int 0))
2726                    (const_string "V1DF")
2727                    (const_string "DF"))
2728               ]
2729               (const_string "DF")))])
2730
2731 (define_insn "*movdf_integer"
2732   [(set (match_operand:DF 0 "nonimmediate_operand"
2733                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
2734         (match_operand:DF 1 "general_operand"
2735                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
2736   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2737    && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2738    && (reload_in_progress || reload_completed
2739        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2740        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2741            && standard_80387_constant_p (operands[1]))
2742        || GET_CODE (operands[1]) != CONST_DOUBLE
2743        || memory_operand (operands[0], DFmode))"
2744 {
2745   switch (which_alternative)
2746     {
2747     case 0:
2748     case 1:
2749       return output_387_reg_move (insn, operands);
2750
2751     case 2:
2752       return standard_80387_constant_opcode (operands[1]);
2753
2754     case 3:
2755     case 4:
2756       return "#";
2757
2758     case 5:
2759       switch (get_attr_mode (insn))
2760         {
2761         case MODE_V4SF:
2762           return "xorps\t%0, %0";
2763         case MODE_V2DF:
2764           return "xorpd\t%0, %0";
2765         case MODE_TI:
2766           return "pxor\t%0, %0";
2767         default:
2768           gcc_unreachable ();
2769         }
2770     case 6:
2771     case 7:
2772     case 8:
2773       switch (get_attr_mode (insn))
2774         {
2775         case MODE_V4SF:
2776           return "movaps\t{%1, %0|%0, %1}";
2777         case MODE_V2DF:
2778           return "movapd\t{%1, %0|%0, %1}";
2779         case MODE_TI:
2780           return "movdqa\t{%1, %0|%0, %1}";
2781         case MODE_DI:
2782           return "movq\t{%1, %0|%0, %1}";
2783         case MODE_DF:
2784           return "movsd\t{%1, %0|%0, %1}";
2785         case MODE_V1DF:
2786           return "movlpd\t{%1, %0|%0, %1}";
2787         case MODE_V2SF:
2788           return "movlps\t{%1, %0|%0, %1}";
2789         default:
2790           gcc_unreachable ();
2791         }
2792
2793     default:
2794       gcc_unreachable();
2795     }
2796 }
2797   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2798    (set (attr "mode")
2799         (cond [(eq_attr "alternative" "0,1,2")
2800                  (const_string "DF")
2801                (eq_attr "alternative" "3,4")
2802                  (const_string "SI")
2803
2804                /* For SSE1, we have many fewer alternatives.  */
2805                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2806                  (cond [(eq_attr "alternative" "5,6")
2807                           (const_string "V4SF")
2808                        ]
2809                    (const_string "V2SF"))
2810
2811                /* xorps is one byte shorter.  */
2812                (eq_attr "alternative" "5")
2813                  (cond [(ne (symbol_ref "optimize_size")
2814                             (const_int 0))
2815                           (const_string "V4SF")
2816                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2817                             (const_int 0))
2818                           (const_string "TI")
2819                        ]
2820                        (const_string "V2DF"))
2821
2822                /* For architectures resolving dependencies on
2823                   whole SSE registers use APD move to break dependency
2824                   chains, otherwise use short move to avoid extra work.
2825
2826                   movaps encodes one byte shorter.  */
2827                (eq_attr "alternative" "6")
2828                  (cond
2829                    [(ne (symbol_ref "optimize_size")
2830                         (const_int 0))
2831                       (const_string "V4SF")
2832                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2833                         (const_int 0))
2834                       (const_string "V2DF")
2835                    ]
2836                    (const_string "DF"))
2837                /* For architectures resolving dependencies on register
2838                   parts we may avoid extra work to zero out upper part
2839                   of register.  */
2840                (eq_attr "alternative" "7")
2841                  (if_then_else
2842                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2843                        (const_int 0))
2844                    (const_string "V1DF")
2845                    (const_string "DF"))
2846               ]
2847               (const_string "DF")))])
2848
2849 (define_split
2850   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2851         (match_operand:DF 1 "general_operand" ""))]
2852   "reload_completed
2853    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2854    && ! (ANY_FP_REG_P (operands[0]) ||
2855          (GET_CODE (operands[0]) == SUBREG
2856           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2857    && ! (ANY_FP_REG_P (operands[1]) ||
2858          (GET_CODE (operands[1]) == SUBREG
2859           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2860   [(const_int 0)]
2861   "ix86_split_long_move (operands); DONE;")
2862
2863 (define_insn "*swapdf"
2864   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2865         (match_operand:DF 1 "fp_register_operand" "+f"))
2866    (set (match_dup 1)
2867         (match_dup 0))]
2868   "reload_completed || TARGET_80387"
2869 {
2870   if (STACK_TOP_P (operands[0]))
2871     return "fxch\t%1";
2872   else
2873     return "fxch\t%0";
2874 }
2875   [(set_attr "type" "fxch")
2876    (set_attr "mode" "DF")])
2877
2878 (define_expand "movxf"
2879   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2880         (match_operand:XF 1 "general_operand" ""))]
2881   ""
2882   "ix86_expand_move (XFmode, operands); DONE;")
2883
2884 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2885 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2886 ;; Pushing using integer instructions is longer except for constants
2887 ;; and direct memory references.
2888 ;; (assuming that any given constant is pushed only once, but this ought to be
2889 ;;  handled elsewhere).
2890
2891 (define_insn "*pushxf_nointeger"
2892   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2893         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2894   "optimize_size"
2895 {
2896   /* This insn should be already split before reg-stack.  */
2897   gcc_unreachable ();
2898 }
2899   [(set_attr "type" "multi")
2900    (set_attr "unit" "i387,*,*")
2901    (set_attr "mode" "XF,SI,SI")])
2902
2903 (define_insn "*pushxf_integer"
2904   [(set (match_operand:XF 0 "push_operand" "=<,<")
2905         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2906   "!optimize_size"
2907 {
2908   /* This insn should be already split before reg-stack.  */
2909   gcc_unreachable ();
2910 }
2911   [(set_attr "type" "multi")
2912    (set_attr "unit" "i387,*")
2913    (set_attr "mode" "XF,SI")])
2914
2915 (define_split
2916   [(set (match_operand 0 "push_operand" "")
2917         (match_operand 1 "general_operand" ""))]
2918   "reload_completed
2919    && (GET_MODE (operands[0]) == XFmode
2920        || GET_MODE (operands[0]) == DFmode)
2921    && !ANY_FP_REG_P (operands[1])"
2922   [(const_int 0)]
2923   "ix86_split_long_move (operands); DONE;")
2924
2925 (define_split
2926   [(set (match_operand:XF 0 "push_operand" "")
2927         (match_operand:XF 1 "any_fp_register_operand" ""))]
2928   "!TARGET_64BIT"
2929   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2930    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2931   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2932
2933 (define_split
2934   [(set (match_operand:XF 0 "push_operand" "")
2935         (match_operand:XF 1 "any_fp_register_operand" ""))]
2936   "TARGET_64BIT"
2937   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2938    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2939   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2940
2941 ;; Do not use integer registers when optimizing for size
2942 (define_insn "*movxf_nointeger"
2943   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2944         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2945   "optimize_size
2946    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2947    && (reload_in_progress || reload_completed
2948        || (optimize_size && standard_80387_constant_p (operands[1]))
2949        || GET_CODE (operands[1]) != CONST_DOUBLE
2950        || memory_operand (operands[0], XFmode))"
2951 {
2952   switch (which_alternative)
2953     {
2954     case 0:
2955     case 1:
2956       return output_387_reg_move (insn, operands);
2957
2958     case 2:
2959       return standard_80387_constant_opcode (operands[1]);
2960
2961     case 3: case 4:
2962       return "#";
2963     default:
2964       gcc_unreachable ();
2965     }
2966 }
2967   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2968    (set_attr "mode" "XF,XF,XF,SI,SI")])
2969
2970 (define_insn "*movxf_integer"
2971   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2972         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2973   "!optimize_size
2974    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2975    && (reload_in_progress || reload_completed
2976        || (optimize_size && standard_80387_constant_p (operands[1]))
2977        || GET_CODE (operands[1]) != CONST_DOUBLE
2978        || memory_operand (operands[0], XFmode))"
2979 {
2980   switch (which_alternative)
2981     {
2982     case 0:
2983     case 1:
2984       return output_387_reg_move (insn, operands);
2985
2986     case 2:
2987       return standard_80387_constant_opcode (operands[1]);
2988
2989     case 3: case 4:
2990       return "#";
2991
2992     default:
2993       gcc_unreachable ();
2994     }
2995 }
2996   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2997    (set_attr "mode" "XF,XF,XF,SI,SI")])
2998
2999 (define_split
3000   [(set (match_operand 0 "nonimmediate_operand" "")
3001         (match_operand 1 "general_operand" ""))]
3002   "reload_completed
3003    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3004    && GET_MODE (operands[0]) == XFmode
3005    && ! (ANY_FP_REG_P (operands[0]) ||
3006          (GET_CODE (operands[0]) == SUBREG
3007           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3008    && ! (ANY_FP_REG_P (operands[1]) ||
3009          (GET_CODE (operands[1]) == SUBREG
3010           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3011   [(const_int 0)]
3012   "ix86_split_long_move (operands); DONE;")
3013
3014 (define_split
3015   [(set (match_operand 0 "register_operand" "")
3016         (match_operand 1 "memory_operand" ""))]
3017   "reload_completed
3018    && MEM_P (operands[1])
3019    && (GET_MODE (operands[0]) == XFmode
3020        || GET_MODE (operands[0]) == SFmode
3021        || GET_MODE (operands[0]) == DFmode)
3022    && (operands[2] = find_constant_src (insn))"
3023   [(set (match_dup 0) (match_dup 2))]
3024 {
3025   rtx c = operands[2];
3026   rtx r = operands[0];
3027
3028   if (GET_CODE (r) == SUBREG)
3029     r = SUBREG_REG (r);
3030
3031   if (SSE_REG_P (r))
3032     {
3033       if (!standard_sse_constant_p (c))
3034         FAIL;
3035     }
3036   else if (FP_REG_P (r))
3037     {
3038       if (!standard_80387_constant_p (c))
3039         FAIL;
3040     }
3041   else if (MMX_REG_P (r))
3042     FAIL;
3043 })
3044
3045 (define_split
3046   [(set (match_operand 0 "register_operand" "")
3047         (float_extend (match_operand 1 "memory_operand" "")))]
3048   "reload_completed
3049    && MEM_P (operands[1])
3050    && (GET_MODE (operands[0]) == XFmode
3051        || GET_MODE (operands[0]) == SFmode
3052        || GET_MODE (operands[0]) == DFmode)
3053    && (operands[2] = find_constant_src (insn))"
3054   [(set (match_dup 0) (match_dup 2))]
3055 {
3056   rtx c = operands[2];
3057   rtx r = operands[0];
3058
3059   if (GET_CODE (r) == SUBREG)
3060     r = SUBREG_REG (r);
3061
3062   if (SSE_REG_P (r))
3063     {
3064       if (!standard_sse_constant_p (c))
3065         FAIL;
3066     }
3067   else if (FP_REG_P (r))
3068     {
3069       if (!standard_80387_constant_p (c))
3070         FAIL;
3071     }
3072   else if (MMX_REG_P (r))
3073     FAIL;
3074 })
3075
3076 (define_insn "swapxf"
3077   [(set (match_operand:XF 0 "register_operand" "+f")
3078         (match_operand:XF 1 "register_operand" "+f"))
3079    (set (match_dup 1)
3080         (match_dup 0))]
3081   "TARGET_80387"
3082 {
3083   if (STACK_TOP_P (operands[0]))
3084     return "fxch\t%1";
3085   else
3086     return "fxch\t%0";
3087 }
3088   [(set_attr "type" "fxch")
3089    (set_attr "mode" "XF")])
3090
3091 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3092 (define_split
3093   [(set (match_operand:X87MODEF 0 "register_operand" "")
3094         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3095   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3096    && (standard_80387_constant_p (operands[1]) == 8
3097        || standard_80387_constant_p (operands[1]) == 9)"
3098   [(set (match_dup 0)(match_dup 1))
3099    (set (match_dup 0)
3100         (neg:X87MODEF (match_dup 0)))]
3101 {
3102   REAL_VALUE_TYPE r;
3103
3104   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3105   if (real_isnegzero (&r))
3106     operands[1] = CONST0_RTX (<MODE>mode);
3107   else
3108     operands[1] = CONST1_RTX (<MODE>mode);
3109 })
3110
3111 (define_expand "movtf"
3112   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3113         (match_operand:TF 1 "nonimmediate_operand" ""))]
3114   "TARGET_64BIT"
3115 {
3116   ix86_expand_move (TFmode, operands);
3117   DONE;
3118 })
3119
3120 (define_insn "*movtf_internal"
3121   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3122         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3123   "TARGET_64BIT
3124    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3125 {
3126   switch (which_alternative)
3127     {
3128     case 0:
3129     case 1:
3130       return "#";
3131     case 2:
3132       if (get_attr_mode (insn) == MODE_V4SF)
3133         return "xorps\t%0, %0";
3134       else
3135         return "pxor\t%0, %0";
3136     case 3:
3137     case 4:
3138       if (get_attr_mode (insn) == MODE_V4SF)
3139         return "movaps\t{%1, %0|%0, %1}";
3140       else
3141         return "movdqa\t{%1, %0|%0, %1}";
3142     default:
3143       gcc_unreachable ();
3144     }
3145 }
3146   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3147    (set (attr "mode")
3148         (cond [(eq_attr "alternative" "2,3")
3149                  (if_then_else
3150                    (ne (symbol_ref "optimize_size")
3151                        (const_int 0))
3152                    (const_string "V4SF")
3153                    (const_string "TI"))
3154                (eq_attr "alternative" "4")
3155                  (if_then_else
3156                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3157                             (const_int 0))
3158                         (ne (symbol_ref "optimize_size")
3159                             (const_int 0)))
3160                    (const_string "V4SF")
3161                    (const_string "TI"))]
3162                (const_string "DI")))])
3163
3164 (define_split
3165   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3166         (match_operand:TF 1 "general_operand" ""))]
3167   "reload_completed && !SSE_REG_P (operands[0])
3168    && !SSE_REG_P (operands[1])"
3169   [(const_int 0)]
3170   "ix86_split_long_move (operands); DONE;")
3171 \f
3172 ;; Zero extension instructions
3173
3174 (define_expand "zero_extendhisi2"
3175   [(set (match_operand:SI 0 "register_operand" "")
3176      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3177   ""
3178 {
3179   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3180     {
3181       operands[1] = force_reg (HImode, operands[1]);
3182       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3183       DONE;
3184     }
3185 })
3186
3187 (define_insn "zero_extendhisi2_and"
3188   [(set (match_operand:SI 0 "register_operand" "=r")
3189      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3190    (clobber (reg:CC FLAGS_REG))]
3191   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3192   "#"
3193   [(set_attr "type" "alu1")
3194    (set_attr "mode" "SI")])
3195
3196 (define_split
3197   [(set (match_operand:SI 0 "register_operand" "")
3198         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3199    (clobber (reg:CC FLAGS_REG))]
3200   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3201   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3202               (clobber (reg:CC FLAGS_REG))])]
3203   "")
3204
3205 (define_insn "*zero_extendhisi2_movzwl"
3206   [(set (match_operand:SI 0 "register_operand" "=r")
3207      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3208   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3209   "movz{wl|x}\t{%1, %0|%0, %1}"
3210   [(set_attr "type" "imovx")
3211    (set_attr "mode" "SI")])
3212
3213 (define_expand "zero_extendqihi2"
3214   [(parallel
3215     [(set (match_operand:HI 0 "register_operand" "")
3216        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3217      (clobber (reg:CC FLAGS_REG))])]
3218   ""
3219   "")
3220
3221 (define_insn "*zero_extendqihi2_and"
3222   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3223      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3224    (clobber (reg:CC FLAGS_REG))]
3225   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3226   "#"
3227   [(set_attr "type" "alu1")
3228    (set_attr "mode" "HI")])
3229
3230 (define_insn "*zero_extendqihi2_movzbw_and"
3231   [(set (match_operand:HI 0 "register_operand" "=r,r")
3232      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3233    (clobber (reg:CC FLAGS_REG))]
3234   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3235   "#"
3236   [(set_attr "type" "imovx,alu1")
3237    (set_attr "mode" "HI")])
3238
3239 ; zero extend to SImode here to avoid partial register stalls
3240 (define_insn "*zero_extendqihi2_movzbl"
3241   [(set (match_operand:HI 0 "register_operand" "=r")
3242      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3243   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3244   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3245   [(set_attr "type" "imovx")
3246    (set_attr "mode" "SI")])
3247
3248 ;; For the movzbw case strip only the clobber
3249 (define_split
3250   [(set (match_operand:HI 0 "register_operand" "")
3251         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3252    (clobber (reg:CC FLAGS_REG))]
3253   "reload_completed
3254    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3255    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3256   [(set (match_operand:HI 0 "register_operand" "")
3257         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3258
3259 ;; When source and destination does not overlap, clear destination
3260 ;; first and then do the movb
3261 (define_split
3262   [(set (match_operand:HI 0 "register_operand" "")
3263         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3264    (clobber (reg:CC FLAGS_REG))]
3265   "reload_completed
3266    && ANY_QI_REG_P (operands[0])
3267    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3268    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3269   [(set (match_dup 0) (const_int 0))
3270    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3271   "operands[2] = gen_lowpart (QImode, operands[0]);")
3272
3273 ;; Rest is handled by single and.
3274 (define_split
3275   [(set (match_operand:HI 0 "register_operand" "")
3276         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3277    (clobber (reg:CC FLAGS_REG))]
3278   "reload_completed
3279    && true_regnum (operands[0]) == true_regnum (operands[1])"
3280   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3281               (clobber (reg:CC FLAGS_REG))])]
3282   "")
3283
3284 (define_expand "zero_extendqisi2"
3285   [(parallel
3286     [(set (match_operand:SI 0 "register_operand" "")
3287        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3288      (clobber (reg:CC FLAGS_REG))])]
3289   ""
3290   "")
3291
3292 (define_insn "*zero_extendqisi2_and"
3293   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3294      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3295    (clobber (reg:CC FLAGS_REG))]
3296   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3297   "#"
3298   [(set_attr "type" "alu1")
3299    (set_attr "mode" "SI")])
3300
3301 (define_insn "*zero_extendqisi2_movzbw_and"
3302   [(set (match_operand:SI 0 "register_operand" "=r,r")
3303      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3304    (clobber (reg:CC FLAGS_REG))]
3305   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3306   "#"
3307   [(set_attr "type" "imovx,alu1")
3308    (set_attr "mode" "SI")])
3309
3310 (define_insn "*zero_extendqisi2_movzbw"
3311   [(set (match_operand:SI 0 "register_operand" "=r")
3312      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3313   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3314   "movz{bl|x}\t{%1, %0|%0, %1}"
3315   [(set_attr "type" "imovx")
3316    (set_attr "mode" "SI")])
3317
3318 ;; For the movzbl case strip only the clobber
3319 (define_split
3320   [(set (match_operand:SI 0 "register_operand" "")
3321         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3322    (clobber (reg:CC FLAGS_REG))]
3323   "reload_completed
3324    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3325    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3326   [(set (match_dup 0)
3327         (zero_extend:SI (match_dup 1)))])
3328
3329 ;; When source and destination does not overlap, clear destination
3330 ;; first and then do the movb
3331 (define_split
3332   [(set (match_operand:SI 0 "register_operand" "")
3333         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3334    (clobber (reg:CC FLAGS_REG))]
3335   "reload_completed
3336    && ANY_QI_REG_P (operands[0])
3337    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3338    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3339    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3340   [(set (match_dup 0) (const_int 0))
3341    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3342   "operands[2] = gen_lowpart (QImode, operands[0]);")
3343
3344 ;; Rest is handled by single and.
3345 (define_split
3346   [(set (match_operand:SI 0 "register_operand" "")
3347         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3348    (clobber (reg:CC FLAGS_REG))]
3349   "reload_completed
3350    && true_regnum (operands[0]) == true_regnum (operands[1])"
3351   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3352               (clobber (reg:CC FLAGS_REG))])]
3353   "")
3354
3355 ;; %%% Kill me once multi-word ops are sane.
3356 (define_expand "zero_extendsidi2"
3357   [(set (match_operand:DI 0 "register_operand" "=r")
3358      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3359   ""
3360 {
3361   if (!TARGET_64BIT)
3362     {
3363       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3364       DONE;
3365     }
3366 })
3367
3368 (define_insn "zero_extendsidi2_32"
3369   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3370         (zero_extend:DI
3371          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3372    (clobber (reg:CC FLAGS_REG))]
3373   "!TARGET_64BIT"
3374   "@
3375    #
3376    #
3377    #
3378    movd\t{%1, %0|%0, %1}
3379    movd\t{%1, %0|%0, %1}
3380    movd\t{%1, %0|%0, %1}
3381    movd\t{%1, %0|%0, %1}"
3382   [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3383    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3384
3385 (define_insn "zero_extendsidi2_rex64"
3386   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3387      (zero_extend:DI
3388        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3389   "TARGET_64BIT"
3390   "@
3391    mov\t{%k1, %k0|%k0, %k1}
3392    #
3393    movd\t{%1, %0|%0, %1}
3394    movd\t{%1, %0|%0, %1}
3395    movd\t{%1, %0|%0, %1}
3396    movd\t{%1, %0|%0, %1}"
3397   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3398    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3399
3400 (define_split
3401   [(set (match_operand:DI 0 "memory_operand" "")
3402      (zero_extend:DI (match_dup 0)))]
3403   "TARGET_64BIT"
3404   [(set (match_dup 4) (const_int 0))]
3405   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3406
3407 (define_split
3408   [(set (match_operand:DI 0 "register_operand" "")
3409         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3410    (clobber (reg:CC FLAGS_REG))]
3411   "!TARGET_64BIT && reload_completed
3412    && true_regnum (operands[0]) == true_regnum (operands[1])"
3413   [(set (match_dup 4) (const_int 0))]
3414   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3415
3416 (define_split
3417   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3418         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3419    (clobber (reg:CC FLAGS_REG))]
3420   "!TARGET_64BIT && reload_completed
3421    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3422   [(set (match_dup 3) (match_dup 1))
3423    (set (match_dup 4) (const_int 0))]
3424   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3425
3426 (define_insn "zero_extendhidi2"
3427   [(set (match_operand:DI 0 "register_operand" "=r")
3428      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3429   "TARGET_64BIT"
3430   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3431   [(set_attr "type" "imovx")
3432    (set_attr "mode" "DI")])
3433
3434 (define_insn "zero_extendqidi2"
3435   [(set (match_operand:DI 0 "register_operand" "=r")
3436      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3437   "TARGET_64BIT"
3438   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3439   [(set_attr "type" "imovx")
3440    (set_attr "mode" "DI")])
3441 \f
3442 ;; Sign extension instructions
3443
3444 (define_expand "extendsidi2"
3445   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3446                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3447               (clobber (reg:CC FLAGS_REG))
3448               (clobber (match_scratch:SI 2 ""))])]
3449   ""
3450 {
3451   if (TARGET_64BIT)
3452     {
3453       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3454       DONE;
3455     }
3456 })
3457
3458 (define_insn "*extendsidi2_1"
3459   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3460         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3461    (clobber (reg:CC FLAGS_REG))
3462    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3463   "!TARGET_64BIT"
3464   "#")
3465
3466 (define_insn "extendsidi2_rex64"
3467   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3468         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3469   "TARGET_64BIT"
3470   "@
3471    {cltq|cdqe}
3472    movs{lq|x}\t{%1,%0|%0, %1}"
3473   [(set_attr "type" "imovx")
3474    (set_attr "mode" "DI")
3475    (set_attr "prefix_0f" "0")
3476    (set_attr "modrm" "0,1")])
3477
3478 (define_insn "extendhidi2"
3479   [(set (match_operand:DI 0 "register_operand" "=r")
3480         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3481   "TARGET_64BIT"
3482   "movs{wq|x}\t{%1,%0|%0, %1}"
3483   [(set_attr "type" "imovx")
3484    (set_attr "mode" "DI")])
3485
3486 (define_insn "extendqidi2"
3487   [(set (match_operand:DI 0 "register_operand" "=r")
3488         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3489   "TARGET_64BIT"
3490   "movs{bq|x}\t{%1,%0|%0, %1}"
3491    [(set_attr "type" "imovx")
3492     (set_attr "mode" "DI")])
3493
3494 ;; Extend to memory case when source register does die.
3495 (define_split
3496   [(set (match_operand:DI 0 "memory_operand" "")
3497         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3498    (clobber (reg:CC FLAGS_REG))
3499    (clobber (match_operand:SI 2 "register_operand" ""))]
3500   "(reload_completed
3501     && dead_or_set_p (insn, operands[1])
3502     && !reg_mentioned_p (operands[1], operands[0]))"
3503   [(set (match_dup 3) (match_dup 1))
3504    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3505               (clobber (reg:CC FLAGS_REG))])
3506    (set (match_dup 4) (match_dup 1))]
3507   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3508
3509 ;; Extend to memory case when source register does not die.
3510 (define_split
3511   [(set (match_operand:DI 0 "memory_operand" "")
3512         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3513    (clobber (reg:CC FLAGS_REG))
3514    (clobber (match_operand:SI 2 "register_operand" ""))]
3515   "reload_completed"
3516   [(const_int 0)]
3517 {
3518   split_di (&operands[0], 1, &operands[3], &operands[4]);
3519
3520   emit_move_insn (operands[3], operands[1]);
3521
3522   /* Generate a cltd if possible and doing so it profitable.  */
3523   if (true_regnum (operands[1]) == 0
3524       && true_regnum (operands[2]) == 1
3525       && (optimize_size || TARGET_USE_CLTD))
3526     {
3527       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3528     }
3529   else
3530     {
3531       emit_move_insn (operands[2], operands[1]);
3532       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3533     }
3534   emit_move_insn (operands[4], operands[2]);
3535   DONE;
3536 })
3537
3538 ;; Extend to register case.  Optimize case where source and destination
3539 ;; registers match and cases where we can use cltd.
3540 (define_split
3541   [(set (match_operand:DI 0 "register_operand" "")
3542         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3543    (clobber (reg:CC FLAGS_REG))
3544    (clobber (match_scratch:SI 2 ""))]
3545   "reload_completed"
3546   [(const_int 0)]
3547 {
3548   split_di (&operands[0], 1, &operands[3], &operands[4]);
3549
3550   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3551     emit_move_insn (operands[3], operands[1]);
3552
3553   /* Generate a cltd if possible and doing so it profitable.  */
3554   if (true_regnum (operands[3]) == 0
3555       && (optimize_size || TARGET_USE_CLTD))
3556     {
3557       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3558       DONE;
3559     }
3560
3561   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3562     emit_move_insn (operands[4], operands[1]);
3563
3564   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3565   DONE;
3566 })
3567
3568 (define_insn "extendhisi2"
3569   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3570         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3571   ""
3572 {
3573   switch (get_attr_prefix_0f (insn))
3574     {
3575     case 0:
3576       return "{cwtl|cwde}";
3577     default:
3578       return "movs{wl|x}\t{%1,%0|%0, %1}";
3579     }
3580 }
3581   [(set_attr "type" "imovx")
3582    (set_attr "mode" "SI")
3583    (set (attr "prefix_0f")
3584      ;; movsx is short decodable while cwtl is vector decoded.
3585      (if_then_else (and (eq_attr "cpu" "!k6")
3586                         (eq_attr "alternative" "0"))
3587         (const_string "0")
3588         (const_string "1")))
3589    (set (attr "modrm")
3590      (if_then_else (eq_attr "prefix_0f" "0")
3591         (const_string "0")
3592         (const_string "1")))])
3593
3594 (define_insn "*extendhisi2_zext"
3595   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3596         (zero_extend:DI
3597           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3598   "TARGET_64BIT"
3599 {
3600   switch (get_attr_prefix_0f (insn))
3601     {
3602     case 0:
3603       return "{cwtl|cwde}";
3604     default:
3605       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3606     }
3607 }
3608   [(set_attr "type" "imovx")
3609    (set_attr "mode" "SI")
3610    (set (attr "prefix_0f")
3611      ;; movsx is short decodable while cwtl is vector decoded.
3612      (if_then_else (and (eq_attr "cpu" "!k6")
3613                         (eq_attr "alternative" "0"))
3614         (const_string "0")
3615         (const_string "1")))
3616    (set (attr "modrm")
3617      (if_then_else (eq_attr "prefix_0f" "0")
3618         (const_string "0")
3619         (const_string "1")))])
3620
3621 (define_insn "extendqihi2"
3622   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3623         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3624   ""
3625 {
3626   switch (get_attr_prefix_0f (insn))
3627     {
3628     case 0:
3629       return "{cbtw|cbw}";
3630     default:
3631       return "movs{bw|x}\t{%1,%0|%0, %1}";
3632     }
3633 }
3634   [(set_attr "type" "imovx")
3635    (set_attr "mode" "HI")
3636    (set (attr "prefix_0f")
3637      ;; movsx is short decodable while cwtl is vector decoded.
3638      (if_then_else (and (eq_attr "cpu" "!k6")
3639                         (eq_attr "alternative" "0"))
3640         (const_string "0")
3641         (const_string "1")))
3642    (set (attr "modrm")
3643      (if_then_else (eq_attr "prefix_0f" "0")
3644         (const_string "0")
3645         (const_string "1")))])
3646
3647 (define_insn "extendqisi2"
3648   [(set (match_operand:SI 0 "register_operand" "=r")
3649         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3650   ""
3651   "movs{bl|x}\t{%1,%0|%0, %1}"
3652    [(set_attr "type" "imovx")
3653     (set_attr "mode" "SI")])
3654
3655 (define_insn "*extendqisi2_zext"
3656   [(set (match_operand:DI 0 "register_operand" "=r")
3657         (zero_extend:DI
3658           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3659   "TARGET_64BIT"
3660   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3661    [(set_attr "type" "imovx")
3662     (set_attr "mode" "SI")])
3663 \f
3664 ;; Conversions between float and double.
3665
3666 ;; These are all no-ops in the model used for the 80387.  So just
3667 ;; emit moves.
3668
3669 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3670 (define_insn "*dummy_extendsfdf2"
3671   [(set (match_operand:DF 0 "push_operand" "=<")
3672         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3673   "0"
3674   "#")
3675
3676 (define_split
3677   [(set (match_operand:DF 0 "push_operand" "")
3678         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3679   "!TARGET_64BIT"
3680   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3681    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3682
3683 (define_split
3684   [(set (match_operand:DF 0 "push_operand" "")
3685         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3686   "TARGET_64BIT"
3687   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3688    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3689
3690 (define_insn "*dummy_extendsfxf2"
3691   [(set (match_operand:XF 0 "push_operand" "=<")
3692         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3693   "0"
3694   "#")
3695
3696 (define_split
3697   [(set (match_operand:XF 0 "push_operand" "")
3698         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3699   ""
3700   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3701    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3702   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3703
3704 (define_split
3705   [(set (match_operand:XF 0 "push_operand" "")
3706         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3707   "TARGET_64BIT"
3708   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3709    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3710   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3711
3712 (define_split
3713   [(set (match_operand:XF 0 "push_operand" "")
3714         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3715   ""
3716   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3717    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3718   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3719
3720 (define_split
3721   [(set (match_operand:XF 0 "push_operand" "")
3722         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3723   "TARGET_64BIT"
3724   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3725    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3726   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3727
3728 (define_expand "extendsfdf2"
3729   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3730         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3731   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3732 {
3733   /* ??? Needed for compress_float_constant since all fp constants
3734      are LEGITIMATE_CONSTANT_P.  */
3735   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3736     {
3737       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3738           && standard_80387_constant_p (operands[1]) > 0)
3739         {
3740           operands[1] = simplify_const_unary_operation
3741             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3742           emit_move_insn_1 (operands[0], operands[1]);
3743           DONE;
3744         }
3745       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3746     }
3747 })
3748
3749 (define_insn "*extendsfdf2_mixed"
3750   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3751         (float_extend:DF
3752           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3753   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3754 {
3755   switch (which_alternative)
3756     {
3757     case 0:
3758     case 1:
3759       return output_387_reg_move (insn, operands);
3760
3761     case 2:
3762       return "cvtss2sd\t{%1, %0|%0, %1}";
3763
3764     default:
3765       gcc_unreachable ();
3766     }
3767 }
3768   [(set_attr "type" "fmov,fmov,ssecvt")
3769    (set_attr "mode" "SF,XF,DF")])
3770
3771 (define_insn "*extendsfdf2_sse"
3772   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3773         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3774   "TARGET_SSE2 && TARGET_SSE_MATH"
3775   "cvtss2sd\t{%1, %0|%0, %1}"
3776   [(set_attr "type" "ssecvt")
3777    (set_attr "mode" "DF")])
3778
3779 (define_insn "*extendsfdf2_i387"
3780   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3781         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3782   "TARGET_80387"
3783   "* return output_387_reg_move (insn, operands);"
3784   [(set_attr "type" "fmov")
3785    (set_attr "mode" "SF,XF")])
3786
3787 (define_expand "extendsfxf2"
3788   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3789         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3790   "TARGET_80387"
3791 {
3792   /* ??? Needed for compress_float_constant since all fp constants
3793      are LEGITIMATE_CONSTANT_P.  */
3794   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3795     {
3796       if (standard_80387_constant_p (operands[1]) > 0)
3797         {
3798           operands[1] = simplify_const_unary_operation
3799             (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3800           emit_move_insn_1 (operands[0], operands[1]);
3801           DONE;
3802         }
3803       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3804     }
3805 })
3806
3807 (define_insn "*extendsfxf2_i387"
3808   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3809         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3810   "TARGET_80387"
3811   "* return output_387_reg_move (insn, operands);"
3812   [(set_attr "type" "fmov")
3813    (set_attr "mode" "SF,XF")])
3814
3815 (define_expand "extenddfxf2"
3816   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3817         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3818   "TARGET_80387"
3819 {
3820   /* ??? Needed for compress_float_constant since all fp constants
3821      are LEGITIMATE_CONSTANT_P.  */
3822   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3823     {
3824       if (standard_80387_constant_p (operands[1]) > 0)
3825         {
3826           operands[1] = simplify_const_unary_operation
3827             (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3828           emit_move_insn_1 (operands[0], operands[1]);
3829           DONE;
3830         }
3831       operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3832     }
3833 })
3834
3835 (define_insn "*extenddfxf2_i387"
3836   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3837         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3838   "TARGET_80387"
3839   "* return output_387_reg_move (insn, operands);"
3840   [(set_attr "type" "fmov")
3841    (set_attr "mode" "DF,XF")])
3842
3843 ;; %%% This seems bad bad news.
3844 ;; This cannot output into an f-reg because there is no way to be sure
3845 ;; of truncating in that case.  Otherwise this is just like a simple move
3846 ;; insn.  So we pretend we can output to a reg in order to get better
3847 ;; register preferencing, but we really use a stack slot.
3848
3849 ;; Conversion from DFmode to SFmode.
3850
3851 (define_expand "truncdfsf2"
3852   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3853         (float_truncate:SF
3854           (match_operand:DF 1 "nonimmediate_operand" "")))]
3855   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3856 {
3857   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3858     ;
3859   else if (flag_unsafe_math_optimizations)
3860     ;
3861   else
3862     {
3863       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3864       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3865       DONE;
3866     }
3867 })
3868
3869 (define_expand "truncdfsf2_with_temp"
3870   [(parallel [(set (match_operand:SF 0 "" "")
3871                    (float_truncate:SF (match_operand:DF 1 "" "")))
3872               (clobber (match_operand:SF 2 "" ""))])]
3873   "")
3874
3875 (define_insn "*truncdfsf_fast_mixed"
3876   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,x")
3877         (float_truncate:SF
3878           (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
3879   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3880 {
3881   switch (which_alternative)
3882     {
3883     case 0:
3884     case 1:
3885       return output_387_reg_move (insn, operands);
3886     case 2:
3887       return "cvtsd2ss\t{%1, %0|%0, %1}";
3888     default:
3889       gcc_unreachable ();
3890     }
3891 }
3892   [(set_attr "type" "fmov,fmov,ssecvt")
3893    (set_attr "mode" "SF")])
3894
3895 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3896 ;; because nothing we do here is unsafe.
3897 (define_insn "*truncdfsf_fast_sse"
3898   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
3899         (float_truncate:SF
3900           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
3901   "TARGET_SSE2 && TARGET_SSE_MATH"
3902   "cvtsd2ss\t{%1, %0|%0, %1}"
3903   [(set_attr "type" "ssecvt")
3904    (set_attr "mode" "SF")])
3905
3906 (define_insn "*truncdfsf_fast_i387"
3907   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3908         (float_truncate:SF
3909           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3910   "TARGET_80387 && flag_unsafe_math_optimizations"
3911   "* return output_387_reg_move (insn, operands);"
3912   [(set_attr "type" "fmov")
3913    (set_attr "mode" "SF")])
3914
3915 (define_insn "*truncdfsf_mixed"
3916   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y2")
3917         (float_truncate:SF
3918           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Y2m")))
3919    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3920   "TARGET_MIX_SSE_I387"
3921 {
3922   switch (which_alternative)
3923     {
3924     case 0:
3925       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3926         return "fstp%z0\t%y0";
3927       else
3928         return "fst%z0\t%y0";
3929     case 1:
3930       return "#";
3931     case 2:
3932       return "cvtsd2ss\t{%1, %0|%0, %1}";
3933     default:
3934       gcc_unreachable ();
3935     }
3936 }
3937   [(set_attr "type" "fmov,multi,ssecvt")
3938    (set_attr "unit" "*,i387,*")
3939    (set_attr "mode" "SF")])
3940
3941 (define_insn "*truncdfsf_i387"
3942   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3943         (float_truncate:SF
3944           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3945    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3946   "TARGET_80387"
3947 {
3948   switch (which_alternative)
3949     {
3950     case 0:
3951       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3952         return "fstp%z0\t%y0";
3953       else
3954         return "fst%z0\t%y0";
3955     case 1:
3956       return "#";
3957     default:
3958       gcc_unreachable ();
3959     }
3960 }
3961   [(set_attr "type" "fmov,multi")
3962    (set_attr "unit" "*,i387")
3963    (set_attr "mode" "SF")])
3964
3965 (define_insn "*truncdfsf2_i387_1"
3966   [(set (match_operand:SF 0 "memory_operand" "=m")
3967         (float_truncate:SF
3968           (match_operand:DF 1 "register_operand" "f")))]
3969   "TARGET_80387
3970    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3971    && !TARGET_MIX_SSE_I387"
3972 {
3973   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3974     return "fstp%z0\t%y0";
3975   else
3976     return "fst%z0\t%y0";
3977 }
3978   [(set_attr "type" "fmov")
3979    (set_attr "mode" "SF")])
3980
3981 (define_split
3982   [(set (match_operand:SF 0 "register_operand" "")
3983         (float_truncate:SF
3984          (match_operand:DF 1 "fp_register_operand" "")))
3985    (clobber (match_operand 2 "" ""))]
3986   "reload_completed"
3987   [(set (match_dup 2) (match_dup 1))
3988    (set (match_dup 0) (match_dup 2))]
3989 {
3990   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3991 })
3992
3993 ;; Conversion from XFmode to SFmode.
3994
3995 (define_expand "truncxfsf2"
3996   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3997                    (float_truncate:SF
3998                     (match_operand:XF 1 "register_operand" "")))
3999               (clobber (match_dup 2))])]
4000   "TARGET_80387"
4001 {
4002   if (flag_unsafe_math_optimizations)
4003     {
4004       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
4005       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
4006       if (reg != operands[0])
4007         emit_move_insn (operands[0], reg);
4008       DONE;
4009     }
4010   else
4011     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
4012 })
4013
4014 (define_insn "*truncxfsf2_mixed"
4015   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
4016         (float_truncate:SF
4017          (match_operand:XF 1 "register_operand" "f,f,f,f")))
4018    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4019   "TARGET_80387"
4020 {
4021   gcc_assert (!which_alternative);
4022   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4023     return "fstp%z0\t%y0";
4024   else
4025     return "fst%z0\t%y0";
4026 }
4027   [(set_attr "type" "fmov,multi,multi,multi")
4028    (set_attr "unit" "*,i387,i387,i387")
4029    (set_attr "mode" "SF")])
4030
4031 (define_insn "truncxfsf2_i387_noop"
4032   [(set (match_operand:SF 0 "register_operand" "=f")
4033         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
4034   "TARGET_80387 && flag_unsafe_math_optimizations"
4035   "* return output_387_reg_move (insn, operands);"
4036   [(set_attr "type" "fmov")
4037    (set_attr "mode" "SF")])
4038
4039 (define_insn "*truncxfsf2_i387"
4040   [(set (match_operand:SF 0 "memory_operand" "=m")
4041         (float_truncate:SF
4042          (match_operand:XF 1 "register_operand" "f")))]
4043   "TARGET_80387"
4044 {
4045   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4046     return "fstp%z0\t%y0";
4047   else
4048     return "fst%z0\t%y0";
4049 }
4050   [(set_attr "type" "fmov")
4051    (set_attr "mode" "SF")])
4052
4053 (define_split
4054   [(set (match_operand:SF 0 "register_operand" "")
4055         (float_truncate:SF
4056          (match_operand:XF 1 "register_operand" "")))
4057    (clobber (match_operand:SF 2 "memory_operand" ""))]
4058   "TARGET_80387 && reload_completed"
4059   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4060    (set (match_dup 0) (match_dup 2))]
4061   "")
4062
4063 (define_split
4064   [(set (match_operand:SF 0 "memory_operand" "")
4065         (float_truncate:SF
4066          (match_operand:XF 1 "register_operand" "")))
4067    (clobber (match_operand:SF 2 "memory_operand" ""))]
4068   "TARGET_80387"
4069   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4070   "")
4071
4072 ;; Conversion from XFmode to DFmode.
4073
4074 (define_expand "truncxfdf2"
4075   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4076                    (float_truncate:DF
4077                     (match_operand:XF 1 "register_operand" "")))
4078               (clobber (match_dup 2))])]
4079   "TARGET_80387"
4080 {
4081   if (flag_unsafe_math_optimizations)
4082     {
4083       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4084       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4085       if (reg != operands[0])
4086         emit_move_insn (operands[0], reg);
4087       DONE;
4088     }
4089   else
4090     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
4091 })
4092
4093 (define_insn "*truncxfdf2_mixed"
4094   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y2*x")
4095         (float_truncate:DF
4096          (match_operand:XF 1 "register_operand" "f,f,f,f")))
4097    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4098   "TARGET_80387"
4099 {
4100   gcc_assert (!which_alternative);
4101   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4102     return "fstp%z0\t%y0";
4103   else
4104     return "fst%z0\t%y0";
4105 }
4106   [(set_attr "type" "fmov,multi,multi,multi")
4107    (set_attr "unit" "*,i387,i387,i387")
4108    (set_attr "mode" "DF")])
4109
4110 (define_insn "truncxfdf2_i387_noop"
4111   [(set (match_operand:DF 0 "register_operand" "=f")
4112         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4113   "TARGET_80387 && flag_unsafe_math_optimizations"
4114   "* return output_387_reg_move (insn, operands);"
4115   [(set_attr "type" "fmov")
4116    (set_attr "mode" "DF")])
4117
4118 (define_insn "*truncxfdf2_i387"
4119   [(set (match_operand:DF 0 "memory_operand" "=m")
4120         (float_truncate:DF
4121           (match_operand:XF 1 "register_operand" "f")))]
4122   "TARGET_80387"
4123 {
4124   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4125     return "fstp%z0\t%y0";
4126   else
4127     return "fst%z0\t%y0";
4128 }
4129   [(set_attr "type" "fmov")
4130    (set_attr "mode" "DF")])
4131
4132 (define_split
4133   [(set (match_operand:DF 0 "register_operand" "")
4134         (float_truncate:DF
4135          (match_operand:XF 1 "register_operand" "")))
4136    (clobber (match_operand:DF 2 "memory_operand" ""))]
4137   "TARGET_80387 && reload_completed"
4138   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4139    (set (match_dup 0) (match_dup 2))]
4140   "")
4141
4142 (define_split
4143   [(set (match_operand:DF 0 "memory_operand" "")
4144         (float_truncate:DF
4145          (match_operand:XF 1 "register_operand" "")))
4146    (clobber (match_operand:DF 2 "memory_operand" ""))]
4147   "TARGET_80387"
4148   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4149   "")
4150 \f
4151 ;; Signed conversion to DImode.
4152
4153 (define_expand "fix_truncxfdi2"
4154   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4155                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4156               (clobber (reg:CC FLAGS_REG))])]
4157   "TARGET_80387"
4158 {
4159   if (TARGET_FISTTP)
4160    {
4161      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4162      DONE;
4163    }
4164 })
4165
4166 (define_expand "fix_trunc<mode>di2"
4167   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4168                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4169               (clobber (reg:CC FLAGS_REG))])]
4170   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4171 {
4172   if (TARGET_FISTTP
4173       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4174    {
4175      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4176      DONE;
4177    }
4178   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4179    {
4180      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4181      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4182      if (out != operands[0])
4183         emit_move_insn (operands[0], out);
4184      DONE;
4185    }
4186 })
4187
4188 ;; Signed conversion to SImode.
4189
4190 (define_expand "fix_truncxfsi2"
4191   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4192                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4193               (clobber (reg:CC FLAGS_REG))])]
4194   "TARGET_80387"
4195 {
4196   if (TARGET_FISTTP)
4197    {
4198      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4199      DONE;
4200    }
4201 })
4202
4203 (define_expand "fix_trunc<mode>si2"
4204   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4205                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4206               (clobber (reg:CC FLAGS_REG))])]
4207   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4208 {
4209   if (TARGET_FISTTP
4210       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4211    {
4212      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4213      DONE;
4214    }
4215   if (SSE_FLOAT_MODE_P (<MODE>mode))
4216    {
4217      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4218      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4219      if (out != operands[0])
4220         emit_move_insn (operands[0], out);
4221      DONE;
4222    }
4223 })
4224
4225 ;; Signed conversion to HImode.
4226
4227 (define_expand "fix_trunc<mode>hi2"
4228   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4229                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4230               (clobber (reg:CC FLAGS_REG))])]
4231   "TARGET_80387
4232    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4233 {
4234   if (TARGET_FISTTP)
4235    {
4236      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4237      DONE;
4238    }
4239 })
4240
4241 ;; Unsigned conversion to SImode.
4242
4243 (define_expand "fixuns_trunc<mode>si2"
4244   [(parallel
4245     [(set (match_operand:SI 0 "register_operand" "")
4246           (unsigned_fix:SI
4247             (match_operand:SSEMODEF 1 "nonimmediate_operand" "")))
4248      (use (match_dup 2))
4249      (clobber (match_scratch:<ssevecmode> 3 ""))
4250      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4251   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4252 {
4253   enum machine_mode mode = <MODE>mode;
4254   enum machine_mode vecmode = <ssevecmode>mode;
4255   REAL_VALUE_TYPE TWO31r;
4256   rtx two31;
4257
4258   real_ldexp (&TWO31r, &dconst1, 31);
4259   two31 = const_double_from_real_value (TWO31r, mode);
4260   two31 = ix86_build_const_vector (mode, true, two31);
4261   operands[2] = force_reg (vecmode, two31);
4262 })
4263
4264 (define_insn_and_split "*fixuns_trunc<mode>_1"
4265   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4266         (unsigned_fix:SI
4267           (match_operand:SSEMODEF 3 "nonimmediate_operand" "xm,xm")))
4268    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4269    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4270    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4271   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4272   "#"
4273   "&& reload_completed"
4274   [(const_int 0)]
4275 {
4276   ix86_split_convert_uns_si_sse (operands);
4277   DONE;
4278 })
4279
4280 ;; Unsigned conversion to HImode.
4281 ;; Without these patterns, we'll try the unsigned SI conversion which
4282 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4283
4284 (define_expand "fixuns_trunc<mode>hi2"
4285   [(set (match_dup 2)
4286         (fix:SI (match_operand:SSEMODEF 1 "nonimmediate_operand" "")))
4287    (set (match_operand:HI 0 "nonimmediate_operand" "")
4288         (subreg:HI (match_dup 2) 0))]
4289   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4290   "operands[2] = gen_reg_rtx (SImode);")
4291
4292 ;; When SSE is available, it is always faster to use it!
4293 (define_insn "fix_trunc<mode>di_sse"
4294   [(set (match_operand:DI 0 "register_operand" "=r,r")
4295         (fix:DI (match_operand:SSEMODEF 1 "nonimmediate_operand" "x,xm")))]
4296   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4297    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4298   "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4299   [(set_attr "type" "sseicvt")
4300    (set_attr "mode" "<MODE>")
4301    (set_attr "athlon_decode" "double,vector")
4302    (set_attr "amdfam10_decode" "double,double")])
4303
4304 (define_insn "fix_trunc<mode>si_sse"
4305   [(set (match_operand:SI 0 "register_operand" "=r,r")
4306         (fix:SI (match_operand:SSEMODEF 1 "nonimmediate_operand" "x,xm")))]
4307   "SSE_FLOAT_MODE_P (<MODE>mode)
4308    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4309   "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4310   [(set_attr "type" "sseicvt")
4311    (set_attr "mode" "<MODE>")
4312    (set_attr "athlon_decode" "double,vector")
4313    (set_attr "amdfam10_decode" "double,double")])
4314
4315 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4316 (define_peephole2
4317   [(set (match_operand:SSEMODEF 0 "register_operand" "")
4318         (match_operand:SSEMODEF 1 "memory_operand" ""))
4319    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4320         (fix:SSEMODEI24 (match_dup 0)))]
4321   "TARGET_SHORTEN_X87_SSE
4322    && peep2_reg_dead_p (2, operands[0])"
4323   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4324   "")
4325
4326 ;; Avoid vector decoded forms of the instruction.
4327 (define_peephole2
4328   [(match_scratch:DF 2 "Y2")
4329    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4330         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4331   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4332   [(set (match_dup 2) (match_dup 1))
4333    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4334   "")
4335
4336 (define_peephole2
4337   [(match_scratch:SF 2 "x")
4338    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4339         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4340   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4341   [(set (match_dup 2) (match_dup 1))
4342    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4343   "")
4344
4345 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4346   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4347         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4348   "TARGET_FISTTP
4349    && FLOAT_MODE_P (GET_MODE (operands[1]))
4350    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4351          && (TARGET_64BIT || <MODE>mode != DImode))
4352         && TARGET_SSE_MATH)
4353    && !(reload_completed || reload_in_progress)"
4354   "#"
4355   "&& 1"
4356   [(const_int 0)]
4357 {
4358   if (memory_operand (operands[0], VOIDmode))
4359     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4360   else
4361     {
4362       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4363       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4364                                                             operands[1],
4365                                                             operands[2]));
4366     }
4367   DONE;
4368 }
4369   [(set_attr "type" "fisttp")
4370    (set_attr "mode" "<MODE>")])
4371
4372 (define_insn "fix_trunc<mode>_i387_fisttp"
4373   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4374         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4375    (clobber (match_scratch:XF 2 "=&1f"))]
4376   "TARGET_FISTTP
4377    && FLOAT_MODE_P (GET_MODE (operands[1]))
4378    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4379          && (TARGET_64BIT || <MODE>mode != DImode))
4380         && TARGET_SSE_MATH)"
4381   "* return output_fix_trunc (insn, operands, 1);"
4382   [(set_attr "type" "fisttp")
4383    (set_attr "mode" "<MODE>")])
4384
4385 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4386   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4387         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4388    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4389    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4390   "TARGET_FISTTP
4391    && FLOAT_MODE_P (GET_MODE (operands[1]))
4392    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4393         && (TARGET_64BIT || <MODE>mode != DImode))
4394         && TARGET_SSE_MATH)"
4395   "#"
4396   [(set_attr "type" "fisttp")
4397    (set_attr "mode" "<MODE>")])
4398
4399 (define_split
4400   [(set (match_operand:X87MODEI 0 "register_operand" "")
4401         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4402    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4403    (clobber (match_scratch 3 ""))]
4404   "reload_completed"
4405   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4406               (clobber (match_dup 3))])
4407    (set (match_dup 0) (match_dup 2))]
4408   "")
4409
4410 (define_split
4411   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4412         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4413    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4414    (clobber (match_scratch 3 ""))]
4415   "reload_completed"
4416   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4417               (clobber (match_dup 3))])]
4418   "")
4419
4420 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4421 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4422 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4423 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4424 ;; function in i386.c.
4425 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4426   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4427         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4428    (clobber (reg:CC FLAGS_REG))]
4429   "TARGET_80387 && !TARGET_FISTTP
4430    && FLOAT_MODE_P (GET_MODE (operands[1]))
4431    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4432          && (TARGET_64BIT || <MODE>mode != DImode))
4433    && !(reload_completed || reload_in_progress)"
4434   "#"
4435   "&& 1"
4436   [(const_int 0)]
4437 {
4438   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4439
4440   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4441   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4442   if (memory_operand (operands[0], VOIDmode))
4443     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4444                                          operands[2], operands[3]));
4445   else
4446     {
4447       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4448       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4449                                                      operands[2], operands[3],
4450                                                      operands[4]));
4451     }
4452   DONE;
4453 }
4454   [(set_attr "type" "fistp")
4455    (set_attr "i387_cw" "trunc")
4456    (set_attr "mode" "<MODE>")])
4457
4458 (define_insn "fix_truncdi_i387"
4459   [(set (match_operand:DI 0 "memory_operand" "=m")
4460         (fix:DI (match_operand 1 "register_operand" "f")))
4461    (use (match_operand:HI 2 "memory_operand" "m"))
4462    (use (match_operand:HI 3 "memory_operand" "m"))
4463    (clobber (match_scratch:XF 4 "=&1f"))]
4464   "TARGET_80387 && !TARGET_FISTTP
4465    && FLOAT_MODE_P (GET_MODE (operands[1]))
4466    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4467   "* return output_fix_trunc (insn, operands, 0);"
4468   [(set_attr "type" "fistp")
4469    (set_attr "i387_cw" "trunc")
4470    (set_attr "mode" "DI")])
4471
4472 (define_insn "fix_truncdi_i387_with_temp"
4473   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4474         (fix:DI (match_operand 1 "register_operand" "f,f")))
4475    (use (match_operand:HI 2 "memory_operand" "m,m"))
4476    (use (match_operand:HI 3 "memory_operand" "m,m"))
4477    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4478    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4479   "TARGET_80387 && !TARGET_FISTTP
4480    && FLOAT_MODE_P (GET_MODE (operands[1]))
4481    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4482   "#"
4483   [(set_attr "type" "fistp")
4484    (set_attr "i387_cw" "trunc")
4485    (set_attr "mode" "DI")])
4486
4487 (define_split
4488   [(set (match_operand:DI 0 "register_operand" "")
4489         (fix:DI (match_operand 1 "register_operand" "")))
4490    (use (match_operand:HI 2 "memory_operand" ""))
4491    (use (match_operand:HI 3 "memory_operand" ""))
4492    (clobber (match_operand:DI 4 "memory_operand" ""))
4493    (clobber (match_scratch 5 ""))]
4494   "reload_completed"
4495   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4496               (use (match_dup 2))
4497               (use (match_dup 3))
4498               (clobber (match_dup 5))])
4499    (set (match_dup 0) (match_dup 4))]
4500   "")
4501
4502 (define_split
4503   [(set (match_operand:DI 0 "memory_operand" "")
4504         (fix:DI (match_operand 1 "register_operand" "")))
4505    (use (match_operand:HI 2 "memory_operand" ""))
4506    (use (match_operand:HI 3 "memory_operand" ""))
4507    (clobber (match_operand:DI 4 "memory_operand" ""))
4508    (clobber (match_scratch 5 ""))]
4509   "reload_completed"
4510   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4511               (use (match_dup 2))
4512               (use (match_dup 3))
4513               (clobber (match_dup 5))])]
4514   "")
4515
4516 (define_insn "fix_trunc<mode>_i387"
4517   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4518         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4519    (use (match_operand:HI 2 "memory_operand" "m"))
4520    (use (match_operand:HI 3 "memory_operand" "m"))]
4521   "TARGET_80387 && !TARGET_FISTTP
4522    && FLOAT_MODE_P (GET_MODE (operands[1]))
4523    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4524   "* return output_fix_trunc (insn, operands, 0);"
4525   [(set_attr "type" "fistp")
4526    (set_attr "i387_cw" "trunc")
4527    (set_attr "mode" "<MODE>")])
4528
4529 (define_insn "fix_trunc<mode>_i387_with_temp"
4530   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4531         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4532    (use (match_operand:HI 2 "memory_operand" "m,m"))
4533    (use (match_operand:HI 3 "memory_operand" "m,m"))
4534    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4535   "TARGET_80387 && !TARGET_FISTTP
4536    && FLOAT_MODE_P (GET_MODE (operands[1]))
4537    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4538   "#"
4539   [(set_attr "type" "fistp")
4540    (set_attr "i387_cw" "trunc")
4541    (set_attr "mode" "<MODE>")])
4542
4543 (define_split
4544   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4545         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4546    (use (match_operand:HI 2 "memory_operand" ""))
4547    (use (match_operand:HI 3 "memory_operand" ""))
4548    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4549   "reload_completed"
4550   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4551               (use (match_dup 2))
4552               (use (match_dup 3))])
4553    (set (match_dup 0) (match_dup 4))]
4554   "")
4555
4556 (define_split
4557   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4558         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4559    (use (match_operand:HI 2 "memory_operand" ""))
4560    (use (match_operand:HI 3 "memory_operand" ""))
4561    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4562   "reload_completed"
4563   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4564               (use (match_dup 2))
4565               (use (match_dup 3))])]
4566   "")
4567
4568 (define_insn "x86_fnstcw_1"
4569   [(set (match_operand:HI 0 "memory_operand" "=m")
4570         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4571   "TARGET_80387"
4572   "fnstcw\t%0"
4573   [(set_attr "length" "2")
4574    (set_attr "mode" "HI")
4575    (set_attr "unit" "i387")])
4576
4577 (define_insn "x86_fldcw_1"
4578   [(set (reg:HI FPCR_REG)
4579         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4580   "TARGET_80387"
4581   "fldcw\t%0"
4582   [(set_attr "length" "2")
4583    (set_attr "mode" "HI")
4584    (set_attr "unit" "i387")
4585    (set_attr "athlon_decode" "vector")
4586    (set_attr "amdfam10_decode" "vector")])   
4587 \f
4588 ;; Conversion between fixed point and floating point.
4589
4590 ;; Even though we only accept memory inputs, the backend _really_
4591 ;; wants to be able to do this between registers.
4592
4593 (define_expand "floathisf2"
4594   [(set (match_operand:SF 0 "register_operand" "")
4595         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4596   "TARGET_80387 || TARGET_SSE_MATH"
4597 {
4598   if (TARGET_SSE_MATH)
4599     {
4600       emit_insn (gen_floatsisf2 (operands[0],
4601                                  convert_to_mode (SImode, operands[1], 0)));
4602       DONE;
4603     }
4604 })
4605
4606 (define_insn "*floathisf2_i387"
4607   [(set (match_operand:SF 0 "register_operand" "=f,f")
4608         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4609   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4610   "@
4611    fild%z1\t%1
4612    #"
4613   [(set_attr "type" "fmov,multi")
4614    (set_attr "mode" "SF")
4615    (set_attr "unit" "*,i387")
4616    (set_attr "fp_int_src" "true")])
4617
4618 (define_expand "floatsisf2"
4619   [(set (match_operand:SF 0 "register_operand" "")
4620         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4621   "TARGET_80387 || TARGET_SSE_MATH"
4622   "")
4623
4624 (define_insn "*floatsisf2_mixed"
4625   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4626         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4627   "TARGET_MIX_SSE_I387"
4628   "@
4629    fild%z1\t%1
4630    #
4631    cvtsi2ss\t{%1, %0|%0, %1}
4632    cvtsi2ss\t{%1, %0|%0, %1}"
4633   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4634    (set_attr "mode" "SF")
4635    (set_attr "unit" "*,i387,*,*")
4636    (set_attr "athlon_decode" "*,*,vector,double")
4637    (set_attr "amdfam10_decode" "*,*,vector,double")
4638    (set_attr "fp_int_src" "true")])
4639
4640 (define_insn "*floatsisf2_sse"
4641   [(set (match_operand:SF 0 "register_operand" "=x,x")
4642         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4643   "TARGET_SSE_MATH"
4644   "cvtsi2ss\t{%1, %0|%0, %1}"
4645   [(set_attr "type" "sseicvt")
4646    (set_attr "mode" "SF")
4647    (set_attr "athlon_decode" "vector,double")
4648    (set_attr "amdfam10_decode" "vector,double")
4649    (set_attr "fp_int_src" "true")])
4650
4651 (define_insn "*floatsisf2_i387"
4652   [(set (match_operand:SF 0 "register_operand" "=f,f")
4653         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4654   "TARGET_80387"
4655   "@
4656    fild%z1\t%1
4657    #"
4658   [(set_attr "type" "fmov,multi")
4659    (set_attr "mode" "SF")
4660    (set_attr "unit" "*,i387")
4661    (set_attr "fp_int_src" "true")])
4662
4663 (define_expand "floatdisf2"
4664   [(set (match_operand:SF 0 "register_operand" "")
4665         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4666   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4667   "")
4668
4669 (define_insn "*floatdisf2_mixed"
4670   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4671         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4672   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4673   "@
4674    fild%z1\t%1
4675    #
4676    cvtsi2ss{q}\t{%1, %0|%0, %1}
4677    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4678   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4679    (set_attr "mode" "SF")
4680    (set_attr "unit" "*,i387,*,*")
4681    (set_attr "athlon_decode" "*,*,vector,double")
4682    (set_attr "amdfam10_decode" "*,*,vector,double")
4683    (set_attr "fp_int_src" "true")])
4684
4685 (define_insn "*floatdisf2_sse"
4686   [(set (match_operand:SF 0 "register_operand" "=x,x")
4687         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4688   "TARGET_64BIT && TARGET_SSE_MATH"
4689   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4690   [(set_attr "type" "sseicvt")
4691    (set_attr "mode" "SF")
4692    (set_attr "athlon_decode" "vector,double")
4693    (set_attr "amdfam10_decode" "vector,double")
4694    (set_attr "fp_int_src" "true")])
4695
4696 (define_insn "*floatdisf2_i387"
4697   [(set (match_operand:SF 0 "register_operand" "=f,f")
4698         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4699   "TARGET_80387"
4700   "@
4701    fild%z1\t%1
4702    #"
4703   [(set_attr "type" "fmov,multi")
4704    (set_attr "mode" "SF")
4705    (set_attr "unit" "*,i387")
4706    (set_attr "fp_int_src" "true")])
4707
4708 (define_expand "floathidf2"
4709   [(set (match_operand:DF 0 "register_operand" "")
4710         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4711   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4712 {
4713   if (TARGET_SSE2 && TARGET_SSE_MATH)
4714     {
4715       emit_insn (gen_floatsidf2 (operands[0],
4716                                  convert_to_mode (SImode, operands[1], 0)));
4717       DONE;
4718     }
4719 })
4720
4721 (define_insn "*floathidf2_i387"
4722   [(set (match_operand:DF 0 "register_operand" "=f,f")
4723         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4724   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4725   "@
4726    fild%z1\t%1
4727    #"
4728   [(set_attr "type" "fmov,multi")
4729    (set_attr "mode" "DF")
4730    (set_attr "unit" "*,i387")
4731    (set_attr "fp_int_src" "true")])
4732
4733 (define_expand "floatsidf2"
4734   [(set (match_operand:DF 0 "register_operand" "")
4735         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4736   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4737   "")
4738
4739 (define_insn "*floatsidf2_mixed"
4740   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4741         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4742   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4743   "@
4744    fild%z1\t%1
4745    #
4746    cvtsi2sd\t{%1, %0|%0, %1}
4747    cvtsi2sd\t{%1, %0|%0, %1}"
4748   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4749    (set_attr "mode" "DF")
4750    (set_attr "unit" "*,i387,*,*")
4751    (set_attr "athlon_decode" "*,*,double,direct")
4752    (set_attr "amdfam10_decode" "*,*,vector,double")
4753    (set_attr "fp_int_src" "true")])
4754
4755 (define_insn "*floatsidf2_sse"
4756   [(set (match_operand:DF 0 "register_operand" "=x,x")
4757         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4758   "TARGET_SSE2 && TARGET_SSE_MATH"
4759   "cvtsi2sd\t{%1, %0|%0, %1}"
4760   [(set_attr "type" "sseicvt")
4761    (set_attr "mode" "DF")
4762    (set_attr "athlon_decode" "double,direct")
4763    (set_attr "amdfam10_decode" "vector,double")
4764    (set_attr "fp_int_src" "true")])
4765
4766 (define_insn "*floatsidf2_i387"
4767   [(set (match_operand:DF 0 "register_operand" "=f,f")
4768         (float:DF (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" "DF")
4775    (set_attr "unit" "*,i387")
4776    (set_attr "fp_int_src" "true")])
4777
4778 (define_expand "floatdidf2"
4779   [(set (match_operand:DF 0 "register_operand" "")
4780         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4781   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4782 {
4783   if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
4784     {
4785       ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
4786       DONE;
4787     }
4788 })
4789
4790 (define_insn "*floatdidf2_mixed"
4791   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4792         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4793   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4794   "@
4795    fild%z1\t%1
4796    #
4797    cvtsi2sd{q}\t{%1, %0|%0, %1}
4798    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4799   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4800    (set_attr "mode" "DF")
4801    (set_attr "unit" "*,i387,*,*")
4802    (set_attr "athlon_decode" "*,*,double,direct")
4803    (set_attr "amdfam10_decode" "*,*,vector,double")
4804    (set_attr "fp_int_src" "true")])
4805
4806 (define_insn "*floatdidf2_sse"
4807   [(set (match_operand:DF 0 "register_operand" "=x,x")
4808         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4809   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4810   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4811   [(set_attr "type" "sseicvt")
4812    (set_attr "mode" "DF")
4813    (set_attr "athlon_decode" "double,direct")
4814    (set_attr "amdfam10_decode" "vector,double")
4815    (set_attr "fp_int_src" "true")])
4816
4817 (define_insn "*floatdidf2_i387"
4818   [(set (match_operand:DF 0 "register_operand" "=f,f")
4819         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4820   "TARGET_80387"
4821   "@
4822    fild%z1\t%1
4823    #"
4824   [(set_attr "type" "fmov,multi")
4825    (set_attr "mode" "DF")
4826    (set_attr "unit" "*,i387")
4827    (set_attr "fp_int_src" "true")])
4828
4829 (define_insn "floathixf2"
4830   [(set (match_operand:XF 0 "register_operand" "=f,f")
4831         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4832   "TARGET_80387"
4833   "@
4834    fild%z1\t%1
4835    #"
4836   [(set_attr "type" "fmov,multi")
4837    (set_attr "mode" "XF")
4838    (set_attr "unit" "*,i387")
4839    (set_attr "fp_int_src" "true")])
4840
4841 (define_insn "floatsixf2"
4842   [(set (match_operand:XF 0 "register_operand" "=f,f")
4843         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4844   "TARGET_80387"
4845   "@
4846    fild%z1\t%1
4847    #"
4848   [(set_attr "type" "fmov,multi")
4849    (set_attr "mode" "XF")
4850    (set_attr "unit" "*,i387")
4851    (set_attr "fp_int_src" "true")])
4852
4853 (define_insn "floatdixf2"
4854   [(set (match_operand:XF 0 "register_operand" "=f,f")
4855         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4856   "TARGET_80387"
4857   "@
4858    fild%z1\t%1
4859    #"
4860   [(set_attr "type" "fmov,multi")
4861    (set_attr "mode" "XF")
4862    (set_attr "unit" "*,i387")
4863    (set_attr "fp_int_src" "true")])
4864
4865 ;; %%% Kill these when reload knows how to do it.
4866 (define_split
4867   [(set (match_operand 0 "fp_register_operand" "")
4868         (float (match_operand 1 "register_operand" "")))]
4869   "reload_completed
4870    && TARGET_80387
4871    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4872   [(const_int 0)]
4873 {
4874   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4875   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4876   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4877   ix86_free_from_memory (GET_MODE (operands[1]));
4878   DONE;
4879 })
4880
4881 (define_expand "floatunssisf2"
4882   [(use (match_operand:SF 0 "register_operand" ""))
4883    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
4884   "!TARGET_64BIT"
4885 {
4886   if (TARGET_SSE_MATH && TARGET_SSE2)
4887     ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
4888   else
4889     x86_emit_floatuns (operands);
4890   DONE;
4891 })
4892
4893 (define_expand "floatunssidf2"
4894   [(use (match_operand:DF 0 "register_operand" ""))
4895    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
4896   "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
4897   "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
4898
4899 (define_expand "floatunsdisf2"
4900   [(use (match_operand:SF 0 "register_operand" ""))
4901    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
4902   "TARGET_64BIT && TARGET_SSE_MATH"
4903   "x86_emit_floatuns (operands); DONE;")
4904
4905 (define_expand "floatunsdidf2"
4906   [(use (match_operand:DF 0 "register_operand" ""))
4907    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
4908   "TARGET_SSE_MATH && TARGET_SSE2
4909    && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
4910 {
4911   if (TARGET_64BIT)
4912     x86_emit_floatuns (operands);
4913   else
4914     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
4915   DONE;
4916 })
4917 \f
4918 ;; SSE extract/set expanders
4919
4920 \f
4921 ;; Add instructions
4922
4923 ;; %%% splits for addditi3
4924
4925 (define_expand "addti3"
4926   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4927         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4928                  (match_operand:TI 2 "x86_64_general_operand" "")))
4929    (clobber (reg:CC FLAGS_REG))]
4930   "TARGET_64BIT"
4931   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4932
4933 (define_insn "*addti3_1"
4934   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4935         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4936                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
4937    (clobber (reg:CC FLAGS_REG))]
4938   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4939   "#")
4940
4941 (define_split
4942   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4943         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4944                  (match_operand:TI 2 "x86_64_general_operand" "")))
4945    (clobber (reg:CC FLAGS_REG))]
4946   "TARGET_64BIT && reload_completed"
4947   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4948                                           UNSPEC_ADD_CARRY))
4949               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4950    (parallel [(set (match_dup 3)
4951                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4952                                      (match_dup 4))
4953                             (match_dup 5)))
4954               (clobber (reg:CC FLAGS_REG))])]
4955   "split_ti (operands+0, 1, operands+0, operands+3);
4956    split_ti (operands+1, 1, operands+1, operands+4);
4957    split_ti (operands+2, 1, operands+2, operands+5);")
4958
4959 ;; %%% splits for addsidi3
4960 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4961 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4962 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4963
4964 (define_expand "adddi3"
4965   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4966         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4967                  (match_operand:DI 2 "x86_64_general_operand" "")))
4968    (clobber (reg:CC FLAGS_REG))]
4969   ""
4970   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4971
4972 (define_insn "*adddi3_1"
4973   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4974         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4975                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4976    (clobber (reg:CC FLAGS_REG))]
4977   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4978   "#")
4979
4980 (define_split
4981   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4982         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4983                  (match_operand:DI 2 "general_operand" "")))
4984    (clobber (reg:CC FLAGS_REG))]
4985   "!TARGET_64BIT && reload_completed"
4986   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4987                                           UNSPEC_ADD_CARRY))
4988               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4989    (parallel [(set (match_dup 3)
4990                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4991                                      (match_dup 4))
4992                             (match_dup 5)))
4993               (clobber (reg:CC FLAGS_REG))])]
4994   "split_di (operands+0, 1, operands+0, operands+3);
4995    split_di (operands+1, 1, operands+1, operands+4);
4996    split_di (operands+2, 1, operands+2, operands+5);")
4997
4998 (define_insn "adddi3_carry_rex64"
4999   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5000           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5001                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5002                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5003    (clobber (reg:CC FLAGS_REG))]
5004   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5005   "adc{q}\t{%2, %0|%0, %2}"
5006   [(set_attr "type" "alu")
5007    (set_attr "pent_pair" "pu")
5008    (set_attr "mode" "DI")])
5009
5010 (define_insn "*adddi3_cc_rex64"
5011   [(set (reg:CC FLAGS_REG)
5012         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5013                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5014                    UNSPEC_ADD_CARRY))
5015    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5016         (plus:DI (match_dup 1) (match_dup 2)))]
5017   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5018   "add{q}\t{%2, %0|%0, %2}"
5019   [(set_attr "type" "alu")
5020    (set_attr "mode" "DI")])
5021
5022 (define_insn "addqi3_carry"
5023   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5024           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5025                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5026                    (match_operand:QI 2 "general_operand" "qi,qm")))
5027    (clobber (reg:CC FLAGS_REG))]
5028   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5029   "adc{b}\t{%2, %0|%0, %2}"
5030   [(set_attr "type" "alu")
5031    (set_attr "pent_pair" "pu")
5032    (set_attr "mode" "QI")])
5033
5034 (define_insn "addhi3_carry"
5035   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5036           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5037                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5038                    (match_operand:HI 2 "general_operand" "ri,rm")))
5039    (clobber (reg:CC FLAGS_REG))]
5040   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5041   "adc{w}\t{%2, %0|%0, %2}"
5042   [(set_attr "type" "alu")
5043    (set_attr "pent_pair" "pu")
5044    (set_attr "mode" "HI")])
5045
5046 (define_insn "addsi3_carry"
5047   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5048           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5049                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5050                    (match_operand:SI 2 "general_operand" "ri,rm")))
5051    (clobber (reg:CC FLAGS_REG))]
5052   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5053   "adc{l}\t{%2, %0|%0, %2}"
5054   [(set_attr "type" "alu")
5055    (set_attr "pent_pair" "pu")
5056    (set_attr "mode" "SI")])
5057
5058 (define_insn "*addsi3_carry_zext"
5059   [(set (match_operand:DI 0 "register_operand" "=r")
5060           (zero_extend:DI
5061             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5062                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5063                      (match_operand:SI 2 "general_operand" "rim"))))
5064    (clobber (reg:CC FLAGS_REG))]
5065   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5066   "adc{l}\t{%2, %k0|%k0, %2}"
5067   [(set_attr "type" "alu")
5068    (set_attr "pent_pair" "pu")
5069    (set_attr "mode" "SI")])
5070
5071 (define_insn "*addsi3_cc"
5072   [(set (reg:CC FLAGS_REG)
5073         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5074                     (match_operand:SI 2 "general_operand" "ri,rm")]
5075                    UNSPEC_ADD_CARRY))
5076    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5077         (plus:SI (match_dup 1) (match_dup 2)))]
5078   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5079   "add{l}\t{%2, %0|%0, %2}"
5080   [(set_attr "type" "alu")
5081    (set_attr "mode" "SI")])
5082
5083 (define_insn "addqi3_cc"
5084   [(set (reg:CC FLAGS_REG)
5085         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5086                     (match_operand:QI 2 "general_operand" "qi,qm")]
5087                    UNSPEC_ADD_CARRY))
5088    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5089         (plus:QI (match_dup 1) (match_dup 2)))]
5090   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5091   "add{b}\t{%2, %0|%0, %2}"
5092   [(set_attr "type" "alu")
5093    (set_attr "mode" "QI")])
5094
5095 (define_expand "addsi3"
5096   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5097                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5098                             (match_operand:SI 2 "general_operand" "")))
5099               (clobber (reg:CC FLAGS_REG))])]
5100   ""
5101   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5102
5103 (define_insn "*lea_1"
5104   [(set (match_operand:SI 0 "register_operand" "=r")
5105         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5106   "!TARGET_64BIT"
5107   "lea{l}\t{%a1, %0|%0, %a1}"
5108   [(set_attr "type" "lea")
5109    (set_attr "mode" "SI")])
5110
5111 (define_insn "*lea_1_rex64"
5112   [(set (match_operand:SI 0 "register_operand" "=r")
5113         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5114   "TARGET_64BIT"
5115   "lea{l}\t{%a1, %0|%0, %a1}"
5116   [(set_attr "type" "lea")
5117    (set_attr "mode" "SI")])
5118
5119 (define_insn "*lea_1_zext"
5120   [(set (match_operand:DI 0 "register_operand" "=r")
5121         (zero_extend:DI
5122          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5123   "TARGET_64BIT"
5124   "lea{l}\t{%a1, %k0|%k0, %a1}"
5125   [(set_attr "type" "lea")
5126    (set_attr "mode" "SI")])
5127
5128 (define_insn "*lea_2_rex64"
5129   [(set (match_operand:DI 0 "register_operand" "=r")
5130         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5131   "TARGET_64BIT"
5132   "lea{q}\t{%a1, %0|%0, %a1}"
5133   [(set_attr "type" "lea")
5134    (set_attr "mode" "DI")])
5135
5136 ;; The lea patterns for non-Pmodes needs to be matched by several
5137 ;; insns converted to real lea by splitters.
5138
5139 (define_insn_and_split "*lea_general_1"
5140   [(set (match_operand 0 "register_operand" "=r")
5141         (plus (plus (match_operand 1 "index_register_operand" "l")
5142                     (match_operand 2 "register_operand" "r"))
5143               (match_operand 3 "immediate_operand" "i")))]
5144   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5145     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5146    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5147    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5148    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5149    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5150        || GET_MODE (operands[3]) == VOIDmode)"
5151   "#"
5152   "&& reload_completed"
5153   [(const_int 0)]
5154 {
5155   rtx pat;
5156   operands[0] = gen_lowpart (SImode, operands[0]);
5157   operands[1] = gen_lowpart (Pmode, operands[1]);
5158   operands[2] = gen_lowpart (Pmode, operands[2]);
5159   operands[3] = gen_lowpart (Pmode, operands[3]);
5160   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5161                       operands[3]);
5162   if (Pmode != SImode)
5163     pat = gen_rtx_SUBREG (SImode, pat, 0);
5164   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5165   DONE;
5166 }
5167   [(set_attr "type" "lea")
5168    (set_attr "mode" "SI")])
5169
5170 (define_insn_and_split "*lea_general_1_zext"
5171   [(set (match_operand:DI 0 "register_operand" "=r")
5172         (zero_extend:DI
5173           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5174                             (match_operand:SI 2 "register_operand" "r"))
5175                    (match_operand:SI 3 "immediate_operand" "i"))))]
5176   "TARGET_64BIT"
5177   "#"
5178   "&& reload_completed"
5179   [(set (match_dup 0)
5180         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5181                                                      (match_dup 2))
5182                                             (match_dup 3)) 0)))]
5183 {
5184   operands[1] = gen_lowpart (Pmode, operands[1]);
5185   operands[2] = gen_lowpart (Pmode, operands[2]);
5186   operands[3] = gen_lowpart (Pmode, operands[3]);
5187 }
5188   [(set_attr "type" "lea")
5189    (set_attr "mode" "SI")])
5190
5191 (define_insn_and_split "*lea_general_2"
5192   [(set (match_operand 0 "register_operand" "=r")
5193         (plus (mult (match_operand 1 "index_register_operand" "l")
5194                     (match_operand 2 "const248_operand" "i"))
5195               (match_operand 3 "nonmemory_operand" "ri")))]
5196   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5197     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5198    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5199    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5200    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5201        || GET_MODE (operands[3]) == VOIDmode)"
5202   "#"
5203   "&& reload_completed"
5204   [(const_int 0)]
5205 {
5206   rtx pat;
5207   operands[0] = gen_lowpart (SImode, operands[0]);
5208   operands[1] = gen_lowpart (Pmode, operands[1]);
5209   operands[3] = gen_lowpart (Pmode, operands[3]);
5210   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5211                       operands[3]);
5212   if (Pmode != SImode)
5213     pat = gen_rtx_SUBREG (SImode, pat, 0);
5214   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5215   DONE;
5216 }
5217   [(set_attr "type" "lea")
5218    (set_attr "mode" "SI")])
5219
5220 (define_insn_and_split "*lea_general_2_zext"
5221   [(set (match_operand:DI 0 "register_operand" "=r")
5222         (zero_extend:DI
5223           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5224                             (match_operand:SI 2 "const248_operand" "n"))
5225                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5226   "TARGET_64BIT"
5227   "#"
5228   "&& reload_completed"
5229   [(set (match_dup 0)
5230         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5231                                                      (match_dup 2))
5232                                             (match_dup 3)) 0)))]
5233 {
5234   operands[1] = gen_lowpart (Pmode, operands[1]);
5235   operands[3] = gen_lowpart (Pmode, operands[3]);
5236 }
5237   [(set_attr "type" "lea")
5238    (set_attr "mode" "SI")])
5239
5240 (define_insn_and_split "*lea_general_3"
5241   [(set (match_operand 0 "register_operand" "=r")
5242         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5243                           (match_operand 2 "const248_operand" "i"))
5244                     (match_operand 3 "register_operand" "r"))
5245               (match_operand 4 "immediate_operand" "i")))]
5246   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5247     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5248    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5249    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5250    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5251   "#"
5252   "&& reload_completed"
5253   [(const_int 0)]
5254 {
5255   rtx pat;
5256   operands[0] = gen_lowpart (SImode, operands[0]);
5257   operands[1] = gen_lowpart (Pmode, operands[1]);
5258   operands[3] = gen_lowpart (Pmode, operands[3]);
5259   operands[4] = gen_lowpart (Pmode, operands[4]);
5260   pat = gen_rtx_PLUS (Pmode,
5261                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5262                                                          operands[2]),
5263                                     operands[3]),
5264                       operands[4]);
5265   if (Pmode != SImode)
5266     pat = gen_rtx_SUBREG (SImode, pat, 0);
5267   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5268   DONE;
5269 }
5270   [(set_attr "type" "lea")
5271    (set_attr "mode" "SI")])
5272
5273 (define_insn_and_split "*lea_general_3_zext"
5274   [(set (match_operand:DI 0 "register_operand" "=r")
5275         (zero_extend:DI
5276           (plus:SI (plus:SI (mult:SI
5277                               (match_operand:SI 1 "index_register_operand" "l")
5278                               (match_operand:SI 2 "const248_operand" "n"))
5279                             (match_operand:SI 3 "register_operand" "r"))
5280                    (match_operand:SI 4 "immediate_operand" "i"))))]
5281   "TARGET_64BIT"
5282   "#"
5283   "&& reload_completed"
5284   [(set (match_dup 0)
5285         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5286                                                               (match_dup 2))
5287                                                      (match_dup 3))
5288                                             (match_dup 4)) 0)))]
5289 {
5290   operands[1] = gen_lowpart (Pmode, operands[1]);
5291   operands[3] = gen_lowpart (Pmode, operands[3]);
5292   operands[4] = gen_lowpart (Pmode, operands[4]);
5293 }
5294   [(set_attr "type" "lea")
5295    (set_attr "mode" "SI")])
5296
5297 (define_insn "*adddi_1_rex64"
5298   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5299         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5300                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5301    (clobber (reg:CC FLAGS_REG))]
5302   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5303 {
5304   switch (get_attr_type (insn))
5305     {
5306     case TYPE_LEA:
5307       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5308       return "lea{q}\t{%a2, %0|%0, %a2}";
5309
5310     case TYPE_INCDEC:
5311       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5312       if (operands[2] == const1_rtx)
5313         return "inc{q}\t%0";
5314       else
5315         {
5316           gcc_assert (operands[2] == constm1_rtx);
5317           return "dec{q}\t%0";
5318         }
5319
5320     default:
5321       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5322
5323       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5324          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5325       if (CONST_INT_P (operands[2])
5326           /* Avoid overflows.  */
5327           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5328           && (INTVAL (operands[2]) == 128
5329               || (INTVAL (operands[2]) < 0
5330                   && INTVAL (operands[2]) != -128)))
5331         {
5332           operands[2] = GEN_INT (-INTVAL (operands[2]));
5333           return "sub{q}\t{%2, %0|%0, %2}";
5334         }
5335       return "add{q}\t{%2, %0|%0, %2}";
5336     }
5337 }
5338   [(set (attr "type")
5339      (cond [(eq_attr "alternative" "2")
5340               (const_string "lea")
5341             ; Current assemblers are broken and do not allow @GOTOFF in
5342             ; ought but a memory context.
5343             (match_operand:DI 2 "pic_symbolic_operand" "")
5344               (const_string "lea")
5345             (match_operand:DI 2 "incdec_operand" "")
5346               (const_string "incdec")
5347            ]
5348            (const_string "alu")))
5349    (set_attr "mode" "DI")])
5350
5351 ;; Convert lea to the lea pattern to avoid flags dependency.
5352 (define_split
5353   [(set (match_operand:DI 0 "register_operand" "")
5354         (plus:DI (match_operand:DI 1 "register_operand" "")
5355                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5356    (clobber (reg:CC FLAGS_REG))]
5357   "TARGET_64BIT && reload_completed
5358    && true_regnum (operands[0]) != true_regnum (operands[1])"
5359   [(set (match_dup 0)
5360         (plus:DI (match_dup 1)
5361                  (match_dup 2)))]
5362   "")
5363
5364 (define_insn "*adddi_2_rex64"
5365   [(set (reg FLAGS_REG)
5366         (compare
5367           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5368                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5369           (const_int 0)))
5370    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5371         (plus:DI (match_dup 1) (match_dup 2)))]
5372   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5373    && ix86_binary_operator_ok (PLUS, DImode, operands)
5374    /* Current assemblers are broken and do not allow @GOTOFF in
5375       ought but a memory context.  */
5376    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5377 {
5378   switch (get_attr_type (insn))
5379     {
5380     case TYPE_INCDEC:
5381       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5382       if (operands[2] == const1_rtx)
5383         return "inc{q}\t%0";
5384       else
5385         {
5386           gcc_assert (operands[2] == constm1_rtx);
5387           return "dec{q}\t%0";
5388         }
5389
5390     default:
5391       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5392       /* ???? We ought to handle there the 32bit case too
5393          - do we need new constraint?  */
5394       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5395          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5396       if (CONST_INT_P (operands[2])
5397           /* Avoid overflows.  */
5398           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5399           && (INTVAL (operands[2]) == 128
5400               || (INTVAL (operands[2]) < 0
5401                   && INTVAL (operands[2]) != -128)))
5402         {
5403           operands[2] = GEN_INT (-INTVAL (operands[2]));
5404           return "sub{q}\t{%2, %0|%0, %2}";
5405         }
5406       return "add{q}\t{%2, %0|%0, %2}";
5407     }
5408 }
5409   [(set (attr "type")
5410      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5411         (const_string "incdec")
5412         (const_string "alu")))
5413    (set_attr "mode" "DI")])
5414
5415 (define_insn "*adddi_3_rex64"
5416   [(set (reg FLAGS_REG)
5417         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5418                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5419    (clobber (match_scratch:DI 0 "=r"))]
5420   "TARGET_64BIT
5421    && ix86_match_ccmode (insn, CCZmode)
5422    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5423    /* Current assemblers are broken and do not allow @GOTOFF in
5424       ought but a memory context.  */
5425    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5426 {
5427   switch (get_attr_type (insn))
5428     {
5429     case TYPE_INCDEC:
5430       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5431       if (operands[2] == const1_rtx)
5432         return "inc{q}\t%0";
5433       else
5434         {
5435           gcc_assert (operands[2] == constm1_rtx);
5436           return "dec{q}\t%0";
5437         }
5438
5439     default:
5440       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5441       /* ???? We ought to handle there the 32bit case too
5442          - do we need new constraint?  */
5443       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5444          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5445       if (CONST_INT_P (operands[2])
5446           /* Avoid overflows.  */
5447           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5448           && (INTVAL (operands[2]) == 128
5449               || (INTVAL (operands[2]) < 0
5450                   && INTVAL (operands[2]) != -128)))
5451         {
5452           operands[2] = GEN_INT (-INTVAL (operands[2]));
5453           return "sub{q}\t{%2, %0|%0, %2}";
5454         }
5455       return "add{q}\t{%2, %0|%0, %2}";
5456     }
5457 }
5458   [(set (attr "type")
5459      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5460         (const_string "incdec")
5461         (const_string "alu")))
5462    (set_attr "mode" "DI")])
5463
5464 ; For comparisons against 1, -1 and 128, we may generate better code
5465 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5466 ; is matched then.  We can't accept general immediate, because for
5467 ; case of overflows,  the result is messed up.
5468 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5469 ; when negated.
5470 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5471 ; only for comparisons not depending on it.
5472 (define_insn "*adddi_4_rex64"
5473   [(set (reg FLAGS_REG)
5474         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5475                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5476    (clobber (match_scratch:DI 0 "=rm"))]
5477   "TARGET_64BIT
5478    &&  ix86_match_ccmode (insn, CCGCmode)"
5479 {
5480   switch (get_attr_type (insn))
5481     {
5482     case TYPE_INCDEC:
5483       if (operands[2] == constm1_rtx)
5484         return "inc{q}\t%0";
5485       else
5486         {
5487           gcc_assert (operands[2] == const1_rtx);
5488           return "dec{q}\t%0";
5489         }
5490
5491     default:
5492       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5493       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5494          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5495       if ((INTVAL (operands[2]) == -128
5496            || (INTVAL (operands[2]) > 0
5497                && INTVAL (operands[2]) != 128))
5498           /* Avoid overflows.  */
5499           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5500         return "sub{q}\t{%2, %0|%0, %2}";
5501       operands[2] = GEN_INT (-INTVAL (operands[2]));
5502       return "add{q}\t{%2, %0|%0, %2}";
5503     }
5504 }
5505   [(set (attr "type")
5506      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5507         (const_string "incdec")
5508         (const_string "alu")))
5509    (set_attr "mode" "DI")])
5510
5511 (define_insn "*adddi_5_rex64"
5512   [(set (reg FLAGS_REG)
5513         (compare
5514           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5515                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5516           (const_int 0)))
5517    (clobber (match_scratch:DI 0 "=r"))]
5518   "TARGET_64BIT
5519    && ix86_match_ccmode (insn, CCGOCmode)
5520    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5521    /* Current assemblers are broken and do not allow @GOTOFF in
5522       ought but a memory context.  */
5523    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5524 {
5525   switch (get_attr_type (insn))
5526     {
5527     case TYPE_INCDEC:
5528       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5529       if (operands[2] == const1_rtx)
5530         return "inc{q}\t%0";
5531       else
5532         {
5533           gcc_assert (operands[2] == constm1_rtx);
5534           return "dec{q}\t%0";
5535         }
5536
5537     default:
5538       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5539       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5540          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5541       if (CONST_INT_P (operands[2])
5542           /* Avoid overflows.  */
5543           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5544           && (INTVAL (operands[2]) == 128
5545               || (INTVAL (operands[2]) < 0
5546                   && INTVAL (operands[2]) != -128)))
5547         {
5548           operands[2] = GEN_INT (-INTVAL (operands[2]));
5549           return "sub{q}\t{%2, %0|%0, %2}";
5550         }
5551       return "add{q}\t{%2, %0|%0, %2}";
5552     }
5553 }
5554   [(set (attr "type")
5555      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5556         (const_string "incdec")
5557         (const_string "alu")))
5558    (set_attr "mode" "DI")])
5559
5560
5561 (define_insn "*addsi_1"
5562   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5563         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5564                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5565    (clobber (reg:CC FLAGS_REG))]
5566   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5567 {
5568   switch (get_attr_type (insn))
5569     {
5570     case TYPE_LEA:
5571       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5572       return "lea{l}\t{%a2, %0|%0, %a2}";
5573
5574     case TYPE_INCDEC:
5575       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5576       if (operands[2] == const1_rtx)
5577         return "inc{l}\t%0";
5578       else
5579         {
5580           gcc_assert (operands[2] == constm1_rtx);
5581           return "dec{l}\t%0";
5582         }
5583
5584     default:
5585       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5586
5587       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5588          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5589       if (CONST_INT_P (operands[2])
5590           && (INTVAL (operands[2]) == 128
5591               || (INTVAL (operands[2]) < 0
5592                   && INTVAL (operands[2]) != -128)))
5593         {
5594           operands[2] = GEN_INT (-INTVAL (operands[2]));
5595           return "sub{l}\t{%2, %0|%0, %2}";
5596         }
5597       return "add{l}\t{%2, %0|%0, %2}";
5598     }
5599 }
5600   [(set (attr "type")
5601      (cond [(eq_attr "alternative" "2")
5602               (const_string "lea")
5603             ; Current assemblers are broken and do not allow @GOTOFF in
5604             ; ought but a memory context.
5605             (match_operand:SI 2 "pic_symbolic_operand" "")
5606               (const_string "lea")
5607             (match_operand:SI 2 "incdec_operand" "")
5608               (const_string "incdec")
5609            ]
5610            (const_string "alu")))
5611    (set_attr "mode" "SI")])
5612
5613 ;; Convert lea to the lea pattern to avoid flags dependency.
5614 (define_split
5615   [(set (match_operand 0 "register_operand" "")
5616         (plus (match_operand 1 "register_operand" "")
5617               (match_operand 2 "nonmemory_operand" "")))
5618    (clobber (reg:CC FLAGS_REG))]
5619   "reload_completed
5620    && true_regnum (operands[0]) != true_regnum (operands[1])"
5621   [(const_int 0)]
5622 {
5623   rtx pat;
5624   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5625      may confuse gen_lowpart.  */
5626   if (GET_MODE (operands[0]) != Pmode)
5627     {
5628       operands[1] = gen_lowpart (Pmode, operands[1]);
5629       operands[2] = gen_lowpart (Pmode, operands[2]);
5630     }
5631   operands[0] = gen_lowpart (SImode, operands[0]);
5632   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5633   if (Pmode != SImode)
5634     pat = gen_rtx_SUBREG (SImode, pat, 0);
5635   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5636   DONE;
5637 })
5638
5639 ;; It may seem that nonimmediate operand is proper one for operand 1.
5640 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5641 ;; we take care in ix86_binary_operator_ok to not allow two memory
5642 ;; operands so proper swapping will be done in reload.  This allow
5643 ;; patterns constructed from addsi_1 to match.
5644 (define_insn "addsi_1_zext"
5645   [(set (match_operand:DI 0 "register_operand" "=r,r")
5646         (zero_extend:DI
5647           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5648                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5649    (clobber (reg:CC FLAGS_REG))]
5650   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5651 {
5652   switch (get_attr_type (insn))
5653     {
5654     case TYPE_LEA:
5655       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5656       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5657
5658     case TYPE_INCDEC:
5659       if (operands[2] == const1_rtx)
5660         return "inc{l}\t%k0";
5661       else
5662         {
5663           gcc_assert (operands[2] == constm1_rtx);
5664           return "dec{l}\t%k0";
5665         }
5666
5667     default:
5668       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5669          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5670       if (CONST_INT_P (operands[2])
5671           && (INTVAL (operands[2]) == 128
5672               || (INTVAL (operands[2]) < 0
5673                   && INTVAL (operands[2]) != -128)))
5674         {
5675           operands[2] = GEN_INT (-INTVAL (operands[2]));
5676           return "sub{l}\t{%2, %k0|%k0, %2}";
5677         }
5678       return "add{l}\t{%2, %k0|%k0, %2}";
5679     }
5680 }
5681   [(set (attr "type")
5682      (cond [(eq_attr "alternative" "1")
5683               (const_string "lea")
5684             ; Current assemblers are broken and do not allow @GOTOFF in
5685             ; ought but a memory context.
5686             (match_operand:SI 2 "pic_symbolic_operand" "")
5687               (const_string "lea")
5688             (match_operand:SI 2 "incdec_operand" "")
5689               (const_string "incdec")
5690            ]
5691            (const_string "alu")))
5692    (set_attr "mode" "SI")])
5693
5694 ;; Convert lea to the lea pattern to avoid flags dependency.
5695 (define_split
5696   [(set (match_operand:DI 0 "register_operand" "")
5697         (zero_extend:DI
5698           (plus:SI (match_operand:SI 1 "register_operand" "")
5699                    (match_operand:SI 2 "nonmemory_operand" ""))))
5700    (clobber (reg:CC FLAGS_REG))]
5701   "TARGET_64BIT && reload_completed
5702    && true_regnum (operands[0]) != true_regnum (operands[1])"
5703   [(set (match_dup 0)
5704         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5705 {
5706   operands[1] = gen_lowpart (Pmode, operands[1]);
5707   operands[2] = gen_lowpart (Pmode, operands[2]);
5708 })
5709
5710 (define_insn "*addsi_2"
5711   [(set (reg FLAGS_REG)
5712         (compare
5713           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5714                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5715           (const_int 0)))
5716    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5717         (plus:SI (match_dup 1) (match_dup 2)))]
5718   "ix86_match_ccmode (insn, CCGOCmode)
5719    && ix86_binary_operator_ok (PLUS, SImode, operands)
5720    /* Current assemblers are broken and do not allow @GOTOFF in
5721       ought but a memory context.  */
5722    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5723 {
5724   switch (get_attr_type (insn))
5725     {
5726     case TYPE_INCDEC:
5727       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5728       if (operands[2] == const1_rtx)
5729         return "inc{l}\t%0";
5730       else
5731         {
5732           gcc_assert (operands[2] == constm1_rtx);
5733           return "dec{l}\t%0";
5734         }
5735
5736     default:
5737       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5738       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5739          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5740       if (CONST_INT_P (operands[2])
5741           && (INTVAL (operands[2]) == 128
5742               || (INTVAL (operands[2]) < 0
5743                   && INTVAL (operands[2]) != -128)))
5744         {
5745           operands[2] = GEN_INT (-INTVAL (operands[2]));
5746           return "sub{l}\t{%2, %0|%0, %2}";
5747         }
5748       return "add{l}\t{%2, %0|%0, %2}";
5749     }
5750 }
5751   [(set (attr "type")
5752      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5753         (const_string "incdec")
5754         (const_string "alu")))
5755    (set_attr "mode" "SI")])
5756
5757 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5758 (define_insn "*addsi_2_zext"
5759   [(set (reg FLAGS_REG)
5760         (compare
5761           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5762                    (match_operand:SI 2 "general_operand" "rmni"))
5763           (const_int 0)))
5764    (set (match_operand:DI 0 "register_operand" "=r")
5765         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5766   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5767    && ix86_binary_operator_ok (PLUS, SImode, operands)
5768    /* Current assemblers are broken and do not allow @GOTOFF in
5769       ought but a memory context.  */
5770    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5771 {
5772   switch (get_attr_type (insn))
5773     {
5774     case TYPE_INCDEC:
5775       if (operands[2] == const1_rtx)
5776         return "inc{l}\t%k0";
5777       else
5778         {
5779           gcc_assert (operands[2] == constm1_rtx);
5780           return "dec{l}\t%k0";
5781         }
5782
5783     default:
5784       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5785          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5786       if (CONST_INT_P (operands[2])
5787           && (INTVAL (operands[2]) == 128
5788               || (INTVAL (operands[2]) < 0
5789                   && INTVAL (operands[2]) != -128)))
5790         {
5791           operands[2] = GEN_INT (-INTVAL (operands[2]));
5792           return "sub{l}\t{%2, %k0|%k0, %2}";
5793         }
5794       return "add{l}\t{%2, %k0|%k0, %2}";
5795     }
5796 }
5797   [(set (attr "type")
5798      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5799         (const_string "incdec")
5800         (const_string "alu")))
5801    (set_attr "mode" "SI")])
5802
5803 (define_insn "*addsi_3"
5804   [(set (reg FLAGS_REG)
5805         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5806                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5807    (clobber (match_scratch:SI 0 "=r"))]
5808   "ix86_match_ccmode (insn, CCZmode)
5809    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5810    /* Current assemblers are broken and do not allow @GOTOFF in
5811       ought but a memory context.  */
5812    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5813 {
5814   switch (get_attr_type (insn))
5815     {
5816     case TYPE_INCDEC:
5817       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5818       if (operands[2] == const1_rtx)
5819         return "inc{l}\t%0";
5820       else
5821         {
5822           gcc_assert (operands[2] == constm1_rtx);
5823           return "dec{l}\t%0";
5824         }
5825
5826     default:
5827       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5828       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5829          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5830       if (CONST_INT_P (operands[2])
5831           && (INTVAL (operands[2]) == 128
5832               || (INTVAL (operands[2]) < 0
5833                   && INTVAL (operands[2]) != -128)))
5834         {
5835           operands[2] = GEN_INT (-INTVAL (operands[2]));
5836           return "sub{l}\t{%2, %0|%0, %2}";
5837         }
5838       return "add{l}\t{%2, %0|%0, %2}";
5839     }
5840 }
5841   [(set (attr "type")
5842      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5843         (const_string "incdec")
5844         (const_string "alu")))
5845    (set_attr "mode" "SI")])
5846
5847 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5848 (define_insn "*addsi_3_zext"
5849   [(set (reg FLAGS_REG)
5850         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5851                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5852    (set (match_operand:DI 0 "register_operand" "=r")
5853         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5854   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5855    && ix86_binary_operator_ok (PLUS, SImode, operands)
5856    /* Current assemblers are broken and do not allow @GOTOFF in
5857       ought but a memory context.  */
5858    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5859 {
5860   switch (get_attr_type (insn))
5861     {
5862     case TYPE_INCDEC:
5863       if (operands[2] == const1_rtx)
5864         return "inc{l}\t%k0";
5865       else
5866         {
5867           gcc_assert (operands[2] == constm1_rtx);
5868           return "dec{l}\t%k0";
5869         }
5870
5871     default:
5872       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5873          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5874       if (CONST_INT_P (operands[2])
5875           && (INTVAL (operands[2]) == 128
5876               || (INTVAL (operands[2]) < 0
5877                   && INTVAL (operands[2]) != -128)))
5878         {
5879           operands[2] = GEN_INT (-INTVAL (operands[2]));
5880           return "sub{l}\t{%2, %k0|%k0, %2}";
5881         }
5882       return "add{l}\t{%2, %k0|%k0, %2}";
5883     }
5884 }
5885   [(set (attr "type")
5886      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5887         (const_string "incdec")
5888         (const_string "alu")))
5889    (set_attr "mode" "SI")])
5890
5891 ; For comparisons against 1, -1 and 128, we may generate better code
5892 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5893 ; is matched then.  We can't accept general immediate, because for
5894 ; case of overflows,  the result is messed up.
5895 ; This pattern also don't hold of 0x80000000, since the value overflows
5896 ; when negated.
5897 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5898 ; only for comparisons not depending on it.
5899 (define_insn "*addsi_4"
5900   [(set (reg FLAGS_REG)
5901         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5902                  (match_operand:SI 2 "const_int_operand" "n")))
5903    (clobber (match_scratch:SI 0 "=rm"))]
5904   "ix86_match_ccmode (insn, CCGCmode)
5905    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5906 {
5907   switch (get_attr_type (insn))
5908     {
5909     case TYPE_INCDEC:
5910       if (operands[2] == constm1_rtx)
5911         return "inc{l}\t%0";
5912       else
5913         {
5914           gcc_assert (operands[2] == const1_rtx);
5915           return "dec{l}\t%0";
5916         }
5917
5918     default:
5919       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5920       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5921          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5922       if ((INTVAL (operands[2]) == -128
5923            || (INTVAL (operands[2]) > 0
5924                && INTVAL (operands[2]) != 128)))
5925         return "sub{l}\t{%2, %0|%0, %2}";
5926       operands[2] = GEN_INT (-INTVAL (operands[2]));
5927       return "add{l}\t{%2, %0|%0, %2}";
5928     }
5929 }
5930   [(set (attr "type")
5931      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5932         (const_string "incdec")
5933         (const_string "alu")))
5934    (set_attr "mode" "SI")])
5935
5936 (define_insn "*addsi_5"
5937   [(set (reg FLAGS_REG)
5938         (compare
5939           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5940                    (match_operand:SI 2 "general_operand" "rmni"))
5941           (const_int 0)))
5942    (clobber (match_scratch:SI 0 "=r"))]
5943   "ix86_match_ccmode (insn, CCGOCmode)
5944    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5945    /* Current assemblers are broken and do not allow @GOTOFF in
5946       ought but a memory context.  */
5947    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5948 {
5949   switch (get_attr_type (insn))
5950     {
5951     case TYPE_INCDEC:
5952       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5953       if (operands[2] == const1_rtx)
5954         return "inc{l}\t%0";
5955       else
5956         {
5957           gcc_assert (operands[2] == constm1_rtx);
5958           return "dec{l}\t%0";
5959         }
5960
5961     default:
5962       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5963       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5964          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5965       if (CONST_INT_P (operands[2])
5966           && (INTVAL (operands[2]) == 128
5967               || (INTVAL (operands[2]) < 0
5968                   && INTVAL (operands[2]) != -128)))
5969         {
5970           operands[2] = GEN_INT (-INTVAL (operands[2]));
5971           return "sub{l}\t{%2, %0|%0, %2}";
5972         }
5973       return "add{l}\t{%2, %0|%0, %2}";
5974     }
5975 }
5976   [(set (attr "type")
5977      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5978         (const_string "incdec")
5979         (const_string "alu")))
5980    (set_attr "mode" "SI")])
5981
5982 (define_expand "addhi3"
5983   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5984                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5985                             (match_operand:HI 2 "general_operand" "")))
5986               (clobber (reg:CC FLAGS_REG))])]
5987   "TARGET_HIMODE_MATH"
5988   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5989
5990 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5991 ;; type optimizations enabled by define-splits.  This is not important
5992 ;; for PII, and in fact harmful because of partial register stalls.
5993
5994 (define_insn "*addhi_1_lea"
5995   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5996         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5997                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5998    (clobber (reg:CC FLAGS_REG))]
5999   "!TARGET_PARTIAL_REG_STALL
6000    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6001 {
6002   switch (get_attr_type (insn))
6003     {
6004     case TYPE_LEA:
6005       return "#";
6006     case TYPE_INCDEC:
6007       if (operands[2] == const1_rtx)
6008         return "inc{w}\t%0";
6009       else
6010         {
6011           gcc_assert (operands[2] == constm1_rtx);
6012           return "dec{w}\t%0";
6013         }
6014
6015     default:
6016       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6017          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6018       if (CONST_INT_P (operands[2])
6019           && (INTVAL (operands[2]) == 128
6020               || (INTVAL (operands[2]) < 0
6021                   && INTVAL (operands[2]) != -128)))
6022         {
6023           operands[2] = GEN_INT (-INTVAL (operands[2]));
6024           return "sub{w}\t{%2, %0|%0, %2}";
6025         }
6026       return "add{w}\t{%2, %0|%0, %2}";
6027     }
6028 }
6029   [(set (attr "type")
6030      (if_then_else (eq_attr "alternative" "2")
6031         (const_string "lea")
6032         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6033            (const_string "incdec")
6034            (const_string "alu"))))
6035    (set_attr "mode" "HI,HI,SI")])
6036
6037 (define_insn "*addhi_1"
6038   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6039         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6040                  (match_operand:HI 2 "general_operand" "ri,rm")))
6041    (clobber (reg:CC FLAGS_REG))]
6042   "TARGET_PARTIAL_REG_STALL
6043    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6044 {
6045   switch (get_attr_type (insn))
6046     {
6047     case TYPE_INCDEC:
6048       if (operands[2] == const1_rtx)
6049         return "inc{w}\t%0";
6050       else
6051         {
6052           gcc_assert (operands[2] == constm1_rtx);
6053           return "dec{w}\t%0";
6054         }
6055
6056     default:
6057       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6058          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6059       if (CONST_INT_P (operands[2])
6060           && (INTVAL (operands[2]) == 128
6061               || (INTVAL (operands[2]) < 0
6062                   && INTVAL (operands[2]) != -128)))
6063         {
6064           operands[2] = GEN_INT (-INTVAL (operands[2]));
6065           return "sub{w}\t{%2, %0|%0, %2}";
6066         }
6067       return "add{w}\t{%2, %0|%0, %2}";
6068     }
6069 }
6070   [(set (attr "type")
6071      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6072         (const_string "incdec")
6073         (const_string "alu")))
6074    (set_attr "mode" "HI")])
6075
6076 (define_insn "*addhi_2"
6077   [(set (reg FLAGS_REG)
6078         (compare
6079           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6080                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6081           (const_int 0)))
6082    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6083         (plus:HI (match_dup 1) (match_dup 2)))]
6084   "ix86_match_ccmode (insn, CCGOCmode)
6085    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6086 {
6087   switch (get_attr_type (insn))
6088     {
6089     case TYPE_INCDEC:
6090       if (operands[2] == const1_rtx)
6091         return "inc{w}\t%0";
6092       else
6093         {
6094           gcc_assert (operands[2] == constm1_rtx);
6095           return "dec{w}\t%0";
6096         }
6097
6098     default:
6099       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6100          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6101       if (CONST_INT_P (operands[2])
6102           && (INTVAL (operands[2]) == 128
6103               || (INTVAL (operands[2]) < 0
6104                   && INTVAL (operands[2]) != -128)))
6105         {
6106           operands[2] = GEN_INT (-INTVAL (operands[2]));
6107           return "sub{w}\t{%2, %0|%0, %2}";
6108         }
6109       return "add{w}\t{%2, %0|%0, %2}";
6110     }
6111 }
6112   [(set (attr "type")
6113      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6114         (const_string "incdec")
6115         (const_string "alu")))
6116    (set_attr "mode" "HI")])
6117
6118 (define_insn "*addhi_3"
6119   [(set (reg FLAGS_REG)
6120         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6121                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6122    (clobber (match_scratch:HI 0 "=r"))]
6123   "ix86_match_ccmode (insn, CCZmode)
6124    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6125 {
6126   switch (get_attr_type (insn))
6127     {
6128     case TYPE_INCDEC:
6129       if (operands[2] == const1_rtx)
6130         return "inc{w}\t%0";
6131       else
6132         {
6133           gcc_assert (operands[2] == constm1_rtx);
6134           return "dec{w}\t%0";
6135         }
6136
6137     default:
6138       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6139          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6140       if (CONST_INT_P (operands[2])
6141           && (INTVAL (operands[2]) == 128
6142               || (INTVAL (operands[2]) < 0
6143                   && INTVAL (operands[2]) != -128)))
6144         {
6145           operands[2] = GEN_INT (-INTVAL (operands[2]));
6146           return "sub{w}\t{%2, %0|%0, %2}";
6147         }
6148       return "add{w}\t{%2, %0|%0, %2}";
6149     }
6150 }
6151   [(set (attr "type")
6152      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6153         (const_string "incdec")
6154         (const_string "alu")))
6155    (set_attr "mode" "HI")])
6156
6157 ; See comments above addsi_4 for details.
6158 (define_insn "*addhi_4"
6159   [(set (reg FLAGS_REG)
6160         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6161                  (match_operand:HI 2 "const_int_operand" "n")))
6162    (clobber (match_scratch:HI 0 "=rm"))]
6163   "ix86_match_ccmode (insn, CCGCmode)
6164    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6165 {
6166   switch (get_attr_type (insn))
6167     {
6168     case TYPE_INCDEC:
6169       if (operands[2] == constm1_rtx)
6170         return "inc{w}\t%0";
6171       else
6172         {
6173           gcc_assert (operands[2] == const1_rtx);
6174           return "dec{w}\t%0";
6175         }
6176
6177     default:
6178       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6179       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6180          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6181       if ((INTVAL (operands[2]) == -128
6182            || (INTVAL (operands[2]) > 0
6183                && INTVAL (operands[2]) != 128)))
6184         return "sub{w}\t{%2, %0|%0, %2}";
6185       operands[2] = GEN_INT (-INTVAL (operands[2]));
6186       return "add{w}\t{%2, %0|%0, %2}";
6187     }
6188 }
6189   [(set (attr "type")
6190      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6191         (const_string "incdec")
6192         (const_string "alu")))
6193    (set_attr "mode" "SI")])
6194
6195
6196 (define_insn "*addhi_5"
6197   [(set (reg FLAGS_REG)
6198         (compare
6199           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6200                    (match_operand:HI 2 "general_operand" "rmni"))
6201           (const_int 0)))
6202    (clobber (match_scratch:HI 0 "=r"))]
6203   "ix86_match_ccmode (insn, CCGOCmode)
6204    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6205 {
6206   switch (get_attr_type (insn))
6207     {
6208     case TYPE_INCDEC:
6209       if (operands[2] == const1_rtx)
6210         return "inc{w}\t%0";
6211       else
6212         {
6213           gcc_assert (operands[2] == constm1_rtx);
6214           return "dec{w}\t%0";
6215         }
6216
6217     default:
6218       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6219          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6220       if (CONST_INT_P (operands[2])
6221           && (INTVAL (operands[2]) == 128
6222               || (INTVAL (operands[2]) < 0
6223                   && INTVAL (operands[2]) != -128)))
6224         {
6225           operands[2] = GEN_INT (-INTVAL (operands[2]));
6226           return "sub{w}\t{%2, %0|%0, %2}";
6227         }
6228       return "add{w}\t{%2, %0|%0, %2}";
6229     }
6230 }
6231   [(set (attr "type")
6232      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6233         (const_string "incdec")
6234         (const_string "alu")))
6235    (set_attr "mode" "HI")])
6236
6237 (define_expand "addqi3"
6238   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6239                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6240                             (match_operand:QI 2 "general_operand" "")))
6241               (clobber (reg:CC FLAGS_REG))])]
6242   "TARGET_QIMODE_MATH"
6243   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6244
6245 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6246 (define_insn "*addqi_1_lea"
6247   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6248         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6249                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6250    (clobber (reg:CC FLAGS_REG))]
6251   "!TARGET_PARTIAL_REG_STALL
6252    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6253 {
6254   int widen = (which_alternative == 2);
6255   switch (get_attr_type (insn))
6256     {
6257     case TYPE_LEA:
6258       return "#";
6259     case TYPE_INCDEC:
6260       if (operands[2] == const1_rtx)
6261         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6262       else
6263         {
6264           gcc_assert (operands[2] == constm1_rtx);
6265           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6266         }
6267
6268     default:
6269       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6270          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6271       if (CONST_INT_P (operands[2])
6272           && (INTVAL (operands[2]) == 128
6273               || (INTVAL (operands[2]) < 0
6274                   && INTVAL (operands[2]) != -128)))
6275         {
6276           operands[2] = GEN_INT (-INTVAL (operands[2]));
6277           if (widen)
6278             return "sub{l}\t{%2, %k0|%k0, %2}";
6279           else
6280             return "sub{b}\t{%2, %0|%0, %2}";
6281         }
6282       if (widen)
6283         return "add{l}\t{%k2, %k0|%k0, %k2}";
6284       else
6285         return "add{b}\t{%2, %0|%0, %2}";
6286     }
6287 }
6288   [(set (attr "type")
6289      (if_then_else (eq_attr "alternative" "3")
6290         (const_string "lea")
6291         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6292            (const_string "incdec")
6293            (const_string "alu"))))
6294    (set_attr "mode" "QI,QI,SI,SI")])
6295
6296 (define_insn "*addqi_1"
6297   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6298         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6299                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6300    (clobber (reg:CC FLAGS_REG))]
6301   "TARGET_PARTIAL_REG_STALL
6302    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6303 {
6304   int widen = (which_alternative == 2);
6305   switch (get_attr_type (insn))
6306     {
6307     case TYPE_INCDEC:
6308       if (operands[2] == const1_rtx)
6309         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6310       else
6311         {
6312           gcc_assert (operands[2] == constm1_rtx);
6313           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6314         }
6315
6316     default:
6317       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6318          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6319       if (CONST_INT_P (operands[2])
6320           && (INTVAL (operands[2]) == 128
6321               || (INTVAL (operands[2]) < 0
6322                   && INTVAL (operands[2]) != -128)))
6323         {
6324           operands[2] = GEN_INT (-INTVAL (operands[2]));
6325           if (widen)
6326             return "sub{l}\t{%2, %k0|%k0, %2}";
6327           else
6328             return "sub{b}\t{%2, %0|%0, %2}";
6329         }
6330       if (widen)
6331         return "add{l}\t{%k2, %k0|%k0, %k2}";
6332       else
6333         return "add{b}\t{%2, %0|%0, %2}";
6334     }
6335 }
6336   [(set (attr "type")
6337      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6338         (const_string "incdec")
6339         (const_string "alu")))
6340    (set_attr "mode" "QI,QI,SI")])
6341
6342 (define_insn "*addqi_1_slp"
6343   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6344         (plus:QI (match_dup 0)
6345                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6346    (clobber (reg:CC FLAGS_REG))]
6347   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6348    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6349 {
6350   switch (get_attr_type (insn))
6351     {
6352     case TYPE_INCDEC:
6353       if (operands[1] == const1_rtx)
6354         return "inc{b}\t%0";
6355       else
6356         {
6357           gcc_assert (operands[1] == constm1_rtx);
6358           return "dec{b}\t%0";
6359         }
6360
6361     default:
6362       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6363       if (CONST_INT_P (operands[1])
6364           && INTVAL (operands[1]) < 0)
6365         {
6366           operands[1] = GEN_INT (-INTVAL (operands[1]));
6367           return "sub{b}\t{%1, %0|%0, %1}";
6368         }
6369       return "add{b}\t{%1, %0|%0, %1}";
6370     }
6371 }
6372   [(set (attr "type")
6373      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6374         (const_string "incdec")
6375         (const_string "alu1")))
6376    (set (attr "memory")
6377      (if_then_else (match_operand 1 "memory_operand" "")
6378         (const_string "load")
6379         (const_string "none")))
6380    (set_attr "mode" "QI")])
6381
6382 (define_insn "*addqi_2"
6383   [(set (reg FLAGS_REG)
6384         (compare
6385           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6386                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6387           (const_int 0)))
6388    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6389         (plus:QI (match_dup 1) (match_dup 2)))]
6390   "ix86_match_ccmode (insn, CCGOCmode)
6391    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6392 {
6393   switch (get_attr_type (insn))
6394     {
6395     case TYPE_INCDEC:
6396       if (operands[2] == const1_rtx)
6397         return "inc{b}\t%0";
6398       else
6399         {
6400           gcc_assert (operands[2] == constm1_rtx
6401                       || (CONST_INT_P (operands[2])
6402                           && INTVAL (operands[2]) == 255));
6403           return "dec{b}\t%0";
6404         }
6405
6406     default:
6407       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6408       if (CONST_INT_P (operands[2])
6409           && INTVAL (operands[2]) < 0)
6410         {
6411           operands[2] = GEN_INT (-INTVAL (operands[2]));
6412           return "sub{b}\t{%2, %0|%0, %2}";
6413         }
6414       return "add{b}\t{%2, %0|%0, %2}";
6415     }
6416 }
6417   [(set (attr "type")
6418      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6419         (const_string "incdec")
6420         (const_string "alu")))
6421    (set_attr "mode" "QI")])
6422
6423 (define_insn "*addqi_3"
6424   [(set (reg FLAGS_REG)
6425         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6426                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6427    (clobber (match_scratch:QI 0 "=q"))]
6428   "ix86_match_ccmode (insn, CCZmode)
6429    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6430 {
6431   switch (get_attr_type (insn))
6432     {
6433     case TYPE_INCDEC:
6434       if (operands[2] == const1_rtx)
6435         return "inc{b}\t%0";
6436       else
6437         {
6438           gcc_assert (operands[2] == constm1_rtx
6439                       || (CONST_INT_P (operands[2])
6440                           && INTVAL (operands[2]) == 255));
6441           return "dec{b}\t%0";
6442         }
6443
6444     default:
6445       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6446       if (CONST_INT_P (operands[2])
6447           && INTVAL (operands[2]) < 0)
6448         {
6449           operands[2] = GEN_INT (-INTVAL (operands[2]));
6450           return "sub{b}\t{%2, %0|%0, %2}";
6451         }
6452       return "add{b}\t{%2, %0|%0, %2}";
6453     }
6454 }
6455   [(set (attr "type")
6456      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6457         (const_string "incdec")
6458         (const_string "alu")))
6459    (set_attr "mode" "QI")])
6460
6461 ; See comments above addsi_4 for details.
6462 (define_insn "*addqi_4"
6463   [(set (reg FLAGS_REG)
6464         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6465                  (match_operand:QI 2 "const_int_operand" "n")))
6466    (clobber (match_scratch:QI 0 "=qm"))]
6467   "ix86_match_ccmode (insn, CCGCmode)
6468    && (INTVAL (operands[2]) & 0xff) != 0x80"
6469 {
6470   switch (get_attr_type (insn))
6471     {
6472     case TYPE_INCDEC:
6473       if (operands[2] == constm1_rtx
6474           || (CONST_INT_P (operands[2])
6475               && INTVAL (operands[2]) == 255))
6476         return "inc{b}\t%0";
6477       else
6478         {
6479           gcc_assert (operands[2] == const1_rtx);
6480           return "dec{b}\t%0";
6481         }
6482
6483     default:
6484       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6485       if (INTVAL (operands[2]) < 0)
6486         {
6487           operands[2] = GEN_INT (-INTVAL (operands[2]));
6488           return "add{b}\t{%2, %0|%0, %2}";
6489         }
6490       return "sub{b}\t{%2, %0|%0, %2}";
6491     }
6492 }
6493   [(set (attr "type")
6494      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6495         (const_string "incdec")
6496         (const_string "alu")))
6497    (set_attr "mode" "QI")])
6498
6499
6500 (define_insn "*addqi_5"
6501   [(set (reg FLAGS_REG)
6502         (compare
6503           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6504                    (match_operand:QI 2 "general_operand" "qmni"))
6505           (const_int 0)))
6506    (clobber (match_scratch:QI 0 "=q"))]
6507   "ix86_match_ccmode (insn, CCGOCmode)
6508    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6509 {
6510   switch (get_attr_type (insn))
6511     {
6512     case TYPE_INCDEC:
6513       if (operands[2] == const1_rtx)
6514         return "inc{b}\t%0";
6515       else
6516         {
6517           gcc_assert (operands[2] == constm1_rtx
6518                       || (CONST_INT_P (operands[2])
6519                           && INTVAL (operands[2]) == 255));
6520           return "dec{b}\t%0";
6521         }
6522
6523     default:
6524       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6525       if (CONST_INT_P (operands[2])
6526           && INTVAL (operands[2]) < 0)
6527         {
6528           operands[2] = GEN_INT (-INTVAL (operands[2]));
6529           return "sub{b}\t{%2, %0|%0, %2}";
6530         }
6531       return "add{b}\t{%2, %0|%0, %2}";
6532     }
6533 }
6534   [(set (attr "type")
6535      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6536         (const_string "incdec")
6537         (const_string "alu")))
6538    (set_attr "mode" "QI")])
6539
6540
6541 (define_insn "addqi_ext_1"
6542   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6543                          (const_int 8)
6544                          (const_int 8))
6545         (plus:SI
6546           (zero_extract:SI
6547             (match_operand 1 "ext_register_operand" "0")
6548             (const_int 8)
6549             (const_int 8))
6550           (match_operand:QI 2 "general_operand" "Qmn")))
6551    (clobber (reg:CC FLAGS_REG))]
6552   "!TARGET_64BIT"
6553 {
6554   switch (get_attr_type (insn))
6555     {
6556     case TYPE_INCDEC:
6557       if (operands[2] == const1_rtx)
6558         return "inc{b}\t%h0";
6559       else
6560         {
6561           gcc_assert (operands[2] == constm1_rtx
6562                       || (CONST_INT_P (operands[2])
6563                           && INTVAL (operands[2]) == 255));
6564           return "dec{b}\t%h0";
6565         }
6566
6567     default:
6568       return "add{b}\t{%2, %h0|%h0, %2}";
6569     }
6570 }
6571   [(set (attr "type")
6572      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6573         (const_string "incdec")
6574         (const_string "alu")))
6575    (set_attr "mode" "QI")])
6576
6577 (define_insn "*addqi_ext_1_rex64"
6578   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6579                          (const_int 8)
6580                          (const_int 8))
6581         (plus:SI
6582           (zero_extract:SI
6583             (match_operand 1 "ext_register_operand" "0")
6584             (const_int 8)
6585             (const_int 8))
6586           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6587    (clobber (reg:CC FLAGS_REG))]
6588   "TARGET_64BIT"
6589 {
6590   switch (get_attr_type (insn))
6591     {
6592     case TYPE_INCDEC:
6593       if (operands[2] == const1_rtx)
6594         return "inc{b}\t%h0";
6595       else
6596         {
6597           gcc_assert (operands[2] == constm1_rtx
6598                       || (CONST_INT_P (operands[2])
6599                           && INTVAL (operands[2]) == 255));
6600           return "dec{b}\t%h0";
6601         }
6602
6603     default:
6604       return "add{b}\t{%2, %h0|%h0, %2}";
6605     }
6606 }
6607   [(set (attr "type")
6608      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6609         (const_string "incdec")
6610         (const_string "alu")))
6611    (set_attr "mode" "QI")])
6612
6613 (define_insn "*addqi_ext_2"
6614   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6615                          (const_int 8)
6616                          (const_int 8))
6617         (plus:SI
6618           (zero_extract:SI
6619             (match_operand 1 "ext_register_operand" "%0")
6620             (const_int 8)
6621             (const_int 8))
6622           (zero_extract:SI
6623             (match_operand 2 "ext_register_operand" "Q")
6624             (const_int 8)
6625             (const_int 8))))
6626    (clobber (reg:CC FLAGS_REG))]
6627   ""
6628   "add{b}\t{%h2, %h0|%h0, %h2}"
6629   [(set_attr "type" "alu")
6630    (set_attr "mode" "QI")])
6631
6632 ;; The patterns that match these are at the end of this file.
6633
6634 (define_expand "addxf3"
6635   [(set (match_operand:XF 0 "register_operand" "")
6636         (plus:XF (match_operand:XF 1 "register_operand" "")
6637                  (match_operand:XF 2 "register_operand" "")))]
6638   "TARGET_80387"
6639   "")
6640
6641 (define_expand "adddf3"
6642   [(set (match_operand:DF 0 "register_operand" "")
6643         (plus:DF (match_operand:DF 1 "register_operand" "")
6644                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6645   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6646   "")
6647
6648 (define_expand "addsf3"
6649   [(set (match_operand:SF 0 "register_operand" "")
6650         (plus:SF (match_operand:SF 1 "register_operand" "")
6651                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6652   "TARGET_80387 || TARGET_SSE_MATH"
6653   "")
6654 \f
6655 ;; Subtract instructions
6656
6657 ;; %%% splits for subditi3
6658
6659 (define_expand "subti3"
6660   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6661                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6662                              (match_operand:TI 2 "x86_64_general_operand" "")))
6663               (clobber (reg:CC FLAGS_REG))])]
6664   "TARGET_64BIT"
6665   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6666
6667 (define_insn "*subti3_1"
6668   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6669         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6670                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
6671    (clobber (reg:CC FLAGS_REG))]
6672   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6673   "#")
6674
6675 (define_split
6676   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6677         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6678                   (match_operand:TI 2 "x86_64_general_operand" "")))
6679    (clobber (reg:CC FLAGS_REG))]
6680   "TARGET_64BIT && reload_completed"
6681   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6682               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6683    (parallel [(set (match_dup 3)
6684                    (minus:DI (match_dup 4)
6685                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6686                                       (match_dup 5))))
6687               (clobber (reg:CC FLAGS_REG))])]
6688   "split_ti (operands+0, 1, operands+0, operands+3);
6689    split_ti (operands+1, 1, operands+1, operands+4);
6690    split_ti (operands+2, 1, operands+2, operands+5);")
6691
6692 ;; %%% splits for subsidi3
6693
6694 (define_expand "subdi3"
6695   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6696                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6697                              (match_operand:DI 2 "x86_64_general_operand" "")))
6698               (clobber (reg:CC FLAGS_REG))])]
6699   ""
6700   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6701
6702 (define_insn "*subdi3_1"
6703   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6704         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6705                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6706    (clobber (reg:CC FLAGS_REG))]
6707   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6708   "#")
6709
6710 (define_split
6711   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6712         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6713                   (match_operand:DI 2 "general_operand" "")))
6714    (clobber (reg:CC FLAGS_REG))]
6715   "!TARGET_64BIT && reload_completed"
6716   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6717               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6718    (parallel [(set (match_dup 3)
6719                    (minus:SI (match_dup 4)
6720                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6721                                       (match_dup 5))))
6722               (clobber (reg:CC FLAGS_REG))])]
6723   "split_di (operands+0, 1, operands+0, operands+3);
6724    split_di (operands+1, 1, operands+1, operands+4);
6725    split_di (operands+2, 1, operands+2, operands+5);")
6726
6727 (define_insn "subdi3_carry_rex64"
6728   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6729           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6730             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6731                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6732    (clobber (reg:CC FLAGS_REG))]
6733   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6734   "sbb{q}\t{%2, %0|%0, %2}"
6735   [(set_attr "type" "alu")
6736    (set_attr "pent_pair" "pu")
6737    (set_attr "mode" "DI")])
6738
6739 (define_insn "*subdi_1_rex64"
6740   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6741         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6742                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6743    (clobber (reg:CC FLAGS_REG))]
6744   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6745   "sub{q}\t{%2, %0|%0, %2}"
6746   [(set_attr "type" "alu")
6747    (set_attr "mode" "DI")])
6748
6749 (define_insn "*subdi_2_rex64"
6750   [(set (reg FLAGS_REG)
6751         (compare
6752           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6753                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6754           (const_int 0)))
6755    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6756         (minus:DI (match_dup 1) (match_dup 2)))]
6757   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6758    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6759   "sub{q}\t{%2, %0|%0, %2}"
6760   [(set_attr "type" "alu")
6761    (set_attr "mode" "DI")])
6762
6763 (define_insn "*subdi_3_rex63"
6764   [(set (reg FLAGS_REG)
6765         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6766                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6767    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6768         (minus:DI (match_dup 1) (match_dup 2)))]
6769   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6770    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6771   "sub{q}\t{%2, %0|%0, %2}"
6772   [(set_attr "type" "alu")
6773    (set_attr "mode" "DI")])
6774
6775 (define_insn "subqi3_carry"
6776   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6777           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6778             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6779                (match_operand:QI 2 "general_operand" "qi,qm"))))
6780    (clobber (reg:CC FLAGS_REG))]
6781   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6782   "sbb{b}\t{%2, %0|%0, %2}"
6783   [(set_attr "type" "alu")
6784    (set_attr "pent_pair" "pu")
6785    (set_attr "mode" "QI")])
6786
6787 (define_insn "subhi3_carry"
6788   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6789           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6790             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6791                (match_operand:HI 2 "general_operand" "ri,rm"))))
6792    (clobber (reg:CC FLAGS_REG))]
6793   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6794   "sbb{w}\t{%2, %0|%0, %2}"
6795   [(set_attr "type" "alu")
6796    (set_attr "pent_pair" "pu")
6797    (set_attr "mode" "HI")])
6798
6799 (define_insn "subsi3_carry"
6800   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6801           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6802             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6803                (match_operand:SI 2 "general_operand" "ri,rm"))))
6804    (clobber (reg:CC FLAGS_REG))]
6805   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6806   "sbb{l}\t{%2, %0|%0, %2}"
6807   [(set_attr "type" "alu")
6808    (set_attr "pent_pair" "pu")
6809    (set_attr "mode" "SI")])
6810
6811 (define_insn "subsi3_carry_zext"
6812   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6813           (zero_extend:DI
6814             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6815               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6816                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6817    (clobber (reg:CC FLAGS_REG))]
6818   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6819   "sbb{l}\t{%2, %k0|%k0, %2}"
6820   [(set_attr "type" "alu")
6821    (set_attr "pent_pair" "pu")
6822    (set_attr "mode" "SI")])
6823
6824 (define_expand "subsi3"
6825   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6826                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6827                              (match_operand:SI 2 "general_operand" "")))
6828               (clobber (reg:CC FLAGS_REG))])]
6829   ""
6830   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6831
6832 (define_insn "*subsi_1"
6833   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6834         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6835                   (match_operand:SI 2 "general_operand" "ri,rm")))
6836    (clobber (reg:CC FLAGS_REG))]
6837   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6838   "sub{l}\t{%2, %0|%0, %2}"
6839   [(set_attr "type" "alu")
6840    (set_attr "mode" "SI")])
6841
6842 (define_insn "*subsi_1_zext"
6843   [(set (match_operand:DI 0 "register_operand" "=r")
6844         (zero_extend:DI
6845           (minus:SI (match_operand:SI 1 "register_operand" "0")
6846                     (match_operand:SI 2 "general_operand" "rim"))))
6847    (clobber (reg:CC FLAGS_REG))]
6848   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6849   "sub{l}\t{%2, %k0|%k0, %2}"
6850   [(set_attr "type" "alu")
6851    (set_attr "mode" "SI")])
6852
6853 (define_insn "*subsi_2"
6854   [(set (reg FLAGS_REG)
6855         (compare
6856           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6857                     (match_operand:SI 2 "general_operand" "ri,rm"))
6858           (const_int 0)))
6859    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6860         (minus:SI (match_dup 1) (match_dup 2)))]
6861   "ix86_match_ccmode (insn, CCGOCmode)
6862    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6863   "sub{l}\t{%2, %0|%0, %2}"
6864   [(set_attr "type" "alu")
6865    (set_attr "mode" "SI")])
6866
6867 (define_insn "*subsi_2_zext"
6868   [(set (reg FLAGS_REG)
6869         (compare
6870           (minus:SI (match_operand:SI 1 "register_operand" "0")
6871                     (match_operand:SI 2 "general_operand" "rim"))
6872           (const_int 0)))
6873    (set (match_operand:DI 0 "register_operand" "=r")
6874         (zero_extend:DI
6875           (minus:SI (match_dup 1)
6876                     (match_dup 2))))]
6877   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6878    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6879   "sub{l}\t{%2, %k0|%k0, %2}"
6880   [(set_attr "type" "alu")
6881    (set_attr "mode" "SI")])
6882
6883 (define_insn "*subsi_3"
6884   [(set (reg FLAGS_REG)
6885         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6886                  (match_operand:SI 2 "general_operand" "ri,rm")))
6887    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6888         (minus:SI (match_dup 1) (match_dup 2)))]
6889   "ix86_match_ccmode (insn, CCmode)
6890    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6891   "sub{l}\t{%2, %0|%0, %2}"
6892   [(set_attr "type" "alu")
6893    (set_attr "mode" "SI")])
6894
6895 (define_insn "*subsi_3_zext"
6896   [(set (reg FLAGS_REG)
6897         (compare (match_operand:SI 1 "register_operand" "0")
6898                  (match_operand:SI 2 "general_operand" "rim")))
6899    (set (match_operand:DI 0 "register_operand" "=r")
6900         (zero_extend:DI
6901           (minus:SI (match_dup 1)
6902                     (match_dup 2))))]
6903   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6904    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6905   "sub{l}\t{%2, %1|%1, %2}"
6906   [(set_attr "type" "alu")
6907    (set_attr "mode" "DI")])
6908
6909 (define_expand "subhi3"
6910   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6911                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6912                              (match_operand:HI 2 "general_operand" "")))
6913               (clobber (reg:CC FLAGS_REG))])]
6914   "TARGET_HIMODE_MATH"
6915   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6916
6917 (define_insn "*subhi_1"
6918   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6919         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6920                   (match_operand:HI 2 "general_operand" "ri,rm")))
6921    (clobber (reg:CC FLAGS_REG))]
6922   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6923   "sub{w}\t{%2, %0|%0, %2}"
6924   [(set_attr "type" "alu")
6925    (set_attr "mode" "HI")])
6926
6927 (define_insn "*subhi_2"
6928   [(set (reg FLAGS_REG)
6929         (compare
6930           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6931                     (match_operand:HI 2 "general_operand" "ri,rm"))
6932           (const_int 0)))
6933    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6934         (minus:HI (match_dup 1) (match_dup 2)))]
6935   "ix86_match_ccmode (insn, CCGOCmode)
6936    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6937   "sub{w}\t{%2, %0|%0, %2}"
6938   [(set_attr "type" "alu")
6939    (set_attr "mode" "HI")])
6940
6941 (define_insn "*subhi_3"
6942   [(set (reg FLAGS_REG)
6943         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6944                  (match_operand:HI 2 "general_operand" "ri,rm")))
6945    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6946         (minus:HI (match_dup 1) (match_dup 2)))]
6947   "ix86_match_ccmode (insn, CCmode)
6948    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6949   "sub{w}\t{%2, %0|%0, %2}"
6950   [(set_attr "type" "alu")
6951    (set_attr "mode" "HI")])
6952
6953 (define_expand "subqi3"
6954   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6955                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6956                              (match_operand:QI 2 "general_operand" "")))
6957               (clobber (reg:CC FLAGS_REG))])]
6958   "TARGET_QIMODE_MATH"
6959   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6960
6961 (define_insn "*subqi_1"
6962   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6963         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6964                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6965    (clobber (reg:CC FLAGS_REG))]
6966   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6967   "sub{b}\t{%2, %0|%0, %2}"
6968   [(set_attr "type" "alu")
6969    (set_attr "mode" "QI")])
6970
6971 (define_insn "*subqi_1_slp"
6972   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6973         (minus:QI (match_dup 0)
6974                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6975    (clobber (reg:CC FLAGS_REG))]
6976   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6977    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6978   "sub{b}\t{%1, %0|%0, %1}"
6979   [(set_attr "type" "alu1")
6980    (set_attr "mode" "QI")])
6981
6982 (define_insn "*subqi_2"
6983   [(set (reg FLAGS_REG)
6984         (compare
6985           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6986                     (match_operand:QI 2 "general_operand" "qi,qm"))
6987           (const_int 0)))
6988    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6989         (minus:HI (match_dup 1) (match_dup 2)))]
6990   "ix86_match_ccmode (insn, CCGOCmode)
6991    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6992   "sub{b}\t{%2, %0|%0, %2}"
6993   [(set_attr "type" "alu")
6994    (set_attr "mode" "QI")])
6995
6996 (define_insn "*subqi_3"
6997   [(set (reg FLAGS_REG)
6998         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6999                  (match_operand:QI 2 "general_operand" "qi,qm")))
7000    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7001         (minus:HI (match_dup 1) (match_dup 2)))]
7002   "ix86_match_ccmode (insn, CCmode)
7003    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7004   "sub{b}\t{%2, %0|%0, %2}"
7005   [(set_attr "type" "alu")
7006    (set_attr "mode" "QI")])
7007
7008 ;; The patterns that match these are at the end of this file.
7009
7010 (define_expand "subxf3"
7011   [(set (match_operand:XF 0 "register_operand" "")
7012         (minus:XF (match_operand:XF 1 "register_operand" "")
7013                   (match_operand:XF 2 "register_operand" "")))]
7014   "TARGET_80387"
7015   "")
7016
7017 (define_expand "subdf3"
7018   [(set (match_operand:DF 0 "register_operand" "")
7019         (minus:DF (match_operand:DF 1 "register_operand" "")
7020                   (match_operand:DF 2 "nonimmediate_operand" "")))]
7021   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7022   "")
7023
7024 (define_expand "subsf3"
7025   [(set (match_operand:SF 0 "register_operand" "")
7026         (minus:SF (match_operand:SF 1 "register_operand" "")
7027                   (match_operand:SF 2 "nonimmediate_operand" "")))]
7028   "TARGET_80387 || TARGET_SSE_MATH"
7029   "")
7030 \f
7031 ;; Multiply instructions
7032
7033 (define_expand "muldi3"
7034   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7035                    (mult:DI (match_operand:DI 1 "register_operand" "")
7036                             (match_operand:DI 2 "x86_64_general_operand" "")))
7037               (clobber (reg:CC FLAGS_REG))])]
7038   "TARGET_64BIT"
7039   "")
7040
7041 ;; On AMDFAM10 
7042 ;; IMUL reg64, reg64, imm8      Direct
7043 ;; IMUL reg64, mem64, imm8      VectorPath
7044 ;; IMUL reg64, reg64, imm32     Direct
7045 ;; IMUL reg64, mem64, imm32     VectorPath 
7046 ;; IMUL reg64, reg64            Direct
7047 ;; IMUL reg64, mem64            Direct
7048
7049 (define_insn "*muldi3_1_rex64"
7050   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7051         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7052                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7053    (clobber (reg:CC FLAGS_REG))]
7054   "TARGET_64BIT
7055    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7056   "@
7057    imul{q}\t{%2, %1, %0|%0, %1, %2}
7058    imul{q}\t{%2, %1, %0|%0, %1, %2}
7059    imul{q}\t{%2, %0|%0, %2}"
7060   [(set_attr "type" "imul")
7061    (set_attr "prefix_0f" "0,0,1")
7062    (set (attr "athlon_decode")
7063         (cond [(eq_attr "cpu" "athlon")
7064                   (const_string "vector")
7065                (eq_attr "alternative" "1")
7066                   (const_string "vector")
7067                (and (eq_attr "alternative" "2")
7068                     (match_operand 1 "memory_operand" ""))
7069                   (const_string "vector")]
7070               (const_string "direct")))
7071    (set (attr "amdfam10_decode")
7072         (cond [(and (eq_attr "alternative" "0,1")
7073                     (match_operand 1 "memory_operand" ""))
7074                   (const_string "vector")]
7075               (const_string "direct")))       
7076    (set_attr "mode" "DI")])
7077
7078 (define_expand "mulsi3"
7079   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7080                    (mult:SI (match_operand:SI 1 "register_operand" "")
7081                             (match_operand:SI 2 "general_operand" "")))
7082               (clobber (reg:CC FLAGS_REG))])]
7083   ""
7084   "")
7085
7086 ;; On AMDFAM10 
7087 ;; IMUL reg32, reg32, imm8      Direct
7088 ;; IMUL reg32, mem32, imm8      VectorPath
7089 ;; IMUL reg32, reg32, imm32     Direct
7090 ;; IMUL reg32, mem32, imm32     VectorPath
7091 ;; IMUL reg32, reg32            Direct
7092 ;; IMUL reg32, mem32            Direct
7093
7094 (define_insn "*mulsi3_1"
7095   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7096         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7097                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7098    (clobber (reg:CC FLAGS_REG))]
7099   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7100   "@
7101    imul{l}\t{%2, %1, %0|%0, %1, %2}
7102    imul{l}\t{%2, %1, %0|%0, %1, %2}
7103    imul{l}\t{%2, %0|%0, %2}"
7104   [(set_attr "type" "imul")
7105    (set_attr "prefix_0f" "0,0,1")
7106    (set (attr "athlon_decode")
7107         (cond [(eq_attr "cpu" "athlon")
7108                   (const_string "vector")
7109                (eq_attr "alternative" "1")
7110                   (const_string "vector")
7111                (and (eq_attr "alternative" "2")
7112                     (match_operand 1 "memory_operand" ""))
7113                   (const_string "vector")]
7114               (const_string "direct")))
7115    (set (attr "amdfam10_decode")
7116         (cond [(and (eq_attr "alternative" "0,1")
7117                     (match_operand 1 "memory_operand" ""))
7118                   (const_string "vector")]
7119               (const_string "direct")))       
7120    (set_attr "mode" "SI")])
7121
7122 (define_insn "*mulsi3_1_zext"
7123   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7124         (zero_extend:DI
7125           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7126                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7127    (clobber (reg:CC FLAGS_REG))]
7128   "TARGET_64BIT
7129    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7130   "@
7131    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7132    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7133    imul{l}\t{%2, %k0|%k0, %2}"
7134   [(set_attr "type" "imul")
7135    (set_attr "prefix_0f" "0,0,1")
7136    (set (attr "athlon_decode")
7137         (cond [(eq_attr "cpu" "athlon")
7138                   (const_string "vector")
7139                (eq_attr "alternative" "1")
7140                   (const_string "vector")
7141                (and (eq_attr "alternative" "2")
7142                     (match_operand 1 "memory_operand" ""))
7143                   (const_string "vector")]
7144               (const_string "direct")))
7145    (set (attr "amdfam10_decode")
7146         (cond [(and (eq_attr "alternative" "0,1")
7147                     (match_operand 1 "memory_operand" ""))
7148                   (const_string "vector")]
7149               (const_string "direct")))       
7150    (set_attr "mode" "SI")])
7151
7152 (define_expand "mulhi3"
7153   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7154                    (mult:HI (match_operand:HI 1 "register_operand" "")
7155                             (match_operand:HI 2 "general_operand" "")))
7156               (clobber (reg:CC FLAGS_REG))])]
7157   "TARGET_HIMODE_MATH"
7158   "")
7159
7160 ;; On AMDFAM10
7161 ;; IMUL reg16, reg16, imm8      VectorPath
7162 ;; IMUL reg16, mem16, imm8      VectorPath
7163 ;; IMUL reg16, reg16, imm16     VectorPath
7164 ;; IMUL reg16, mem16, imm16     VectorPath
7165 ;; IMUL reg16, reg16            Direct
7166 ;; IMUL reg16, mem16            Direct
7167 (define_insn "*mulhi3_1"
7168   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7169         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7170                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7171    (clobber (reg:CC FLAGS_REG))]
7172   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7173   "@
7174    imul{w}\t{%2, %1, %0|%0, %1, %2}
7175    imul{w}\t{%2, %1, %0|%0, %1, %2}
7176    imul{w}\t{%2, %0|%0, %2}"
7177   [(set_attr "type" "imul")
7178    (set_attr "prefix_0f" "0,0,1")
7179    (set (attr "athlon_decode")
7180         (cond [(eq_attr "cpu" "athlon")
7181                   (const_string "vector")
7182                (eq_attr "alternative" "1,2")
7183                   (const_string "vector")]
7184               (const_string "direct")))
7185    (set (attr "amdfam10_decode")
7186         (cond [(eq_attr "alternative" "0,1")
7187                   (const_string "vector")]
7188               (const_string "direct")))
7189    (set_attr "mode" "HI")])
7190
7191 (define_expand "mulqi3"
7192   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7193                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7194                             (match_operand:QI 2 "register_operand" "")))
7195               (clobber (reg:CC FLAGS_REG))])]
7196   "TARGET_QIMODE_MATH"
7197   "")
7198
7199 ;;On AMDFAM10
7200 ;; MUL reg8     Direct
7201 ;; MUL mem8     Direct
7202
7203 (define_insn "*mulqi3_1"
7204   [(set (match_operand:QI 0 "register_operand" "=a")
7205         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7206                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7207    (clobber (reg:CC FLAGS_REG))]
7208   "TARGET_QIMODE_MATH
7209    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7210   "mul{b}\t%2"
7211   [(set_attr "type" "imul")
7212    (set_attr "length_immediate" "0")
7213    (set (attr "athlon_decode")
7214      (if_then_else (eq_attr "cpu" "athlon")
7215         (const_string "vector")
7216         (const_string "direct")))
7217    (set_attr "amdfam10_decode" "direct")        
7218    (set_attr "mode" "QI")])
7219
7220 (define_expand "umulqihi3"
7221   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7222                    (mult:HI (zero_extend:HI
7223                               (match_operand:QI 1 "nonimmediate_operand" ""))
7224                             (zero_extend:HI
7225                               (match_operand:QI 2 "register_operand" ""))))
7226               (clobber (reg:CC FLAGS_REG))])]
7227   "TARGET_QIMODE_MATH"
7228   "")
7229
7230 (define_insn "*umulqihi3_1"
7231   [(set (match_operand:HI 0 "register_operand" "=a")
7232         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7233                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7234    (clobber (reg:CC FLAGS_REG))]
7235   "TARGET_QIMODE_MATH
7236    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7237   "mul{b}\t%2"
7238   [(set_attr "type" "imul")
7239    (set_attr "length_immediate" "0")
7240    (set (attr "athlon_decode")
7241      (if_then_else (eq_attr "cpu" "athlon")
7242         (const_string "vector")
7243         (const_string "direct")))
7244    (set_attr "amdfam10_decode" "direct")        
7245    (set_attr "mode" "QI")])
7246
7247 (define_expand "mulqihi3"
7248   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7249                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7250                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7251               (clobber (reg:CC FLAGS_REG))])]
7252   "TARGET_QIMODE_MATH"
7253   "")
7254
7255 (define_insn "*mulqihi3_insn"
7256   [(set (match_operand:HI 0 "register_operand" "=a")
7257         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7258                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7259    (clobber (reg:CC FLAGS_REG))]
7260   "TARGET_QIMODE_MATH
7261    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7262   "imul{b}\t%2"
7263   [(set_attr "type" "imul")
7264    (set_attr "length_immediate" "0")
7265    (set (attr "athlon_decode")
7266      (if_then_else (eq_attr "cpu" "athlon")
7267         (const_string "vector")
7268         (const_string "direct")))
7269    (set_attr "amdfam10_decode" "direct")        
7270    (set_attr "mode" "QI")])
7271
7272 (define_expand "umulditi3"
7273   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7274                    (mult:TI (zero_extend:TI
7275                               (match_operand:DI 1 "nonimmediate_operand" ""))
7276                             (zero_extend:TI
7277                               (match_operand:DI 2 "register_operand" ""))))
7278               (clobber (reg:CC FLAGS_REG))])]
7279   "TARGET_64BIT"
7280   "")
7281
7282 (define_insn "*umulditi3_insn"
7283   [(set (match_operand:TI 0 "register_operand" "=A")
7284         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7285                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7286    (clobber (reg:CC FLAGS_REG))]
7287   "TARGET_64BIT
7288    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7289   "mul{q}\t%2"
7290   [(set_attr "type" "imul")
7291    (set_attr "length_immediate" "0")
7292    (set (attr "athlon_decode")
7293      (if_then_else (eq_attr "cpu" "athlon")
7294         (const_string "vector")
7295         (const_string "double")))
7296    (set_attr "amdfam10_decode" "double")        
7297    (set_attr "mode" "DI")])
7298
7299 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7300 (define_expand "umulsidi3"
7301   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7302                    (mult:DI (zero_extend:DI
7303                               (match_operand:SI 1 "nonimmediate_operand" ""))
7304                             (zero_extend:DI
7305                               (match_operand:SI 2 "register_operand" ""))))
7306               (clobber (reg:CC FLAGS_REG))])]
7307   "!TARGET_64BIT"
7308   "")
7309
7310 (define_insn "*umulsidi3_insn"
7311   [(set (match_operand:DI 0 "register_operand" "=A")
7312         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7313                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7314    (clobber (reg:CC FLAGS_REG))]
7315   "!TARGET_64BIT
7316    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7317   "mul{l}\t%2"
7318   [(set_attr "type" "imul")
7319    (set_attr "length_immediate" "0")
7320    (set (attr "athlon_decode")
7321      (if_then_else (eq_attr "cpu" "athlon")
7322         (const_string "vector")
7323         (const_string "double")))
7324    (set_attr "amdfam10_decode" "double")        
7325    (set_attr "mode" "SI")])
7326
7327 (define_expand "mulditi3"
7328   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7329                    (mult:TI (sign_extend:TI
7330                               (match_operand:DI 1 "nonimmediate_operand" ""))
7331                             (sign_extend:TI
7332                               (match_operand:DI 2 "register_operand" ""))))
7333               (clobber (reg:CC FLAGS_REG))])]
7334   "TARGET_64BIT"
7335   "")
7336
7337 (define_insn "*mulditi3_insn"
7338   [(set (match_operand:TI 0 "register_operand" "=A")
7339         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7340                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7341    (clobber (reg:CC FLAGS_REG))]
7342   "TARGET_64BIT
7343    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7344   "imul{q}\t%2"
7345   [(set_attr "type" "imul")
7346    (set_attr "length_immediate" "0")
7347    (set (attr "athlon_decode")
7348      (if_then_else (eq_attr "cpu" "athlon")
7349         (const_string "vector")
7350         (const_string "double")))
7351    (set_attr "amdfam10_decode" "double")
7352    (set_attr "mode" "DI")])
7353
7354 (define_expand "mulsidi3"
7355   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7356                    (mult:DI (sign_extend:DI
7357                               (match_operand:SI 1 "nonimmediate_operand" ""))
7358                             (sign_extend:DI
7359                               (match_operand:SI 2 "register_operand" ""))))
7360               (clobber (reg:CC FLAGS_REG))])]
7361   "!TARGET_64BIT"
7362   "")
7363
7364 (define_insn "*mulsidi3_insn"
7365   [(set (match_operand:DI 0 "register_operand" "=A")
7366         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7367                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7368    (clobber (reg:CC FLAGS_REG))]
7369   "!TARGET_64BIT
7370    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7371   "imul{l}\t%2"
7372   [(set_attr "type" "imul")
7373    (set_attr "length_immediate" "0")
7374    (set (attr "athlon_decode")
7375      (if_then_else (eq_attr "cpu" "athlon")
7376         (const_string "vector")
7377         (const_string "double")))
7378    (set_attr "amdfam10_decode" "double")        
7379    (set_attr "mode" "SI")])
7380
7381 (define_expand "umuldi3_highpart"
7382   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7383                    (truncate:DI
7384                      (lshiftrt:TI
7385                        (mult:TI (zero_extend:TI
7386                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7387                                 (zero_extend:TI
7388                                   (match_operand:DI 2 "register_operand" "")))
7389                        (const_int 64))))
7390               (clobber (match_scratch:DI 3 ""))
7391               (clobber (reg:CC FLAGS_REG))])]
7392   "TARGET_64BIT"
7393   "")
7394
7395 (define_insn "*umuldi3_highpart_rex64"
7396   [(set (match_operand:DI 0 "register_operand" "=d")
7397         (truncate:DI
7398           (lshiftrt:TI
7399             (mult:TI (zero_extend:TI
7400                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7401                      (zero_extend:TI
7402                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7403             (const_int 64))))
7404    (clobber (match_scratch:DI 3 "=1"))
7405    (clobber (reg:CC FLAGS_REG))]
7406   "TARGET_64BIT
7407    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7408   "mul{q}\t%2"
7409   [(set_attr "type" "imul")
7410    (set_attr "length_immediate" "0")
7411    (set (attr "athlon_decode")
7412      (if_then_else (eq_attr "cpu" "athlon")
7413         (const_string "vector")
7414         (const_string "double")))
7415    (set_attr "amdfam10_decode" "double")        
7416    (set_attr "mode" "DI")])
7417
7418 (define_expand "umulsi3_highpart"
7419   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7420                    (truncate:SI
7421                      (lshiftrt:DI
7422                        (mult:DI (zero_extend:DI
7423                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7424                                 (zero_extend:DI
7425                                   (match_operand:SI 2 "register_operand" "")))
7426                        (const_int 32))))
7427               (clobber (match_scratch:SI 3 ""))
7428               (clobber (reg:CC FLAGS_REG))])]
7429   ""
7430   "")
7431
7432 (define_insn "*umulsi3_highpart_insn"
7433   [(set (match_operand:SI 0 "register_operand" "=d")
7434         (truncate:SI
7435           (lshiftrt:DI
7436             (mult:DI (zero_extend:DI
7437                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7438                      (zero_extend:DI
7439                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7440             (const_int 32))))
7441    (clobber (match_scratch:SI 3 "=1"))
7442    (clobber (reg:CC FLAGS_REG))]
7443   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7444   "mul{l}\t%2"
7445   [(set_attr "type" "imul")
7446    (set_attr "length_immediate" "0")
7447    (set (attr "athlon_decode")
7448      (if_then_else (eq_attr "cpu" "athlon")
7449         (const_string "vector")
7450         (const_string "double")))
7451    (set_attr "amdfam10_decode" "double")
7452    (set_attr "mode" "SI")])
7453
7454 (define_insn "*umulsi3_highpart_zext"
7455   [(set (match_operand:DI 0 "register_operand" "=d")
7456         (zero_extend:DI (truncate:SI
7457           (lshiftrt:DI
7458             (mult:DI (zero_extend:DI
7459                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7460                      (zero_extend:DI
7461                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7462             (const_int 32)))))
7463    (clobber (match_scratch:SI 3 "=1"))
7464    (clobber (reg:CC FLAGS_REG))]
7465   "TARGET_64BIT
7466    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7467   "mul{l}\t%2"
7468   [(set_attr "type" "imul")
7469    (set_attr "length_immediate" "0")
7470    (set (attr "athlon_decode")
7471      (if_then_else (eq_attr "cpu" "athlon")
7472         (const_string "vector")
7473         (const_string "double")))
7474    (set_attr "amdfam10_decode" "double")
7475    (set_attr "mode" "SI")])
7476
7477 (define_expand "smuldi3_highpart"
7478   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7479                    (truncate:DI
7480                      (lshiftrt:TI
7481                        (mult:TI (sign_extend:TI
7482                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7483                                 (sign_extend:TI
7484                                   (match_operand:DI 2 "register_operand" "")))
7485                        (const_int 64))))
7486               (clobber (match_scratch:DI 3 ""))
7487               (clobber (reg:CC FLAGS_REG))])]
7488   "TARGET_64BIT"
7489   "")
7490
7491 (define_insn "*smuldi3_highpart_rex64"
7492   [(set (match_operand:DI 0 "register_operand" "=d")
7493         (truncate:DI
7494           (lshiftrt:TI
7495             (mult:TI (sign_extend:TI
7496                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7497                      (sign_extend:TI
7498                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7499             (const_int 64))))
7500    (clobber (match_scratch:DI 3 "=1"))
7501    (clobber (reg:CC FLAGS_REG))]
7502   "TARGET_64BIT
7503    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7504   "imul{q}\t%2"
7505   [(set_attr "type" "imul")
7506    (set (attr "athlon_decode")
7507      (if_then_else (eq_attr "cpu" "athlon")
7508         (const_string "vector")
7509         (const_string "double")))
7510    (set_attr "amdfam10_decode" "double")
7511    (set_attr "mode" "DI")])
7512
7513 (define_expand "smulsi3_highpart"
7514   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7515                    (truncate:SI
7516                      (lshiftrt:DI
7517                        (mult:DI (sign_extend:DI
7518                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7519                                 (sign_extend:DI
7520                                   (match_operand:SI 2 "register_operand" "")))
7521                        (const_int 32))))
7522               (clobber (match_scratch:SI 3 ""))
7523               (clobber (reg:CC FLAGS_REG))])]
7524   ""
7525   "")
7526
7527 (define_insn "*smulsi3_highpart_insn"
7528   [(set (match_operand:SI 0 "register_operand" "=d")
7529         (truncate:SI
7530           (lshiftrt:DI
7531             (mult:DI (sign_extend:DI
7532                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7533                      (sign_extend:DI
7534                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7535             (const_int 32))))
7536    (clobber (match_scratch:SI 3 "=1"))
7537    (clobber (reg:CC FLAGS_REG))]
7538   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7539   "imul{l}\t%2"
7540   [(set_attr "type" "imul")
7541    (set (attr "athlon_decode")
7542      (if_then_else (eq_attr "cpu" "athlon")
7543         (const_string "vector")
7544         (const_string "double")))
7545    (set_attr "amdfam10_decode" "double")
7546    (set_attr "mode" "SI")])
7547
7548 (define_insn "*smulsi3_highpart_zext"
7549   [(set (match_operand:DI 0 "register_operand" "=d")
7550         (zero_extend:DI (truncate:SI
7551           (lshiftrt:DI
7552             (mult:DI (sign_extend:DI
7553                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7554                      (sign_extend:DI
7555                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7556             (const_int 32)))))
7557    (clobber (match_scratch:SI 3 "=1"))
7558    (clobber (reg:CC FLAGS_REG))]
7559   "TARGET_64BIT
7560    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7561   "imul{l}\t%2"
7562   [(set_attr "type" "imul")
7563    (set (attr "athlon_decode")
7564      (if_then_else (eq_attr "cpu" "athlon")
7565         (const_string "vector")
7566         (const_string "double")))
7567    (set_attr "amdfam10_decode" "double")
7568    (set_attr "mode" "SI")])
7569
7570 ;; The patterns that match these are at the end of this file.
7571
7572 (define_expand "mulxf3"
7573   [(set (match_operand:XF 0 "register_operand" "")
7574         (mult:XF (match_operand:XF 1 "register_operand" "")
7575                  (match_operand:XF 2 "register_operand" "")))]
7576   "TARGET_80387"
7577   "")
7578
7579 (define_expand "muldf3"
7580   [(set (match_operand:DF 0 "register_operand" "")
7581         (mult:DF (match_operand:DF 1 "register_operand" "")
7582                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7583   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7584   "")
7585
7586 (define_expand "mulsf3"
7587   [(set (match_operand:SF 0 "register_operand" "")
7588         (mult:SF (match_operand:SF 1 "register_operand" "")
7589                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7590   "TARGET_80387 || TARGET_SSE_MATH"
7591   "")
7592 \f
7593 ;; Divide instructions
7594
7595 (define_insn "divqi3"
7596   [(set (match_operand:QI 0 "register_operand" "=a")
7597         (div:QI (match_operand:HI 1 "register_operand" "0")
7598                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7599    (clobber (reg:CC FLAGS_REG))]
7600   "TARGET_QIMODE_MATH"
7601   "idiv{b}\t%2"
7602   [(set_attr "type" "idiv")
7603    (set_attr "mode" "QI")])
7604
7605 (define_insn "udivqi3"
7606   [(set (match_operand:QI 0 "register_operand" "=a")
7607         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7608                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7609    (clobber (reg:CC FLAGS_REG))]
7610   "TARGET_QIMODE_MATH"
7611   "div{b}\t%2"
7612   [(set_attr "type" "idiv")
7613    (set_attr "mode" "QI")])
7614
7615 ;; The patterns that match these are at the end of this file.
7616
7617 (define_expand "divxf3"
7618   [(set (match_operand:XF 0 "register_operand" "")
7619         (div:XF (match_operand:XF 1 "register_operand" "")
7620                 (match_operand:XF 2 "register_operand" "")))]
7621   "TARGET_80387"
7622   "")
7623
7624 (define_expand "divdf3"
7625   [(set (match_operand:DF 0 "register_operand" "")
7626         (div:DF (match_operand:DF 1 "register_operand" "")
7627                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7628    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7629    "")
7630
7631 (define_expand "divsf3"
7632   [(set (match_operand:SF 0 "register_operand" "")
7633         (div:SF (match_operand:SF 1 "register_operand" "")
7634                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7635   "TARGET_80387 || TARGET_SSE_MATH"
7636   "")
7637 \f
7638 ;; Remainder instructions.
7639
7640 (define_expand "divmoddi4"
7641   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7642                    (div:DI (match_operand:DI 1 "register_operand" "")
7643                            (match_operand:DI 2 "nonimmediate_operand" "")))
7644               (set (match_operand:DI 3 "register_operand" "")
7645                    (mod:DI (match_dup 1) (match_dup 2)))
7646               (clobber (reg:CC FLAGS_REG))])]
7647   "TARGET_64BIT"
7648   "")
7649
7650 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7651 ;; Penalize eax case slightly because it results in worse scheduling
7652 ;; of code.
7653 (define_insn "*divmoddi4_nocltd_rex64"
7654   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7655         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7656                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7657    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7658         (mod:DI (match_dup 2) (match_dup 3)))
7659    (clobber (reg:CC FLAGS_REG))]
7660   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7661   "#"
7662   [(set_attr "type" "multi")])
7663
7664 (define_insn "*divmoddi4_cltd_rex64"
7665   [(set (match_operand:DI 0 "register_operand" "=a")
7666         (div:DI (match_operand:DI 2 "register_operand" "a")
7667                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7668    (set (match_operand:DI 1 "register_operand" "=&d")
7669         (mod:DI (match_dup 2) (match_dup 3)))
7670    (clobber (reg:CC FLAGS_REG))]
7671   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7672   "#"
7673   [(set_attr "type" "multi")])
7674
7675 (define_insn "*divmoddi_noext_rex64"
7676   [(set (match_operand:DI 0 "register_operand" "=a")
7677         (div:DI (match_operand:DI 1 "register_operand" "0")
7678                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7679    (set (match_operand:DI 3 "register_operand" "=d")
7680         (mod:DI (match_dup 1) (match_dup 2)))
7681    (use (match_operand:DI 4 "register_operand" "3"))
7682    (clobber (reg:CC FLAGS_REG))]
7683   "TARGET_64BIT"
7684   "idiv{q}\t%2"
7685   [(set_attr "type" "idiv")
7686    (set_attr "mode" "DI")])
7687
7688 (define_split
7689   [(set (match_operand:DI 0 "register_operand" "")
7690         (div:DI (match_operand:DI 1 "register_operand" "")
7691                 (match_operand:DI 2 "nonimmediate_operand" "")))
7692    (set (match_operand:DI 3 "register_operand" "")
7693         (mod:DI (match_dup 1) (match_dup 2)))
7694    (clobber (reg:CC FLAGS_REG))]
7695   "TARGET_64BIT && reload_completed"
7696   [(parallel [(set (match_dup 3)
7697                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7698               (clobber (reg:CC FLAGS_REG))])
7699    (parallel [(set (match_dup 0)
7700                    (div:DI (reg:DI 0) (match_dup 2)))
7701               (set (match_dup 3)
7702                    (mod:DI (reg:DI 0) (match_dup 2)))
7703               (use (match_dup 3))
7704               (clobber (reg:CC FLAGS_REG))])]
7705 {
7706   /* Avoid use of cltd in favor of a mov+shift.  */
7707   if (!TARGET_USE_CLTD && !optimize_size)
7708     {
7709       if (true_regnum (operands[1]))
7710         emit_move_insn (operands[0], operands[1]);
7711       else
7712         emit_move_insn (operands[3], operands[1]);
7713       operands[4] = operands[3];
7714     }
7715   else
7716     {
7717       gcc_assert (!true_regnum (operands[1]));
7718       operands[4] = operands[1];
7719     }
7720 })
7721
7722
7723 (define_expand "divmodsi4"
7724   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7725                    (div:SI (match_operand:SI 1 "register_operand" "")
7726                            (match_operand:SI 2 "nonimmediate_operand" "")))
7727               (set (match_operand:SI 3 "register_operand" "")
7728                    (mod:SI (match_dup 1) (match_dup 2)))
7729               (clobber (reg:CC FLAGS_REG))])]
7730   ""
7731   "")
7732
7733 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7734 ;; Penalize eax case slightly because it results in worse scheduling
7735 ;; of code.
7736 (define_insn "*divmodsi4_nocltd"
7737   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7738         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7739                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7740    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7741         (mod:SI (match_dup 2) (match_dup 3)))
7742    (clobber (reg:CC FLAGS_REG))]
7743   "!optimize_size && !TARGET_USE_CLTD"
7744   "#"
7745   [(set_attr "type" "multi")])
7746
7747 (define_insn "*divmodsi4_cltd"
7748   [(set (match_operand:SI 0 "register_operand" "=a")
7749         (div:SI (match_operand:SI 2 "register_operand" "a")
7750                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7751    (set (match_operand:SI 1 "register_operand" "=&d")
7752         (mod:SI (match_dup 2) (match_dup 3)))
7753    (clobber (reg:CC FLAGS_REG))]
7754   "optimize_size || TARGET_USE_CLTD"
7755   "#"
7756   [(set_attr "type" "multi")])
7757
7758 (define_insn "*divmodsi_noext"
7759   [(set (match_operand:SI 0 "register_operand" "=a")
7760         (div:SI (match_operand:SI 1 "register_operand" "0")
7761                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7762    (set (match_operand:SI 3 "register_operand" "=d")
7763         (mod:SI (match_dup 1) (match_dup 2)))
7764    (use (match_operand:SI 4 "register_operand" "3"))
7765    (clobber (reg:CC FLAGS_REG))]
7766   ""
7767   "idiv{l}\t%2"
7768   [(set_attr "type" "idiv")
7769    (set_attr "mode" "SI")])
7770
7771 (define_split
7772   [(set (match_operand:SI 0 "register_operand" "")
7773         (div:SI (match_operand:SI 1 "register_operand" "")
7774                 (match_operand:SI 2 "nonimmediate_operand" "")))
7775    (set (match_operand:SI 3 "register_operand" "")
7776         (mod:SI (match_dup 1) (match_dup 2)))
7777    (clobber (reg:CC FLAGS_REG))]
7778   "reload_completed"
7779   [(parallel [(set (match_dup 3)
7780                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7781               (clobber (reg:CC FLAGS_REG))])
7782    (parallel [(set (match_dup 0)
7783                    (div:SI (reg:SI 0) (match_dup 2)))
7784               (set (match_dup 3)
7785                    (mod:SI (reg:SI 0) (match_dup 2)))
7786               (use (match_dup 3))
7787               (clobber (reg:CC FLAGS_REG))])]
7788 {
7789   /* Avoid use of cltd in favor of a mov+shift.  */
7790   if (!TARGET_USE_CLTD && !optimize_size)
7791     {
7792       if (true_regnum (operands[1]))
7793         emit_move_insn (operands[0], operands[1]);
7794       else
7795         emit_move_insn (operands[3], operands[1]);
7796       operands[4] = operands[3];
7797     }
7798   else
7799     {
7800       gcc_assert (!true_regnum (operands[1]));
7801       operands[4] = operands[1];
7802     }
7803 })
7804 ;; %%% Split me.
7805 (define_insn "divmodhi4"
7806   [(set (match_operand:HI 0 "register_operand" "=a")
7807         (div:HI (match_operand:HI 1 "register_operand" "0")
7808                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7809    (set (match_operand:HI 3 "register_operand" "=&d")
7810         (mod:HI (match_dup 1) (match_dup 2)))
7811    (clobber (reg:CC FLAGS_REG))]
7812   "TARGET_HIMODE_MATH"
7813   "cwtd\;idiv{w}\t%2"
7814   [(set_attr "type" "multi")
7815    (set_attr "length_immediate" "0")
7816    (set_attr "mode" "SI")])
7817
7818 (define_insn "udivmoddi4"
7819   [(set (match_operand:DI 0 "register_operand" "=a")
7820         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7821                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7822    (set (match_operand:DI 3 "register_operand" "=&d")
7823         (umod:DI (match_dup 1) (match_dup 2)))
7824    (clobber (reg:CC FLAGS_REG))]
7825   "TARGET_64BIT"
7826   "xor{q}\t%3, %3\;div{q}\t%2"
7827   [(set_attr "type" "multi")
7828    (set_attr "length_immediate" "0")
7829    (set_attr "mode" "DI")])
7830
7831 (define_insn "*udivmoddi4_noext"
7832   [(set (match_operand:DI 0 "register_operand" "=a")
7833         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7834                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7835    (set (match_operand:DI 3 "register_operand" "=d")
7836         (umod:DI (match_dup 1) (match_dup 2)))
7837    (use (match_dup 3))
7838    (clobber (reg:CC FLAGS_REG))]
7839   "TARGET_64BIT"
7840   "div{q}\t%2"
7841   [(set_attr "type" "idiv")
7842    (set_attr "mode" "DI")])
7843
7844 (define_split
7845   [(set (match_operand:DI 0 "register_operand" "")
7846         (udiv:DI (match_operand:DI 1 "register_operand" "")
7847                  (match_operand:DI 2 "nonimmediate_operand" "")))
7848    (set (match_operand:DI 3 "register_operand" "")
7849         (umod:DI (match_dup 1) (match_dup 2)))
7850    (clobber (reg:CC FLAGS_REG))]
7851   "TARGET_64BIT && reload_completed"
7852   [(set (match_dup 3) (const_int 0))
7853    (parallel [(set (match_dup 0)
7854                    (udiv:DI (match_dup 1) (match_dup 2)))
7855               (set (match_dup 3)
7856                    (umod:DI (match_dup 1) (match_dup 2)))
7857               (use (match_dup 3))
7858               (clobber (reg:CC FLAGS_REG))])]
7859   "")
7860
7861 (define_insn "udivmodsi4"
7862   [(set (match_operand:SI 0 "register_operand" "=a")
7863         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7864                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7865    (set (match_operand:SI 3 "register_operand" "=&d")
7866         (umod:SI (match_dup 1) (match_dup 2)))
7867    (clobber (reg:CC FLAGS_REG))]
7868   ""
7869   "xor{l}\t%3, %3\;div{l}\t%2"
7870   [(set_attr "type" "multi")
7871    (set_attr "length_immediate" "0")
7872    (set_attr "mode" "SI")])
7873
7874 (define_insn "*udivmodsi4_noext"
7875   [(set (match_operand:SI 0 "register_operand" "=a")
7876         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7877                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7878    (set (match_operand:SI 3 "register_operand" "=d")
7879         (umod:SI (match_dup 1) (match_dup 2)))
7880    (use (match_dup 3))
7881    (clobber (reg:CC FLAGS_REG))]
7882   ""
7883   "div{l}\t%2"
7884   [(set_attr "type" "idiv")
7885    (set_attr "mode" "SI")])
7886
7887 (define_split
7888   [(set (match_operand:SI 0 "register_operand" "")
7889         (udiv:SI (match_operand:SI 1 "register_operand" "")
7890                  (match_operand:SI 2 "nonimmediate_operand" "")))
7891    (set (match_operand:SI 3 "register_operand" "")
7892         (umod:SI (match_dup 1) (match_dup 2)))
7893    (clobber (reg:CC FLAGS_REG))]
7894   "reload_completed"
7895   [(set (match_dup 3) (const_int 0))
7896    (parallel [(set (match_dup 0)
7897                    (udiv:SI (match_dup 1) (match_dup 2)))
7898               (set (match_dup 3)
7899                    (umod:SI (match_dup 1) (match_dup 2)))
7900               (use (match_dup 3))
7901               (clobber (reg:CC FLAGS_REG))])]
7902   "")
7903
7904 (define_expand "udivmodhi4"
7905   [(set (match_dup 4) (const_int 0))
7906    (parallel [(set (match_operand:HI 0 "register_operand" "")
7907                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7908                             (match_operand:HI 2 "nonimmediate_operand" "")))
7909               (set (match_operand:HI 3 "register_operand" "")
7910                    (umod:HI (match_dup 1) (match_dup 2)))
7911               (use (match_dup 4))
7912               (clobber (reg:CC FLAGS_REG))])]
7913   "TARGET_HIMODE_MATH"
7914   "operands[4] = gen_reg_rtx (HImode);")
7915
7916 (define_insn "*udivmodhi_noext"
7917   [(set (match_operand:HI 0 "register_operand" "=a")
7918         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7919                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7920    (set (match_operand:HI 3 "register_operand" "=d")
7921         (umod:HI (match_dup 1) (match_dup 2)))
7922    (use (match_operand:HI 4 "register_operand" "3"))
7923    (clobber (reg:CC FLAGS_REG))]
7924   ""
7925   "div{w}\t%2"
7926   [(set_attr "type" "idiv")
7927    (set_attr "mode" "HI")])
7928
7929 ;; We cannot use div/idiv for double division, because it causes
7930 ;; "division by zero" on the overflow and that's not what we expect
7931 ;; from truncate.  Because true (non truncating) double division is
7932 ;; never generated, we can't create this insn anyway.
7933 ;
7934 ;(define_insn ""
7935 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7936 ;       (truncate:SI
7937 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7938 ;                  (zero_extend:DI
7939 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7940 ;   (set (match_operand:SI 3 "register_operand" "=d")
7941 ;       (truncate:SI
7942 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7943 ;   (clobber (reg:CC FLAGS_REG))]
7944 ;  ""
7945 ;  "div{l}\t{%2, %0|%0, %2}"
7946 ;  [(set_attr "type" "idiv")])
7947 \f
7948 ;;- Logical AND instructions
7949
7950 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7951 ;; Note that this excludes ah.
7952
7953 (define_insn "*testdi_1_rex64"
7954   [(set (reg FLAGS_REG)
7955         (compare
7956           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7957                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7958           (const_int 0)))]
7959   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7960    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7961   "@
7962    test{l}\t{%k1, %k0|%k0, %k1}
7963    test{l}\t{%k1, %k0|%k0, %k1}
7964    test{q}\t{%1, %0|%0, %1}
7965    test{q}\t{%1, %0|%0, %1}
7966    test{q}\t{%1, %0|%0, %1}"
7967   [(set_attr "type" "test")
7968    (set_attr "modrm" "0,1,0,1,1")
7969    (set_attr "mode" "SI,SI,DI,DI,DI")
7970    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7971
7972 (define_insn "testsi_1"
7973   [(set (reg FLAGS_REG)
7974         (compare
7975           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7976                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7977           (const_int 0)))]
7978   "ix86_match_ccmode (insn, CCNOmode)
7979    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7980   "test{l}\t{%1, %0|%0, %1}"
7981   [(set_attr "type" "test")
7982    (set_attr "modrm" "0,1,1")
7983    (set_attr "mode" "SI")
7984    (set_attr "pent_pair" "uv,np,uv")])
7985
7986 (define_expand "testsi_ccno_1"
7987   [(set (reg:CCNO FLAGS_REG)
7988         (compare:CCNO
7989           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7990                   (match_operand:SI 1 "nonmemory_operand" ""))
7991           (const_int 0)))]
7992   ""
7993   "")
7994
7995 (define_insn "*testhi_1"
7996   [(set (reg FLAGS_REG)
7997         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7998                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7999                  (const_int 0)))]
8000   "ix86_match_ccmode (insn, CCNOmode)
8001    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8002   "test{w}\t{%1, %0|%0, %1}"
8003   [(set_attr "type" "test")
8004    (set_attr "modrm" "0,1,1")
8005    (set_attr "mode" "HI")
8006    (set_attr "pent_pair" "uv,np,uv")])
8007
8008 (define_expand "testqi_ccz_1"
8009   [(set (reg:CCZ FLAGS_REG)
8010         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8011                              (match_operand:QI 1 "nonmemory_operand" ""))
8012                  (const_int 0)))]
8013   ""
8014   "")
8015
8016 (define_insn "*testqi_1_maybe_si"
8017   [(set (reg FLAGS_REG)
8018         (compare
8019           (and:QI
8020             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8021             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8022           (const_int 0)))]
8023    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8024     && ix86_match_ccmode (insn,
8025                          CONST_INT_P (operands[1])
8026                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8027 {
8028   if (which_alternative == 3)
8029     {
8030       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8031         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8032       return "test{l}\t{%1, %k0|%k0, %1}";
8033     }
8034   return "test{b}\t{%1, %0|%0, %1}";
8035 }
8036   [(set_attr "type" "test")
8037    (set_attr "modrm" "0,1,1,1")
8038    (set_attr "mode" "QI,QI,QI,SI")
8039    (set_attr "pent_pair" "uv,np,uv,np")])
8040
8041 (define_insn "*testqi_1"
8042   [(set (reg FLAGS_REG)
8043         (compare
8044           (and:QI
8045             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8046             (match_operand:QI 1 "general_operand" "n,n,qn"))
8047           (const_int 0)))]
8048   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8049    && ix86_match_ccmode (insn, CCNOmode)"
8050   "test{b}\t{%1, %0|%0, %1}"
8051   [(set_attr "type" "test")
8052    (set_attr "modrm" "0,1,1")
8053    (set_attr "mode" "QI")
8054    (set_attr "pent_pair" "uv,np,uv")])
8055
8056 (define_expand "testqi_ext_ccno_0"
8057   [(set (reg:CCNO FLAGS_REG)
8058         (compare:CCNO
8059           (and:SI
8060             (zero_extract:SI
8061               (match_operand 0 "ext_register_operand" "")
8062               (const_int 8)
8063               (const_int 8))
8064             (match_operand 1 "const_int_operand" ""))
8065           (const_int 0)))]
8066   ""
8067   "")
8068
8069 (define_insn "*testqi_ext_0"
8070   [(set (reg FLAGS_REG)
8071         (compare
8072           (and:SI
8073             (zero_extract:SI
8074               (match_operand 0 "ext_register_operand" "Q")
8075               (const_int 8)
8076               (const_int 8))
8077             (match_operand 1 "const_int_operand" "n"))
8078           (const_int 0)))]
8079   "ix86_match_ccmode (insn, CCNOmode)"
8080   "test{b}\t{%1, %h0|%h0, %1}"
8081   [(set_attr "type" "test")
8082    (set_attr "mode" "QI")
8083    (set_attr "length_immediate" "1")
8084    (set_attr "pent_pair" "np")])
8085
8086 (define_insn "*testqi_ext_1"
8087   [(set (reg FLAGS_REG)
8088         (compare
8089           (and:SI
8090             (zero_extract:SI
8091               (match_operand 0 "ext_register_operand" "Q")
8092               (const_int 8)
8093               (const_int 8))
8094             (zero_extend:SI
8095               (match_operand:QI 1 "general_operand" "Qm")))
8096           (const_int 0)))]
8097   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8098    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8099   "test{b}\t{%1, %h0|%h0, %1}"
8100   [(set_attr "type" "test")
8101    (set_attr "mode" "QI")])
8102
8103 (define_insn "*testqi_ext_1_rex64"
8104   [(set (reg FLAGS_REG)
8105         (compare
8106           (and:SI
8107             (zero_extract:SI
8108               (match_operand 0 "ext_register_operand" "Q")
8109               (const_int 8)
8110               (const_int 8))
8111             (zero_extend:SI
8112               (match_operand:QI 1 "register_operand" "Q")))
8113           (const_int 0)))]
8114   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8115   "test{b}\t{%1, %h0|%h0, %1}"
8116   [(set_attr "type" "test")
8117    (set_attr "mode" "QI")])
8118
8119 (define_insn "*testqi_ext_2"
8120   [(set (reg FLAGS_REG)
8121         (compare
8122           (and:SI
8123             (zero_extract:SI
8124               (match_operand 0 "ext_register_operand" "Q")
8125               (const_int 8)
8126               (const_int 8))
8127             (zero_extract:SI
8128               (match_operand 1 "ext_register_operand" "Q")
8129               (const_int 8)
8130               (const_int 8)))
8131           (const_int 0)))]
8132   "ix86_match_ccmode (insn, CCNOmode)"
8133   "test{b}\t{%h1, %h0|%h0, %h1}"
8134   [(set_attr "type" "test")
8135    (set_attr "mode" "QI")])
8136
8137 ;; Combine likes to form bit extractions for some tests.  Humor it.
8138 (define_insn "*testqi_ext_3"
8139   [(set (reg FLAGS_REG)
8140         (compare (zero_extract:SI
8141                    (match_operand 0 "nonimmediate_operand" "rm")
8142                    (match_operand:SI 1 "const_int_operand" "")
8143                    (match_operand:SI 2 "const_int_operand" ""))
8144                  (const_int 0)))]
8145   "ix86_match_ccmode (insn, CCNOmode)
8146    && INTVAL (operands[1]) > 0
8147    && INTVAL (operands[2]) >= 0
8148    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8149    && (GET_MODE (operands[0]) == SImode
8150        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8151        || GET_MODE (operands[0]) == HImode
8152        || GET_MODE (operands[0]) == QImode)"
8153   "#")
8154
8155 (define_insn "*testqi_ext_3_rex64"
8156   [(set (reg FLAGS_REG)
8157         (compare (zero_extract:DI
8158                    (match_operand 0 "nonimmediate_operand" "rm")
8159                    (match_operand:DI 1 "const_int_operand" "")
8160                    (match_operand:DI 2 "const_int_operand" ""))
8161                  (const_int 0)))]
8162   "TARGET_64BIT
8163    && ix86_match_ccmode (insn, CCNOmode)
8164    && INTVAL (operands[1]) > 0
8165    && INTVAL (operands[2]) >= 0
8166    /* Ensure that resulting mask is zero or sign extended operand.  */
8167    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8168        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8169            && INTVAL (operands[1]) > 32))
8170    && (GET_MODE (operands[0]) == SImode
8171        || GET_MODE (operands[0]) == DImode
8172        || GET_MODE (operands[0]) == HImode
8173        || GET_MODE (operands[0]) == QImode)"
8174   "#")
8175
8176 (define_split
8177   [(set (match_operand 0 "flags_reg_operand" "")
8178         (match_operator 1 "compare_operator"
8179           [(zero_extract
8180              (match_operand 2 "nonimmediate_operand" "")
8181              (match_operand 3 "const_int_operand" "")
8182              (match_operand 4 "const_int_operand" ""))
8183            (const_int 0)]))]
8184   "ix86_match_ccmode (insn, CCNOmode)"
8185   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8186 {
8187   rtx val = operands[2];
8188   HOST_WIDE_INT len = INTVAL (operands[3]);
8189   HOST_WIDE_INT pos = INTVAL (operands[4]);
8190   HOST_WIDE_INT mask;
8191   enum machine_mode mode, submode;
8192
8193   mode = GET_MODE (val);
8194   if (MEM_P (val))
8195     {
8196       /* ??? Combine likes to put non-volatile mem extractions in QImode
8197          no matter the size of the test.  So find a mode that works.  */
8198       if (! MEM_VOLATILE_P (val))
8199         {
8200           mode = smallest_mode_for_size (pos + len, MODE_INT);
8201           val = adjust_address (val, mode, 0);
8202         }
8203     }
8204   else if (GET_CODE (val) == SUBREG
8205            && (submode = GET_MODE (SUBREG_REG (val)),
8206                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8207            && pos + len <= GET_MODE_BITSIZE (submode))
8208     {
8209       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8210       mode = submode;
8211       val = SUBREG_REG (val);
8212     }
8213   else if (mode == HImode && pos + len <= 8)
8214     {
8215       /* Small HImode tests can be converted to QImode.  */
8216       mode = QImode;
8217       val = gen_lowpart (QImode, val);
8218     }
8219
8220   if (len == HOST_BITS_PER_WIDE_INT)
8221     mask = -1;
8222   else
8223     mask = ((HOST_WIDE_INT)1 << len) - 1;
8224   mask <<= pos;
8225
8226   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8227 })
8228
8229 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8230 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8231 ;; this is relatively important trick.
8232 ;; Do the conversion only post-reload to avoid limiting of the register class
8233 ;; to QI regs.
8234 (define_split
8235   [(set (match_operand 0 "flags_reg_operand" "")
8236         (match_operator 1 "compare_operator"
8237           [(and (match_operand 2 "register_operand" "")
8238                 (match_operand 3 "const_int_operand" ""))
8239            (const_int 0)]))]
8240    "reload_completed
8241     && QI_REG_P (operands[2])
8242     && GET_MODE (operands[2]) != QImode
8243     && ((ix86_match_ccmode (insn, CCZmode)
8244          && !(INTVAL (operands[3]) & ~(255 << 8)))
8245         || (ix86_match_ccmode (insn, CCNOmode)
8246             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8247   [(set (match_dup 0)
8248         (match_op_dup 1
8249           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8250                    (match_dup 3))
8251            (const_int 0)]))]
8252   "operands[2] = gen_lowpart (SImode, operands[2]);
8253    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8254
8255 (define_split
8256   [(set (match_operand 0 "flags_reg_operand" "")
8257         (match_operator 1 "compare_operator"
8258           [(and (match_operand 2 "nonimmediate_operand" "")
8259                 (match_operand 3 "const_int_operand" ""))
8260            (const_int 0)]))]
8261    "reload_completed
8262     && GET_MODE (operands[2]) != QImode
8263     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8264     && ((ix86_match_ccmode (insn, CCZmode)
8265          && !(INTVAL (operands[3]) & ~255))
8266         || (ix86_match_ccmode (insn, CCNOmode)
8267             && !(INTVAL (operands[3]) & ~127)))"
8268   [(set (match_dup 0)
8269         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8270                          (const_int 0)]))]
8271   "operands[2] = gen_lowpart (QImode, operands[2]);
8272    operands[3] = gen_lowpart (QImode, operands[3]);")
8273
8274
8275 ;; %%% This used to optimize known byte-wide and operations to memory,
8276 ;; and sometimes to QImode registers.  If this is considered useful,
8277 ;; it should be done with splitters.
8278
8279 (define_expand "anddi3"
8280   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8281         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8282                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8283    (clobber (reg:CC FLAGS_REG))]
8284   "TARGET_64BIT"
8285   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8286
8287 (define_insn "*anddi_1_rex64"
8288   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8289         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8290                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8291    (clobber (reg:CC FLAGS_REG))]
8292   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8293 {
8294   switch (get_attr_type (insn))
8295     {
8296     case TYPE_IMOVX:
8297       {
8298         enum machine_mode mode;
8299
8300         gcc_assert (CONST_INT_P (operands[2]));
8301         if (INTVAL (operands[2]) == 0xff)
8302           mode = QImode;
8303         else
8304           {
8305             gcc_assert (INTVAL (operands[2]) == 0xffff);
8306             mode = HImode;
8307           }
8308
8309         operands[1] = gen_lowpart (mode, operands[1]);
8310         if (mode == QImode)
8311           return "movz{bq|x}\t{%1,%0|%0, %1}";
8312         else
8313           return "movz{wq|x}\t{%1,%0|%0, %1}";
8314       }
8315
8316     default:
8317       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8318       if (get_attr_mode (insn) == MODE_SI)
8319         return "and{l}\t{%k2, %k0|%k0, %k2}";
8320       else
8321         return "and{q}\t{%2, %0|%0, %2}";
8322     }
8323 }
8324   [(set_attr "type" "alu,alu,alu,imovx")
8325    (set_attr "length_immediate" "*,*,*,0")
8326    (set_attr "mode" "SI,DI,DI,DI")])
8327
8328 (define_insn "*anddi_2"
8329   [(set (reg FLAGS_REG)
8330         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8331                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8332                  (const_int 0)))
8333    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8334         (and:DI (match_dup 1) (match_dup 2)))]
8335   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8336    && ix86_binary_operator_ok (AND, DImode, operands)"
8337   "@
8338    and{l}\t{%k2, %k0|%k0, %k2}
8339    and{q}\t{%2, %0|%0, %2}
8340    and{q}\t{%2, %0|%0, %2}"
8341   [(set_attr "type" "alu")
8342    (set_attr "mode" "SI,DI,DI")])
8343
8344 (define_expand "andsi3"
8345   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8346         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8347                 (match_operand:SI 2 "general_operand" "")))
8348    (clobber (reg:CC FLAGS_REG))]
8349   ""
8350   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8351
8352 (define_insn "*andsi_1"
8353   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8354         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8355                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8356    (clobber (reg:CC FLAGS_REG))]
8357   "ix86_binary_operator_ok (AND, SImode, operands)"
8358 {
8359   switch (get_attr_type (insn))
8360     {
8361     case TYPE_IMOVX:
8362       {
8363         enum machine_mode mode;
8364
8365         gcc_assert (CONST_INT_P (operands[2]));
8366         if (INTVAL (operands[2]) == 0xff)
8367           mode = QImode;
8368         else
8369           {
8370             gcc_assert (INTVAL (operands[2]) == 0xffff);
8371             mode = HImode;
8372           }
8373
8374         operands[1] = gen_lowpart (mode, operands[1]);
8375         if (mode == QImode)
8376           return "movz{bl|x}\t{%1,%0|%0, %1}";
8377         else
8378           return "movz{wl|x}\t{%1,%0|%0, %1}";
8379       }
8380
8381     default:
8382       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8383       return "and{l}\t{%2, %0|%0, %2}";
8384     }
8385 }
8386   [(set_attr "type" "alu,alu,imovx")
8387    (set_attr "length_immediate" "*,*,0")
8388    (set_attr "mode" "SI")])
8389
8390 (define_split
8391   [(set (match_operand 0 "register_operand" "")
8392         (and (match_dup 0)
8393              (const_int -65536)))
8394    (clobber (reg:CC FLAGS_REG))]
8395   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8396   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8397   "operands[1] = gen_lowpart (HImode, operands[0]);")
8398
8399 (define_split
8400   [(set (match_operand 0 "ext_register_operand" "")
8401         (and (match_dup 0)
8402              (const_int -256)))
8403    (clobber (reg:CC FLAGS_REG))]
8404   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8405   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8406   "operands[1] = gen_lowpart (QImode, operands[0]);")
8407
8408 (define_split
8409   [(set (match_operand 0 "ext_register_operand" "")
8410         (and (match_dup 0)
8411              (const_int -65281)))
8412    (clobber (reg:CC FLAGS_REG))]
8413   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8414   [(parallel [(set (zero_extract:SI (match_dup 0)
8415                                     (const_int 8)
8416                                     (const_int 8))
8417                    (xor:SI
8418                      (zero_extract:SI (match_dup 0)
8419                                       (const_int 8)
8420                                       (const_int 8))
8421                      (zero_extract:SI (match_dup 0)
8422                                       (const_int 8)
8423                                       (const_int 8))))
8424               (clobber (reg:CC FLAGS_REG))])]
8425   "operands[0] = gen_lowpart (SImode, operands[0]);")
8426
8427 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8428 (define_insn "*andsi_1_zext"
8429   [(set (match_operand:DI 0 "register_operand" "=r")
8430         (zero_extend:DI
8431           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8432                   (match_operand:SI 2 "general_operand" "rim"))))
8433    (clobber (reg:CC FLAGS_REG))]
8434   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8435   "and{l}\t{%2, %k0|%k0, %2}"
8436   [(set_attr "type" "alu")
8437    (set_attr "mode" "SI")])
8438
8439 (define_insn "*andsi_2"
8440   [(set (reg FLAGS_REG)
8441         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8442                          (match_operand:SI 2 "general_operand" "rim,ri"))
8443                  (const_int 0)))
8444    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8445         (and:SI (match_dup 1) (match_dup 2)))]
8446   "ix86_match_ccmode (insn, CCNOmode)
8447    && ix86_binary_operator_ok (AND, SImode, operands)"
8448   "and{l}\t{%2, %0|%0, %2}"
8449   [(set_attr "type" "alu")
8450    (set_attr "mode" "SI")])
8451
8452 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8453 (define_insn "*andsi_2_zext"
8454   [(set (reg FLAGS_REG)
8455         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8456                          (match_operand:SI 2 "general_operand" "rim"))
8457                  (const_int 0)))
8458    (set (match_operand:DI 0 "register_operand" "=r")
8459         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8460   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8461    && ix86_binary_operator_ok (AND, SImode, operands)"
8462   "and{l}\t{%2, %k0|%k0, %2}"
8463   [(set_attr "type" "alu")
8464    (set_attr "mode" "SI")])
8465
8466 (define_expand "andhi3"
8467   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8468         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8469                 (match_operand:HI 2 "general_operand" "")))
8470    (clobber (reg:CC FLAGS_REG))]
8471   "TARGET_HIMODE_MATH"
8472   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8473
8474 (define_insn "*andhi_1"
8475   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8476         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8477                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8478    (clobber (reg:CC FLAGS_REG))]
8479   "ix86_binary_operator_ok (AND, HImode, operands)"
8480 {
8481   switch (get_attr_type (insn))
8482     {
8483     case TYPE_IMOVX:
8484       gcc_assert (CONST_INT_P (operands[2]));
8485       gcc_assert (INTVAL (operands[2]) == 0xff);
8486       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8487
8488     default:
8489       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8490
8491       return "and{w}\t{%2, %0|%0, %2}";
8492     }
8493 }
8494   [(set_attr "type" "alu,alu,imovx")
8495    (set_attr "length_immediate" "*,*,0")
8496    (set_attr "mode" "HI,HI,SI")])
8497
8498 (define_insn "*andhi_2"
8499   [(set (reg FLAGS_REG)
8500         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8501                          (match_operand:HI 2 "general_operand" "rim,ri"))
8502                  (const_int 0)))
8503    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8504         (and:HI (match_dup 1) (match_dup 2)))]
8505   "ix86_match_ccmode (insn, CCNOmode)
8506    && ix86_binary_operator_ok (AND, HImode, operands)"
8507   "and{w}\t{%2, %0|%0, %2}"
8508   [(set_attr "type" "alu")
8509    (set_attr "mode" "HI")])
8510
8511 (define_expand "andqi3"
8512   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8513         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8514                 (match_operand:QI 2 "general_operand" "")))
8515    (clobber (reg:CC FLAGS_REG))]
8516   "TARGET_QIMODE_MATH"
8517   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8518
8519 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8520 (define_insn "*andqi_1"
8521   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8522         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8523                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8524    (clobber (reg:CC FLAGS_REG))]
8525   "ix86_binary_operator_ok (AND, QImode, operands)"
8526   "@
8527    and{b}\t{%2, %0|%0, %2}
8528    and{b}\t{%2, %0|%0, %2}
8529    and{l}\t{%k2, %k0|%k0, %k2}"
8530   [(set_attr "type" "alu")
8531    (set_attr "mode" "QI,QI,SI")])
8532
8533 (define_insn "*andqi_1_slp"
8534   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8535         (and:QI (match_dup 0)
8536                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8537    (clobber (reg:CC FLAGS_REG))]
8538   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8539    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8540   "and{b}\t{%1, %0|%0, %1}"
8541   [(set_attr "type" "alu1")
8542    (set_attr "mode" "QI")])
8543
8544 (define_insn "*andqi_2_maybe_si"
8545   [(set (reg FLAGS_REG)
8546         (compare (and:QI
8547                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8548                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8549                  (const_int 0)))
8550    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8551         (and:QI (match_dup 1) (match_dup 2)))]
8552   "ix86_binary_operator_ok (AND, QImode, operands)
8553    && ix86_match_ccmode (insn,
8554                          CONST_INT_P (operands[2])
8555                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8556 {
8557   if (which_alternative == 2)
8558     {
8559       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8560         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8561       return "and{l}\t{%2, %k0|%k0, %2}";
8562     }
8563   return "and{b}\t{%2, %0|%0, %2}";
8564 }
8565   [(set_attr "type" "alu")
8566    (set_attr "mode" "QI,QI,SI")])
8567
8568 (define_insn "*andqi_2"
8569   [(set (reg FLAGS_REG)
8570         (compare (and:QI
8571                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8572                    (match_operand:QI 2 "general_operand" "qim,qi"))
8573                  (const_int 0)))
8574    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8575         (and:QI (match_dup 1) (match_dup 2)))]
8576   "ix86_match_ccmode (insn, CCNOmode)
8577    && ix86_binary_operator_ok (AND, QImode, operands)"
8578   "and{b}\t{%2, %0|%0, %2}"
8579   [(set_attr "type" "alu")
8580    (set_attr "mode" "QI")])
8581
8582 (define_insn "*andqi_2_slp"
8583   [(set (reg FLAGS_REG)
8584         (compare (and:QI
8585                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8586                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8587                  (const_int 0)))
8588    (set (strict_low_part (match_dup 0))
8589         (and:QI (match_dup 0) (match_dup 1)))]
8590   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8591    && ix86_match_ccmode (insn, CCNOmode)
8592    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8593   "and{b}\t{%1, %0|%0, %1}"
8594   [(set_attr "type" "alu1")
8595    (set_attr "mode" "QI")])
8596
8597 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8598 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8599 ;; for a QImode operand, which of course failed.
8600
8601 (define_insn "andqi_ext_0"
8602   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8603                          (const_int 8)
8604                          (const_int 8))
8605         (and:SI
8606           (zero_extract:SI
8607             (match_operand 1 "ext_register_operand" "0")
8608             (const_int 8)
8609             (const_int 8))
8610           (match_operand 2 "const_int_operand" "n")))
8611    (clobber (reg:CC FLAGS_REG))]
8612   ""
8613   "and{b}\t{%2, %h0|%h0, %2}"
8614   [(set_attr "type" "alu")
8615    (set_attr "length_immediate" "1")
8616    (set_attr "mode" "QI")])
8617
8618 ;; Generated by peephole translating test to and.  This shows up
8619 ;; often in fp comparisons.
8620
8621 (define_insn "*andqi_ext_0_cc"
8622   [(set (reg FLAGS_REG)
8623         (compare
8624           (and:SI
8625             (zero_extract:SI
8626               (match_operand 1 "ext_register_operand" "0")
8627               (const_int 8)
8628               (const_int 8))
8629             (match_operand 2 "const_int_operand" "n"))
8630           (const_int 0)))
8631    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8632                          (const_int 8)
8633                          (const_int 8))
8634         (and:SI
8635           (zero_extract:SI
8636             (match_dup 1)
8637             (const_int 8)
8638             (const_int 8))
8639           (match_dup 2)))]
8640   "ix86_match_ccmode (insn, CCNOmode)"
8641   "and{b}\t{%2, %h0|%h0, %2}"
8642   [(set_attr "type" "alu")
8643    (set_attr "length_immediate" "1")
8644    (set_attr "mode" "QI")])
8645
8646 (define_insn "*andqi_ext_1"
8647   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8648                          (const_int 8)
8649                          (const_int 8))
8650         (and:SI
8651           (zero_extract:SI
8652             (match_operand 1 "ext_register_operand" "0")
8653             (const_int 8)
8654             (const_int 8))
8655           (zero_extend:SI
8656             (match_operand:QI 2 "general_operand" "Qm"))))
8657    (clobber (reg:CC FLAGS_REG))]
8658   "!TARGET_64BIT"
8659   "and{b}\t{%2, %h0|%h0, %2}"
8660   [(set_attr "type" "alu")
8661    (set_attr "length_immediate" "0")
8662    (set_attr "mode" "QI")])
8663
8664 (define_insn "*andqi_ext_1_rex64"
8665   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8666                          (const_int 8)
8667                          (const_int 8))
8668         (and:SI
8669           (zero_extract:SI
8670             (match_operand 1 "ext_register_operand" "0")
8671             (const_int 8)
8672             (const_int 8))
8673           (zero_extend:SI
8674             (match_operand 2 "ext_register_operand" "Q"))))
8675    (clobber (reg:CC FLAGS_REG))]
8676   "TARGET_64BIT"
8677   "and{b}\t{%2, %h0|%h0, %2}"
8678   [(set_attr "type" "alu")
8679    (set_attr "length_immediate" "0")
8680    (set_attr "mode" "QI")])
8681
8682 (define_insn "*andqi_ext_2"
8683   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8684                          (const_int 8)
8685                          (const_int 8))
8686         (and:SI
8687           (zero_extract:SI
8688             (match_operand 1 "ext_register_operand" "%0")
8689             (const_int 8)
8690             (const_int 8))
8691           (zero_extract:SI
8692             (match_operand 2 "ext_register_operand" "Q")
8693             (const_int 8)
8694             (const_int 8))))
8695    (clobber (reg:CC FLAGS_REG))]
8696   ""
8697   "and{b}\t{%h2, %h0|%h0, %h2}"
8698   [(set_attr "type" "alu")
8699    (set_attr "length_immediate" "0")
8700    (set_attr "mode" "QI")])
8701
8702 ;; Convert wide AND instructions with immediate operand to shorter QImode
8703 ;; equivalents when possible.
8704 ;; Don't do the splitting with memory operands, since it introduces risk
8705 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8706 ;; for size, but that can (should?) be handled by generic code instead.
8707 (define_split
8708   [(set (match_operand 0 "register_operand" "")
8709         (and (match_operand 1 "register_operand" "")
8710              (match_operand 2 "const_int_operand" "")))
8711    (clobber (reg:CC FLAGS_REG))]
8712    "reload_completed
8713     && QI_REG_P (operands[0])
8714     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8715     && !(~INTVAL (operands[2]) & ~(255 << 8))
8716     && GET_MODE (operands[0]) != QImode"
8717   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8718                    (and:SI (zero_extract:SI (match_dup 1)
8719                                             (const_int 8) (const_int 8))
8720                            (match_dup 2)))
8721               (clobber (reg:CC FLAGS_REG))])]
8722   "operands[0] = gen_lowpart (SImode, operands[0]);
8723    operands[1] = gen_lowpart (SImode, operands[1]);
8724    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8725
8726 ;; Since AND can be encoded with sign extended immediate, this is only
8727 ;; profitable when 7th bit is not set.
8728 (define_split
8729   [(set (match_operand 0 "register_operand" "")
8730         (and (match_operand 1 "general_operand" "")
8731              (match_operand 2 "const_int_operand" "")))
8732    (clobber (reg:CC FLAGS_REG))]
8733    "reload_completed
8734     && ANY_QI_REG_P (operands[0])
8735     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8736     && !(~INTVAL (operands[2]) & ~255)
8737     && !(INTVAL (operands[2]) & 128)
8738     && GET_MODE (operands[0]) != QImode"
8739   [(parallel [(set (strict_low_part (match_dup 0))
8740                    (and:QI (match_dup 1)
8741                            (match_dup 2)))
8742               (clobber (reg:CC FLAGS_REG))])]
8743   "operands[0] = gen_lowpart (QImode, operands[0]);
8744    operands[1] = gen_lowpart (QImode, operands[1]);
8745    operands[2] = gen_lowpart (QImode, operands[2]);")
8746 \f
8747 ;; Logical inclusive OR instructions
8748
8749 ;; %%% This used to optimize known byte-wide and operations to memory.
8750 ;; If this is considered useful, it should be done with splitters.
8751
8752 (define_expand "iordi3"
8753   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8754         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8755                 (match_operand:DI 2 "x86_64_general_operand" "")))
8756    (clobber (reg:CC FLAGS_REG))]
8757   "TARGET_64BIT"
8758   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8759
8760 (define_insn "*iordi_1_rex64"
8761   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8762         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8763                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8764    (clobber (reg:CC FLAGS_REG))]
8765   "TARGET_64BIT
8766    && ix86_binary_operator_ok (IOR, DImode, operands)"
8767   "or{q}\t{%2, %0|%0, %2}"
8768   [(set_attr "type" "alu")
8769    (set_attr "mode" "DI")])
8770
8771 (define_insn "*iordi_2_rex64"
8772   [(set (reg FLAGS_REG)
8773         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8774                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8775                  (const_int 0)))
8776    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8777         (ior:DI (match_dup 1) (match_dup 2)))]
8778   "TARGET_64BIT
8779    && ix86_match_ccmode (insn, CCNOmode)
8780    && ix86_binary_operator_ok (IOR, DImode, operands)"
8781   "or{q}\t{%2, %0|%0, %2}"
8782   [(set_attr "type" "alu")
8783    (set_attr "mode" "DI")])
8784
8785 (define_insn "*iordi_3_rex64"
8786   [(set (reg FLAGS_REG)
8787         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8788                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8789                  (const_int 0)))
8790    (clobber (match_scratch:DI 0 "=r"))]
8791   "TARGET_64BIT
8792    && ix86_match_ccmode (insn, CCNOmode)
8793    && ix86_binary_operator_ok (IOR, DImode, operands)"
8794   "or{q}\t{%2, %0|%0, %2}"
8795   [(set_attr "type" "alu")
8796    (set_attr "mode" "DI")])
8797
8798
8799 (define_expand "iorsi3"
8800   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8801         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8802                 (match_operand:SI 2 "general_operand" "")))
8803    (clobber (reg:CC FLAGS_REG))]
8804   ""
8805   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8806
8807 (define_insn "*iorsi_1"
8808   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8809         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8810                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8811    (clobber (reg:CC FLAGS_REG))]
8812   "ix86_binary_operator_ok (IOR, SImode, operands)"
8813   "or{l}\t{%2, %0|%0, %2}"
8814   [(set_attr "type" "alu")
8815    (set_attr "mode" "SI")])
8816
8817 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8818 (define_insn "*iorsi_1_zext"
8819   [(set (match_operand:DI 0 "register_operand" "=rm")
8820         (zero_extend:DI
8821           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8822                   (match_operand:SI 2 "general_operand" "rim"))))
8823    (clobber (reg:CC FLAGS_REG))]
8824   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8825   "or{l}\t{%2, %k0|%k0, %2}"
8826   [(set_attr "type" "alu")
8827    (set_attr "mode" "SI")])
8828
8829 (define_insn "*iorsi_1_zext_imm"
8830   [(set (match_operand:DI 0 "register_operand" "=rm")
8831         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8832                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8833    (clobber (reg:CC FLAGS_REG))]
8834   "TARGET_64BIT"
8835   "or{l}\t{%2, %k0|%k0, %2}"
8836   [(set_attr "type" "alu")
8837    (set_attr "mode" "SI")])
8838
8839 (define_insn "*iorsi_2"
8840   [(set (reg FLAGS_REG)
8841         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8842                          (match_operand:SI 2 "general_operand" "rim,ri"))
8843                  (const_int 0)))
8844    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8845         (ior:SI (match_dup 1) (match_dup 2)))]
8846   "ix86_match_ccmode (insn, CCNOmode)
8847    && ix86_binary_operator_ok (IOR, SImode, operands)"
8848   "or{l}\t{%2, %0|%0, %2}"
8849   [(set_attr "type" "alu")
8850    (set_attr "mode" "SI")])
8851
8852 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8853 ;; ??? Special case for immediate operand is missing - it is tricky.
8854 (define_insn "*iorsi_2_zext"
8855   [(set (reg FLAGS_REG)
8856         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8857                          (match_operand:SI 2 "general_operand" "rim"))
8858                  (const_int 0)))
8859    (set (match_operand:DI 0 "register_operand" "=r")
8860         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8861   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8862    && ix86_binary_operator_ok (IOR, SImode, operands)"
8863   "or{l}\t{%2, %k0|%k0, %2}"
8864   [(set_attr "type" "alu")
8865    (set_attr "mode" "SI")])
8866
8867 (define_insn "*iorsi_2_zext_imm"
8868   [(set (reg FLAGS_REG)
8869         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8870                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8871                  (const_int 0)))
8872    (set (match_operand:DI 0 "register_operand" "=r")
8873         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8874   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8875    && ix86_binary_operator_ok (IOR, SImode, operands)"
8876   "or{l}\t{%2, %k0|%k0, %2}"
8877   [(set_attr "type" "alu")
8878    (set_attr "mode" "SI")])
8879
8880 (define_insn "*iorsi_3"
8881   [(set (reg FLAGS_REG)
8882         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8883                          (match_operand:SI 2 "general_operand" "rim"))
8884                  (const_int 0)))
8885    (clobber (match_scratch:SI 0 "=r"))]
8886   "ix86_match_ccmode (insn, CCNOmode)
8887    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8888   "or{l}\t{%2, %0|%0, %2}"
8889   [(set_attr "type" "alu")
8890    (set_attr "mode" "SI")])
8891
8892 (define_expand "iorhi3"
8893   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8894         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8895                 (match_operand:HI 2 "general_operand" "")))
8896    (clobber (reg:CC FLAGS_REG))]
8897   "TARGET_HIMODE_MATH"
8898   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8899
8900 (define_insn "*iorhi_1"
8901   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8902         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8903                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8904    (clobber (reg:CC FLAGS_REG))]
8905   "ix86_binary_operator_ok (IOR, HImode, operands)"
8906   "or{w}\t{%2, %0|%0, %2}"
8907   [(set_attr "type" "alu")
8908    (set_attr "mode" "HI")])
8909
8910 (define_insn "*iorhi_2"
8911   [(set (reg FLAGS_REG)
8912         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8913                          (match_operand:HI 2 "general_operand" "rim,ri"))
8914                  (const_int 0)))
8915    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8916         (ior:HI (match_dup 1) (match_dup 2)))]
8917   "ix86_match_ccmode (insn, CCNOmode)
8918    && ix86_binary_operator_ok (IOR, HImode, operands)"
8919   "or{w}\t{%2, %0|%0, %2}"
8920   [(set_attr "type" "alu")
8921    (set_attr "mode" "HI")])
8922
8923 (define_insn "*iorhi_3"
8924   [(set (reg FLAGS_REG)
8925         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8926                          (match_operand:HI 2 "general_operand" "rim"))
8927                  (const_int 0)))
8928    (clobber (match_scratch:HI 0 "=r"))]
8929   "ix86_match_ccmode (insn, CCNOmode)
8930    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8931   "or{w}\t{%2, %0|%0, %2}"
8932   [(set_attr "type" "alu")
8933    (set_attr "mode" "HI")])
8934
8935 (define_expand "iorqi3"
8936   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8937         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8938                 (match_operand:QI 2 "general_operand" "")))
8939    (clobber (reg:CC FLAGS_REG))]
8940   "TARGET_QIMODE_MATH"
8941   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8942
8943 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8944 (define_insn "*iorqi_1"
8945   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8946         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8947                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8948    (clobber (reg:CC FLAGS_REG))]
8949   "ix86_binary_operator_ok (IOR, QImode, operands)"
8950   "@
8951    or{b}\t{%2, %0|%0, %2}
8952    or{b}\t{%2, %0|%0, %2}
8953    or{l}\t{%k2, %k0|%k0, %k2}"
8954   [(set_attr "type" "alu")
8955    (set_attr "mode" "QI,QI,SI")])
8956
8957 (define_insn "*iorqi_1_slp"
8958   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8959         (ior:QI (match_dup 0)
8960                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8961    (clobber (reg:CC FLAGS_REG))]
8962   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8963    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8964   "or{b}\t{%1, %0|%0, %1}"
8965   [(set_attr "type" "alu1")
8966    (set_attr "mode" "QI")])
8967
8968 (define_insn "*iorqi_2"
8969   [(set (reg FLAGS_REG)
8970         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8971                          (match_operand:QI 2 "general_operand" "qim,qi"))
8972                  (const_int 0)))
8973    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8974         (ior:QI (match_dup 1) (match_dup 2)))]
8975   "ix86_match_ccmode (insn, CCNOmode)
8976    && ix86_binary_operator_ok (IOR, QImode, operands)"
8977   "or{b}\t{%2, %0|%0, %2}"
8978   [(set_attr "type" "alu")
8979    (set_attr "mode" "QI")])
8980
8981 (define_insn "*iorqi_2_slp"
8982   [(set (reg FLAGS_REG)
8983         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8984                          (match_operand:QI 1 "general_operand" "qim,qi"))
8985                  (const_int 0)))
8986    (set (strict_low_part (match_dup 0))
8987         (ior:QI (match_dup 0) (match_dup 1)))]
8988   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8989    && ix86_match_ccmode (insn, CCNOmode)
8990    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8991   "or{b}\t{%1, %0|%0, %1}"
8992   [(set_attr "type" "alu1")
8993    (set_attr "mode" "QI")])
8994
8995 (define_insn "*iorqi_3"
8996   [(set (reg FLAGS_REG)
8997         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8998                          (match_operand:QI 2 "general_operand" "qim"))
8999                  (const_int 0)))
9000    (clobber (match_scratch:QI 0 "=q"))]
9001   "ix86_match_ccmode (insn, CCNOmode)
9002    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9003   "or{b}\t{%2, %0|%0, %2}"
9004   [(set_attr "type" "alu")
9005    (set_attr "mode" "QI")])
9006
9007 (define_insn "iorqi_ext_0"
9008   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9009                          (const_int 8)
9010                          (const_int 8))
9011         (ior:SI
9012           (zero_extract:SI
9013             (match_operand 1 "ext_register_operand" "0")
9014             (const_int 8)
9015             (const_int 8))
9016           (match_operand 2 "const_int_operand" "n")))
9017    (clobber (reg:CC FLAGS_REG))]
9018   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9019   "or{b}\t{%2, %h0|%h0, %2}"
9020   [(set_attr "type" "alu")
9021    (set_attr "length_immediate" "1")
9022    (set_attr "mode" "QI")])
9023
9024 (define_insn "*iorqi_ext_1"
9025   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9026                          (const_int 8)
9027                          (const_int 8))
9028         (ior:SI
9029           (zero_extract:SI
9030             (match_operand 1 "ext_register_operand" "0")
9031             (const_int 8)
9032             (const_int 8))
9033           (zero_extend:SI
9034             (match_operand:QI 2 "general_operand" "Qm"))))
9035    (clobber (reg:CC FLAGS_REG))]
9036   "!TARGET_64BIT
9037    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9038   "or{b}\t{%2, %h0|%h0, %2}"
9039   [(set_attr "type" "alu")
9040    (set_attr "length_immediate" "0")
9041    (set_attr "mode" "QI")])
9042
9043 (define_insn "*iorqi_ext_1_rex64"
9044   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9045                          (const_int 8)
9046                          (const_int 8))
9047         (ior:SI
9048           (zero_extract:SI
9049             (match_operand 1 "ext_register_operand" "0")
9050             (const_int 8)
9051             (const_int 8))
9052           (zero_extend:SI
9053             (match_operand 2 "ext_register_operand" "Q"))))
9054    (clobber (reg:CC FLAGS_REG))]
9055   "TARGET_64BIT
9056    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9057   "or{b}\t{%2, %h0|%h0, %2}"
9058   [(set_attr "type" "alu")
9059    (set_attr "length_immediate" "0")
9060    (set_attr "mode" "QI")])
9061
9062 (define_insn "*iorqi_ext_2"
9063   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9064                          (const_int 8)
9065                          (const_int 8))
9066         (ior:SI
9067           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9068                            (const_int 8)
9069                            (const_int 8))
9070           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9071                            (const_int 8)
9072                            (const_int 8))))
9073    (clobber (reg:CC FLAGS_REG))]
9074   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9075   "ior{b}\t{%h2, %h0|%h0, %h2}"
9076   [(set_attr "type" "alu")
9077    (set_attr "length_immediate" "0")
9078    (set_attr "mode" "QI")])
9079
9080 (define_split
9081   [(set (match_operand 0 "register_operand" "")
9082         (ior (match_operand 1 "register_operand" "")
9083              (match_operand 2 "const_int_operand" "")))
9084    (clobber (reg:CC FLAGS_REG))]
9085    "reload_completed
9086     && QI_REG_P (operands[0])
9087     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9088     && !(INTVAL (operands[2]) & ~(255 << 8))
9089     && GET_MODE (operands[0]) != QImode"
9090   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9091                    (ior:SI (zero_extract:SI (match_dup 1)
9092                                             (const_int 8) (const_int 8))
9093                            (match_dup 2)))
9094               (clobber (reg:CC FLAGS_REG))])]
9095   "operands[0] = gen_lowpart (SImode, operands[0]);
9096    operands[1] = gen_lowpart (SImode, operands[1]);
9097    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9098
9099 ;; Since OR can be encoded with sign extended immediate, this is only
9100 ;; profitable when 7th bit is set.
9101 (define_split
9102   [(set (match_operand 0 "register_operand" "")
9103         (ior (match_operand 1 "general_operand" "")
9104              (match_operand 2 "const_int_operand" "")))
9105    (clobber (reg:CC FLAGS_REG))]
9106    "reload_completed
9107     && ANY_QI_REG_P (operands[0])
9108     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9109     && !(INTVAL (operands[2]) & ~255)
9110     && (INTVAL (operands[2]) & 128)
9111     && GET_MODE (operands[0]) != QImode"
9112   [(parallel [(set (strict_low_part (match_dup 0))
9113                    (ior:QI (match_dup 1)
9114                            (match_dup 2)))
9115               (clobber (reg:CC FLAGS_REG))])]
9116   "operands[0] = gen_lowpart (QImode, operands[0]);
9117    operands[1] = gen_lowpart (QImode, operands[1]);
9118    operands[2] = gen_lowpart (QImode, operands[2]);")
9119 \f
9120 ;; Logical XOR instructions
9121
9122 ;; %%% This used to optimize known byte-wide and operations to memory.
9123 ;; If this is considered useful, it should be done with splitters.
9124
9125 (define_expand "xordi3"
9126   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9127         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9128                 (match_operand:DI 2 "x86_64_general_operand" "")))
9129    (clobber (reg:CC FLAGS_REG))]
9130   "TARGET_64BIT"
9131   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9132
9133 (define_insn "*xordi_1_rex64"
9134   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9135         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9136                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9137    (clobber (reg:CC FLAGS_REG))]
9138   "TARGET_64BIT
9139    && ix86_binary_operator_ok (XOR, DImode, operands)"
9140   "@
9141    xor{q}\t{%2, %0|%0, %2}
9142    xor{q}\t{%2, %0|%0, %2}"
9143   [(set_attr "type" "alu")
9144    (set_attr "mode" "DI,DI")])
9145
9146 (define_insn "*xordi_2_rex64"
9147   [(set (reg FLAGS_REG)
9148         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9149                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9150                  (const_int 0)))
9151    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9152         (xor:DI (match_dup 1) (match_dup 2)))]
9153   "TARGET_64BIT
9154    && ix86_match_ccmode (insn, CCNOmode)
9155    && ix86_binary_operator_ok (XOR, DImode, operands)"
9156   "@
9157    xor{q}\t{%2, %0|%0, %2}
9158    xor{q}\t{%2, %0|%0, %2}"
9159   [(set_attr "type" "alu")
9160    (set_attr "mode" "DI,DI")])
9161
9162 (define_insn "*xordi_3_rex64"
9163   [(set (reg FLAGS_REG)
9164         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9165                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9166                  (const_int 0)))
9167    (clobber (match_scratch:DI 0 "=r"))]
9168   "TARGET_64BIT
9169    && ix86_match_ccmode (insn, CCNOmode)
9170    && ix86_binary_operator_ok (XOR, DImode, operands)"
9171   "xor{q}\t{%2, %0|%0, %2}"
9172   [(set_attr "type" "alu")
9173    (set_attr "mode" "DI")])
9174
9175 (define_expand "xorsi3"
9176   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9177         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9178                 (match_operand:SI 2 "general_operand" "")))
9179    (clobber (reg:CC FLAGS_REG))]
9180   ""
9181   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9182
9183 (define_insn "*xorsi_1"
9184   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9185         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9186                 (match_operand:SI 2 "general_operand" "ri,rm")))
9187    (clobber (reg:CC FLAGS_REG))]
9188   "ix86_binary_operator_ok (XOR, SImode, operands)"
9189   "xor{l}\t{%2, %0|%0, %2}"
9190   [(set_attr "type" "alu")
9191    (set_attr "mode" "SI")])
9192
9193 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9194 ;; Add speccase for immediates
9195 (define_insn "*xorsi_1_zext"
9196   [(set (match_operand:DI 0 "register_operand" "=r")
9197         (zero_extend:DI
9198           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9199                   (match_operand:SI 2 "general_operand" "rim"))))
9200    (clobber (reg:CC FLAGS_REG))]
9201   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9202   "xor{l}\t{%2, %k0|%k0, %2}"
9203   [(set_attr "type" "alu")
9204    (set_attr "mode" "SI")])
9205
9206 (define_insn "*xorsi_1_zext_imm"
9207   [(set (match_operand:DI 0 "register_operand" "=r")
9208         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9209                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9210    (clobber (reg:CC FLAGS_REG))]
9211   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9212   "xor{l}\t{%2, %k0|%k0, %2}"
9213   [(set_attr "type" "alu")
9214    (set_attr "mode" "SI")])
9215
9216 (define_insn "*xorsi_2"
9217   [(set (reg FLAGS_REG)
9218         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9219                          (match_operand:SI 2 "general_operand" "rim,ri"))
9220                  (const_int 0)))
9221    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9222         (xor:SI (match_dup 1) (match_dup 2)))]
9223   "ix86_match_ccmode (insn, CCNOmode)
9224    && ix86_binary_operator_ok (XOR, SImode, operands)"
9225   "xor{l}\t{%2, %0|%0, %2}"
9226   [(set_attr "type" "alu")
9227    (set_attr "mode" "SI")])
9228
9229 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9230 ;; ??? Special case for immediate operand is missing - it is tricky.
9231 (define_insn "*xorsi_2_zext"
9232   [(set (reg FLAGS_REG)
9233         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9234                          (match_operand:SI 2 "general_operand" "rim"))
9235                  (const_int 0)))
9236    (set (match_operand:DI 0 "register_operand" "=r")
9237         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9238   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9239    && ix86_binary_operator_ok (XOR, SImode, operands)"
9240   "xor{l}\t{%2, %k0|%k0, %2}"
9241   [(set_attr "type" "alu")
9242    (set_attr "mode" "SI")])
9243
9244 (define_insn "*xorsi_2_zext_imm"
9245   [(set (reg FLAGS_REG)
9246         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9247                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9248                  (const_int 0)))
9249    (set (match_operand:DI 0 "register_operand" "=r")
9250         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9251   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9252    && ix86_binary_operator_ok (XOR, SImode, operands)"
9253   "xor{l}\t{%2, %k0|%k0, %2}"
9254   [(set_attr "type" "alu")
9255    (set_attr "mode" "SI")])
9256
9257 (define_insn "*xorsi_3"
9258   [(set (reg FLAGS_REG)
9259         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9260                          (match_operand:SI 2 "general_operand" "rim"))
9261                  (const_int 0)))
9262    (clobber (match_scratch:SI 0 "=r"))]
9263   "ix86_match_ccmode (insn, CCNOmode)
9264    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9265   "xor{l}\t{%2, %0|%0, %2}"
9266   [(set_attr "type" "alu")
9267    (set_attr "mode" "SI")])
9268
9269 (define_expand "xorhi3"
9270   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9271         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9272                 (match_operand:HI 2 "general_operand" "")))
9273    (clobber (reg:CC FLAGS_REG))]
9274   "TARGET_HIMODE_MATH"
9275   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9276
9277 (define_insn "*xorhi_1"
9278   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9279         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9280                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9281    (clobber (reg:CC FLAGS_REG))]
9282   "ix86_binary_operator_ok (XOR, HImode, operands)"
9283   "xor{w}\t{%2, %0|%0, %2}"
9284   [(set_attr "type" "alu")
9285    (set_attr "mode" "HI")])
9286
9287 (define_insn "*xorhi_2"
9288   [(set (reg FLAGS_REG)
9289         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9290                          (match_operand:HI 2 "general_operand" "rim,ri"))
9291                  (const_int 0)))
9292    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9293         (xor:HI (match_dup 1) (match_dup 2)))]
9294   "ix86_match_ccmode (insn, CCNOmode)
9295    && ix86_binary_operator_ok (XOR, HImode, operands)"
9296   "xor{w}\t{%2, %0|%0, %2}"
9297   [(set_attr "type" "alu")
9298    (set_attr "mode" "HI")])
9299
9300 (define_insn "*xorhi_3"
9301   [(set (reg FLAGS_REG)
9302         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9303                          (match_operand:HI 2 "general_operand" "rim"))
9304                  (const_int 0)))
9305    (clobber (match_scratch:HI 0 "=r"))]
9306   "ix86_match_ccmode (insn, CCNOmode)
9307    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9308   "xor{w}\t{%2, %0|%0, %2}"
9309   [(set_attr "type" "alu")
9310    (set_attr "mode" "HI")])
9311
9312 (define_expand "xorqi3"
9313   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9314         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9315                 (match_operand:QI 2 "general_operand" "")))
9316    (clobber (reg:CC FLAGS_REG))]
9317   "TARGET_QIMODE_MATH"
9318   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9319
9320 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9321 (define_insn "*xorqi_1"
9322   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9323         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9324                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9325    (clobber (reg:CC FLAGS_REG))]
9326   "ix86_binary_operator_ok (XOR, QImode, operands)"
9327   "@
9328    xor{b}\t{%2, %0|%0, %2}
9329    xor{b}\t{%2, %0|%0, %2}
9330    xor{l}\t{%k2, %k0|%k0, %k2}"
9331   [(set_attr "type" "alu")
9332    (set_attr "mode" "QI,QI,SI")])
9333
9334 (define_insn "*xorqi_1_slp"
9335   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9336         (xor:QI (match_dup 0)
9337                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9338    (clobber (reg:CC FLAGS_REG))]
9339   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9340    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9341   "xor{b}\t{%1, %0|%0, %1}"
9342   [(set_attr "type" "alu1")
9343    (set_attr "mode" "QI")])
9344
9345 (define_insn "xorqi_ext_0"
9346   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9347                          (const_int 8)
9348                          (const_int 8))
9349         (xor:SI
9350           (zero_extract:SI
9351             (match_operand 1 "ext_register_operand" "0")
9352             (const_int 8)
9353             (const_int 8))
9354           (match_operand 2 "const_int_operand" "n")))
9355    (clobber (reg:CC FLAGS_REG))]
9356   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9357   "xor{b}\t{%2, %h0|%h0, %2}"
9358   [(set_attr "type" "alu")
9359    (set_attr "length_immediate" "1")
9360    (set_attr "mode" "QI")])
9361
9362 (define_insn "*xorqi_ext_1"
9363   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9364                          (const_int 8)
9365                          (const_int 8))
9366         (xor:SI
9367           (zero_extract:SI
9368             (match_operand 1 "ext_register_operand" "0")
9369             (const_int 8)
9370             (const_int 8))
9371           (zero_extend:SI
9372             (match_operand:QI 2 "general_operand" "Qm"))))
9373    (clobber (reg:CC FLAGS_REG))]
9374   "!TARGET_64BIT
9375    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9376   "xor{b}\t{%2, %h0|%h0, %2}"
9377   [(set_attr "type" "alu")
9378    (set_attr "length_immediate" "0")
9379    (set_attr "mode" "QI")])
9380
9381 (define_insn "*xorqi_ext_1_rex64"
9382   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9383                          (const_int 8)
9384                          (const_int 8))
9385         (xor:SI
9386           (zero_extract:SI
9387             (match_operand 1 "ext_register_operand" "0")
9388             (const_int 8)
9389             (const_int 8))
9390           (zero_extend:SI
9391             (match_operand 2 "ext_register_operand" "Q"))))
9392    (clobber (reg:CC FLAGS_REG))]
9393   "TARGET_64BIT
9394    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9395   "xor{b}\t{%2, %h0|%h0, %2}"
9396   [(set_attr "type" "alu")
9397    (set_attr "length_immediate" "0")
9398    (set_attr "mode" "QI")])
9399
9400 (define_insn "*xorqi_ext_2"
9401   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9402                          (const_int 8)
9403                          (const_int 8))
9404         (xor:SI
9405           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9406                            (const_int 8)
9407                            (const_int 8))
9408           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9409                            (const_int 8)
9410                            (const_int 8))))
9411    (clobber (reg:CC FLAGS_REG))]
9412   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9413   "xor{b}\t{%h2, %h0|%h0, %h2}"
9414   [(set_attr "type" "alu")
9415    (set_attr "length_immediate" "0")
9416    (set_attr "mode" "QI")])
9417
9418 (define_insn "*xorqi_cc_1"
9419   [(set (reg FLAGS_REG)
9420         (compare
9421           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9422                   (match_operand:QI 2 "general_operand" "qim,qi"))
9423           (const_int 0)))
9424    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9425         (xor:QI (match_dup 1) (match_dup 2)))]
9426   "ix86_match_ccmode (insn, CCNOmode)
9427    && ix86_binary_operator_ok (XOR, QImode, operands)"
9428   "xor{b}\t{%2, %0|%0, %2}"
9429   [(set_attr "type" "alu")
9430    (set_attr "mode" "QI")])
9431
9432 (define_insn "*xorqi_2_slp"
9433   [(set (reg FLAGS_REG)
9434         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9435                          (match_operand:QI 1 "general_operand" "qim,qi"))
9436                  (const_int 0)))
9437    (set (strict_low_part (match_dup 0))
9438         (xor:QI (match_dup 0) (match_dup 1)))]
9439   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9440    && ix86_match_ccmode (insn, CCNOmode)
9441    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9442   "xor{b}\t{%1, %0|%0, %1}"
9443   [(set_attr "type" "alu1")
9444    (set_attr "mode" "QI")])
9445
9446 (define_insn "*xorqi_cc_2"
9447   [(set (reg FLAGS_REG)
9448         (compare
9449           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9450                   (match_operand:QI 2 "general_operand" "qim"))
9451           (const_int 0)))
9452    (clobber (match_scratch:QI 0 "=q"))]
9453   "ix86_match_ccmode (insn, CCNOmode)
9454    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9455   "xor{b}\t{%2, %0|%0, %2}"
9456   [(set_attr "type" "alu")
9457    (set_attr "mode" "QI")])
9458
9459 (define_insn "*xorqi_cc_ext_1"
9460   [(set (reg FLAGS_REG)
9461         (compare
9462           (xor:SI
9463             (zero_extract:SI
9464               (match_operand 1 "ext_register_operand" "0")
9465               (const_int 8)
9466               (const_int 8))
9467             (match_operand:QI 2 "general_operand" "qmn"))
9468           (const_int 0)))
9469    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9470                          (const_int 8)
9471                          (const_int 8))
9472         (xor:SI
9473           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9474           (match_dup 2)))]
9475   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9476   "xor{b}\t{%2, %h0|%h0, %2}"
9477   [(set_attr "type" "alu")
9478    (set_attr "mode" "QI")])
9479
9480 (define_insn "*xorqi_cc_ext_1_rex64"
9481   [(set (reg FLAGS_REG)
9482         (compare
9483           (xor:SI
9484             (zero_extract:SI
9485               (match_operand 1 "ext_register_operand" "0")
9486               (const_int 8)
9487               (const_int 8))
9488             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9489           (const_int 0)))
9490    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9491                          (const_int 8)
9492                          (const_int 8))
9493         (xor:SI
9494           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9495           (match_dup 2)))]
9496   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9497   "xor{b}\t{%2, %h0|%h0, %2}"
9498   [(set_attr "type" "alu")
9499    (set_attr "mode" "QI")])
9500
9501 (define_expand "xorqi_cc_ext_1"
9502   [(parallel [
9503      (set (reg:CCNO FLAGS_REG)
9504           (compare:CCNO
9505             (xor:SI
9506               (zero_extract:SI
9507                 (match_operand 1 "ext_register_operand" "")
9508                 (const_int 8)
9509                 (const_int 8))
9510               (match_operand:QI 2 "general_operand" ""))
9511             (const_int 0)))
9512      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9513                            (const_int 8)
9514                            (const_int 8))
9515           (xor:SI
9516             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9517             (match_dup 2)))])]
9518   ""
9519   "")
9520
9521 (define_split
9522   [(set (match_operand 0 "register_operand" "")
9523         (xor (match_operand 1 "register_operand" "")
9524              (match_operand 2 "const_int_operand" "")))
9525    (clobber (reg:CC FLAGS_REG))]
9526    "reload_completed
9527     && QI_REG_P (operands[0])
9528     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9529     && !(INTVAL (operands[2]) & ~(255 << 8))
9530     && GET_MODE (operands[0]) != QImode"
9531   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9532                    (xor:SI (zero_extract:SI (match_dup 1)
9533                                             (const_int 8) (const_int 8))
9534                            (match_dup 2)))
9535               (clobber (reg:CC FLAGS_REG))])]
9536   "operands[0] = gen_lowpart (SImode, operands[0]);
9537    operands[1] = gen_lowpart (SImode, operands[1]);
9538    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9539
9540 ;; Since XOR can be encoded with sign extended immediate, this is only
9541 ;; profitable when 7th bit is set.
9542 (define_split
9543   [(set (match_operand 0 "register_operand" "")
9544         (xor (match_operand 1 "general_operand" "")
9545              (match_operand 2 "const_int_operand" "")))
9546    (clobber (reg:CC FLAGS_REG))]
9547    "reload_completed
9548     && ANY_QI_REG_P (operands[0])
9549     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9550     && !(INTVAL (operands[2]) & ~255)
9551     && (INTVAL (operands[2]) & 128)
9552     && GET_MODE (operands[0]) != QImode"
9553   [(parallel [(set (strict_low_part (match_dup 0))
9554                    (xor:QI (match_dup 1)
9555                            (match_dup 2)))
9556               (clobber (reg:CC FLAGS_REG))])]
9557   "operands[0] = gen_lowpart (QImode, operands[0]);
9558    operands[1] = gen_lowpart (QImode, operands[1]);
9559    operands[2] = gen_lowpart (QImode, operands[2]);")
9560 \f
9561 ;; Negation instructions
9562
9563 (define_expand "negti2"
9564   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9565                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9566               (clobber (reg:CC FLAGS_REG))])]
9567   "TARGET_64BIT"
9568   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9569
9570 (define_insn "*negti2_1"
9571   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9572         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
9573    (clobber (reg:CC FLAGS_REG))]
9574   "TARGET_64BIT
9575    && ix86_unary_operator_ok (NEG, TImode, operands)"
9576   "#")
9577
9578 (define_split
9579   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9580         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9581    (clobber (reg:CC FLAGS_REG))]
9582   "TARGET_64BIT && reload_completed"
9583   [(parallel
9584     [(set (reg:CCZ FLAGS_REG)
9585           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9586      (set (match_dup 0) (neg:DI (match_dup 2)))])
9587    (parallel
9588     [(set (match_dup 1)
9589           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9590                             (match_dup 3))
9591                    (const_int 0)))
9592      (clobber (reg:CC FLAGS_REG))])
9593    (parallel
9594     [(set (match_dup 1)
9595           (neg:DI (match_dup 1)))
9596      (clobber (reg:CC FLAGS_REG))])]
9597   "split_ti (operands+1, 1, operands+2, operands+3);
9598    split_ti (operands+0, 1, operands+0, operands+1);")
9599
9600 (define_expand "negdi2"
9601   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9602                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9603               (clobber (reg:CC FLAGS_REG))])]
9604   ""
9605   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9606
9607 (define_insn "*negdi2_1"
9608   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9609         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9610    (clobber (reg:CC FLAGS_REG))]
9611   "!TARGET_64BIT
9612    && ix86_unary_operator_ok (NEG, DImode, operands)"
9613   "#")
9614
9615 (define_split
9616   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9617         (neg:DI (match_operand:DI 1 "general_operand" "")))
9618    (clobber (reg:CC FLAGS_REG))]
9619   "!TARGET_64BIT && reload_completed"
9620   [(parallel
9621     [(set (reg:CCZ FLAGS_REG)
9622           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9623      (set (match_dup 0) (neg:SI (match_dup 2)))])
9624    (parallel
9625     [(set (match_dup 1)
9626           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9627                             (match_dup 3))
9628                    (const_int 0)))
9629      (clobber (reg:CC FLAGS_REG))])
9630    (parallel
9631     [(set (match_dup 1)
9632           (neg:SI (match_dup 1)))
9633      (clobber (reg:CC FLAGS_REG))])]
9634   "split_di (operands+1, 1, operands+2, operands+3);
9635    split_di (operands+0, 1, operands+0, operands+1);")
9636
9637 (define_insn "*negdi2_1_rex64"
9638   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9639         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9640    (clobber (reg:CC FLAGS_REG))]
9641   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9642   "neg{q}\t%0"
9643   [(set_attr "type" "negnot")
9644    (set_attr "mode" "DI")])
9645
9646 ;; The problem with neg is that it does not perform (compare x 0),
9647 ;; it really performs (compare 0 x), which leaves us with the zero
9648 ;; flag being the only useful item.
9649
9650 (define_insn "*negdi2_cmpz_rex64"
9651   [(set (reg:CCZ FLAGS_REG)
9652         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9653                      (const_int 0)))
9654    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9655         (neg:DI (match_dup 1)))]
9656   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9657   "neg{q}\t%0"
9658   [(set_attr "type" "negnot")
9659    (set_attr "mode" "DI")])
9660
9661
9662 (define_expand "negsi2"
9663   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9664                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9665               (clobber (reg:CC FLAGS_REG))])]
9666   ""
9667   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9668
9669 (define_insn "*negsi2_1"
9670   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9671         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9672    (clobber (reg:CC FLAGS_REG))]
9673   "ix86_unary_operator_ok (NEG, SImode, operands)"
9674   "neg{l}\t%0"
9675   [(set_attr "type" "negnot")
9676    (set_attr "mode" "SI")])
9677
9678 ;; Combine is quite creative about this pattern.
9679 (define_insn "*negsi2_1_zext"
9680   [(set (match_operand:DI 0 "register_operand" "=r")
9681         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9682                                         (const_int 32)))
9683                      (const_int 32)))
9684    (clobber (reg:CC FLAGS_REG))]
9685   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9686   "neg{l}\t%k0"
9687   [(set_attr "type" "negnot")
9688    (set_attr "mode" "SI")])
9689
9690 ;; The problem with neg is that it does not perform (compare x 0),
9691 ;; it really performs (compare 0 x), which leaves us with the zero
9692 ;; flag being the only useful item.
9693
9694 (define_insn "*negsi2_cmpz"
9695   [(set (reg:CCZ FLAGS_REG)
9696         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9697                      (const_int 0)))
9698    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9699         (neg:SI (match_dup 1)))]
9700   "ix86_unary_operator_ok (NEG, SImode, operands)"
9701   "neg{l}\t%0"
9702   [(set_attr "type" "negnot")
9703    (set_attr "mode" "SI")])
9704
9705 (define_insn "*negsi2_cmpz_zext"
9706   [(set (reg:CCZ FLAGS_REG)
9707         (compare:CCZ (lshiftrt:DI
9708                        (neg:DI (ashift:DI
9709                                  (match_operand:DI 1 "register_operand" "0")
9710                                  (const_int 32)))
9711                        (const_int 32))
9712                      (const_int 0)))
9713    (set (match_operand:DI 0 "register_operand" "=r")
9714         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9715                                         (const_int 32)))
9716                      (const_int 32)))]
9717   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9718   "neg{l}\t%k0"
9719   [(set_attr "type" "negnot")
9720    (set_attr "mode" "SI")])
9721
9722 (define_expand "neghi2"
9723   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9724                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9725               (clobber (reg:CC FLAGS_REG))])]
9726   "TARGET_HIMODE_MATH"
9727   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9728
9729 (define_insn "*neghi2_1"
9730   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9731         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9732    (clobber (reg:CC FLAGS_REG))]
9733   "ix86_unary_operator_ok (NEG, HImode, operands)"
9734   "neg{w}\t%0"
9735   [(set_attr "type" "negnot")
9736    (set_attr "mode" "HI")])
9737
9738 (define_insn "*neghi2_cmpz"
9739   [(set (reg:CCZ FLAGS_REG)
9740         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9741                      (const_int 0)))
9742    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9743         (neg:HI (match_dup 1)))]
9744   "ix86_unary_operator_ok (NEG, HImode, operands)"
9745   "neg{w}\t%0"
9746   [(set_attr "type" "negnot")
9747    (set_attr "mode" "HI")])
9748
9749 (define_expand "negqi2"
9750   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9751                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9752               (clobber (reg:CC FLAGS_REG))])]
9753   "TARGET_QIMODE_MATH"
9754   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9755
9756 (define_insn "*negqi2_1"
9757   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9758         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9759    (clobber (reg:CC FLAGS_REG))]
9760   "ix86_unary_operator_ok (NEG, QImode, operands)"
9761   "neg{b}\t%0"
9762   [(set_attr "type" "negnot")
9763    (set_attr "mode" "QI")])
9764
9765 (define_insn "*negqi2_cmpz"
9766   [(set (reg:CCZ FLAGS_REG)
9767         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9768                      (const_int 0)))
9769    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9770         (neg:QI (match_dup 1)))]
9771   "ix86_unary_operator_ok (NEG, QImode, operands)"
9772   "neg{b}\t%0"
9773   [(set_attr "type" "negnot")
9774    (set_attr "mode" "QI")])
9775
9776 ;; Changing of sign for FP values is doable using integer unit too.
9777
9778 (define_expand "negsf2"
9779   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9780         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9781   "TARGET_80387 || TARGET_SSE_MATH"
9782   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9783
9784 (define_expand "abssf2"
9785   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9786         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9787   "TARGET_80387 || TARGET_SSE_MATH"
9788   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9789
9790 (define_insn "*absnegsf2_mixed"
9791   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9792         (match_operator:SF 3 "absneg_operator"
9793           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9794    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9795    (clobber (reg:CC FLAGS_REG))]
9796   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9797    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9798   "#")
9799
9800 (define_insn "*absnegsf2_sse"
9801   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9802         (match_operator:SF 3 "absneg_operator"
9803           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9804    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9805    (clobber (reg:CC FLAGS_REG))]
9806   "TARGET_SSE_MATH
9807    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9808   "#")
9809
9810 (define_insn "*absnegsf2_i387"
9811   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9812         (match_operator:SF 3 "absneg_operator"
9813           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9814    (use (match_operand 2 "" ""))
9815    (clobber (reg:CC FLAGS_REG))]
9816   "TARGET_80387 && !TARGET_SSE_MATH
9817    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9818   "#")
9819
9820 (define_expand "copysignsf3"
9821   [(match_operand:SF 0 "register_operand" "")
9822    (match_operand:SF 1 "nonmemory_operand" "")
9823    (match_operand:SF 2 "register_operand" "")]
9824   "TARGET_SSE_MATH"
9825 {
9826   ix86_expand_copysign (operands);
9827   DONE;
9828 })
9829
9830 (define_insn_and_split "copysignsf3_const"
9831   [(set (match_operand:SF 0 "register_operand"          "=x")
9832         (unspec:SF
9833           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9834            (match_operand:SF 2 "register_operand"       "0")
9835            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9836           UNSPEC_COPYSIGN))]
9837   "TARGET_SSE_MATH"
9838   "#"
9839   "&& reload_completed"
9840   [(const_int 0)]
9841 {
9842   ix86_split_copysign_const (operands);
9843   DONE;
9844 })
9845
9846 (define_insn "copysignsf3_var"
9847   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9848         (unspec:SF
9849           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9850            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9851            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9852            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9853           UNSPEC_COPYSIGN))
9854    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9855   "TARGET_SSE_MATH"
9856   "#")
9857
9858 (define_split
9859   [(set (match_operand:SF 0 "register_operand" "")
9860         (unspec:SF
9861           [(match_operand:SF 2 "register_operand" "")
9862            (match_operand:SF 3 "register_operand" "")
9863            (match_operand:V4SF 4 "" "")
9864            (match_operand:V4SF 5 "" "")]
9865           UNSPEC_COPYSIGN))
9866    (clobber (match_scratch:V4SF 1 ""))]
9867   "TARGET_SSE_MATH && reload_completed"
9868   [(const_int 0)]
9869 {
9870   ix86_split_copysign_var (operands);
9871   DONE;
9872 })
9873
9874 (define_expand "negdf2"
9875   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9876         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9877   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9878   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9879
9880 (define_expand "absdf2"
9881   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9882         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9883   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9884   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9885
9886 (define_insn "*absnegdf2_mixed"
9887   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,f,rm")
9888         (match_operator:DF 3 "absneg_operator"
9889           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
9890    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X,X"))
9891    (clobber (reg:CC FLAGS_REG))]
9892   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9893    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9894   "#")
9895
9896 (define_insn "*absnegdf2_sse"
9897   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,rm")
9898         (match_operator:DF 3 "absneg_operator"
9899           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
9900    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X "))
9901    (clobber (reg:CC FLAGS_REG))]
9902   "TARGET_SSE2 && TARGET_SSE_MATH
9903    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9904   "#")
9905
9906 (define_insn "*absnegdf2_i387"
9907   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9908         (match_operator:DF 3 "absneg_operator"
9909           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9910    (use (match_operand 2 "" ""))
9911    (clobber (reg:CC FLAGS_REG))]
9912   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9913    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9914   "#")
9915
9916 (define_expand "copysigndf3"
9917   [(match_operand:DF 0 "register_operand" "")
9918    (match_operand:DF 1 "nonmemory_operand" "")
9919    (match_operand:DF 2 "register_operand" "")]
9920   "TARGET_SSE2 && TARGET_SSE_MATH"
9921 {
9922   ix86_expand_copysign (operands);
9923   DONE;
9924 })
9925
9926 (define_insn_and_split "copysigndf3_const"
9927   [(set (match_operand:DF 0 "register_operand"          "=x")
9928         (unspec:DF
9929           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9930            (match_operand:DF 2 "register_operand"       "0")
9931            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9932           UNSPEC_COPYSIGN))]
9933   "TARGET_SSE2 && TARGET_SSE_MATH"
9934   "#"
9935   "&& reload_completed"
9936   [(const_int 0)]
9937 {
9938   ix86_split_copysign_const (operands);
9939   DONE;
9940 })
9941
9942 (define_insn "copysigndf3_var"
9943   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9944         (unspec:DF
9945           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9946            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9947            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9948            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9949           UNSPEC_COPYSIGN))
9950    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9951   "TARGET_SSE2 && TARGET_SSE_MATH"
9952   "#")
9953
9954 (define_split
9955   [(set (match_operand:DF 0 "register_operand" "")
9956         (unspec:DF
9957           [(match_operand:DF 2 "register_operand" "")
9958            (match_operand:DF 3 "register_operand" "")
9959            (match_operand:V2DF 4 "" "")
9960            (match_operand:V2DF 5 "" "")]
9961           UNSPEC_COPYSIGN))
9962    (clobber (match_scratch:V2DF 1 ""))]
9963   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9964   [(const_int 0)]
9965 {
9966   ix86_split_copysign_var (operands);
9967   DONE;
9968 })
9969
9970 (define_expand "negxf2"
9971   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9972         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9973   "TARGET_80387"
9974   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9975
9976 (define_expand "absxf2"
9977   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9978         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9979   "TARGET_80387"
9980   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9981
9982 (define_insn "*absnegxf2_i387"
9983   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9984         (match_operator:XF 3 "absneg_operator"
9985           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9986    (use (match_operand 2 "" ""))
9987    (clobber (reg:CC FLAGS_REG))]
9988   "TARGET_80387
9989    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9990   "#")
9991
9992 ;; Splitters for fp abs and neg.
9993
9994 (define_split
9995   [(set (match_operand 0 "fp_register_operand" "")
9996         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9997    (use (match_operand 2 "" ""))
9998    (clobber (reg:CC FLAGS_REG))]
9999   "reload_completed"
10000   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10001
10002 (define_split
10003   [(set (match_operand 0 "register_operand" "")
10004         (match_operator 3 "absneg_operator"
10005           [(match_operand 1 "register_operand" "")]))
10006    (use (match_operand 2 "nonimmediate_operand" ""))
10007    (clobber (reg:CC FLAGS_REG))]
10008   "reload_completed && SSE_REG_P (operands[0])"
10009   [(set (match_dup 0) (match_dup 3))]
10010 {
10011   enum machine_mode mode = GET_MODE (operands[0]);
10012   enum machine_mode vmode = GET_MODE (operands[2]);
10013   rtx tmp;
10014
10015   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10016   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10017   if (operands_match_p (operands[0], operands[2]))
10018     {
10019       tmp = operands[1];
10020       operands[1] = operands[2];
10021       operands[2] = tmp;
10022     }
10023   if (GET_CODE (operands[3]) == ABS)
10024     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10025   else
10026     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10027   operands[3] = tmp;
10028 })
10029
10030 (define_split
10031   [(set (match_operand:SF 0 "register_operand" "")
10032         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10033    (use (match_operand:V4SF 2 "" ""))
10034    (clobber (reg:CC FLAGS_REG))]
10035   "reload_completed"
10036   [(parallel [(set (match_dup 0) (match_dup 1))
10037               (clobber (reg:CC FLAGS_REG))])]
10038 {
10039   rtx tmp;
10040   operands[0] = gen_lowpart (SImode, operands[0]);
10041   if (GET_CODE (operands[1]) == ABS)
10042     {
10043       tmp = gen_int_mode (0x7fffffff, SImode);
10044       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10045     }
10046   else
10047     {
10048       tmp = gen_int_mode (0x80000000, SImode);
10049       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10050     }
10051   operands[1] = tmp;
10052 })
10053
10054 (define_split
10055   [(set (match_operand:DF 0 "register_operand" "")
10056         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10057    (use (match_operand 2 "" ""))
10058    (clobber (reg:CC FLAGS_REG))]
10059   "reload_completed"
10060   [(parallel [(set (match_dup 0) (match_dup 1))
10061               (clobber (reg:CC FLAGS_REG))])]
10062 {
10063   rtx tmp;
10064   if (TARGET_64BIT)
10065     {
10066       tmp = gen_lowpart (DImode, operands[0]);
10067       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10068       operands[0] = tmp;
10069
10070       if (GET_CODE (operands[1]) == ABS)
10071         tmp = const0_rtx;
10072       else
10073         tmp = gen_rtx_NOT (DImode, tmp);
10074     }
10075   else
10076     {
10077       operands[0] = gen_highpart (SImode, operands[0]);
10078       if (GET_CODE (operands[1]) == ABS)
10079         {
10080           tmp = gen_int_mode (0x7fffffff, SImode);
10081           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10082         }
10083       else
10084         {
10085           tmp = gen_int_mode (0x80000000, SImode);
10086           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10087         }
10088     }
10089   operands[1] = tmp;
10090 })
10091
10092 (define_split
10093   [(set (match_operand:XF 0 "register_operand" "")
10094         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10095    (use (match_operand 2 "" ""))
10096    (clobber (reg:CC FLAGS_REG))]
10097   "reload_completed"
10098   [(parallel [(set (match_dup 0) (match_dup 1))
10099               (clobber (reg:CC FLAGS_REG))])]
10100 {
10101   rtx tmp;
10102   operands[0] = gen_rtx_REG (SImode,
10103                              true_regnum (operands[0])
10104                              + (TARGET_64BIT ? 1 : 2));
10105   if (GET_CODE (operands[1]) == ABS)
10106     {
10107       tmp = GEN_INT (0x7fff);
10108       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10109     }
10110   else
10111     {
10112       tmp = GEN_INT (0x8000);
10113       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10114     }
10115   operands[1] = tmp;
10116 })
10117
10118 (define_split
10119   [(set (match_operand 0 "memory_operand" "")
10120         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10121    (use (match_operand 2 "" ""))
10122    (clobber (reg:CC FLAGS_REG))]
10123   "reload_completed"
10124   [(parallel [(set (match_dup 0) (match_dup 1))
10125               (clobber (reg:CC FLAGS_REG))])]
10126 {
10127   enum machine_mode mode = GET_MODE (operands[0]);
10128   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
10129   rtx tmp;
10130
10131   operands[0] = adjust_address (operands[0], QImode, size - 1);
10132   if (GET_CODE (operands[1]) == ABS)
10133     {
10134       tmp = gen_int_mode (0x7f, QImode);
10135       tmp = gen_rtx_AND (QImode, operands[0], tmp);
10136     }
10137   else
10138     {
10139       tmp = gen_int_mode (0x80, QImode);
10140       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
10141     }
10142   operands[1] = tmp;
10143 })
10144
10145 ;; Conditionalize these after reload. If they match before reload, we
10146 ;; lose the clobber and ability to use integer instructions.
10147
10148 (define_insn "*negsf2_1"
10149   [(set (match_operand:SF 0 "register_operand" "=f")
10150         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10151   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10152   "fchs"
10153   [(set_attr "type" "fsgn")
10154    (set_attr "mode" "SF")])
10155
10156 (define_insn "*negdf2_1"
10157   [(set (match_operand:DF 0 "register_operand" "=f")
10158         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10159   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10160   "fchs"
10161   [(set_attr "type" "fsgn")
10162    (set_attr "mode" "DF")])
10163
10164 (define_insn "*negxf2_1"
10165   [(set (match_operand:XF 0 "register_operand" "=f")
10166         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10167   "TARGET_80387"
10168   "fchs"
10169   [(set_attr "type" "fsgn")
10170    (set_attr "mode" "XF")])
10171
10172 (define_insn "*abssf2_1"
10173   [(set (match_operand:SF 0 "register_operand" "=f")
10174         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10175   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10176   "fabs"
10177   [(set_attr "type" "fsgn")
10178    (set_attr "mode" "SF")])
10179
10180 (define_insn "*absdf2_1"
10181   [(set (match_operand:DF 0 "register_operand" "=f")
10182         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10183   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10184   "fabs"
10185   [(set_attr "type" "fsgn")
10186    (set_attr "mode" "DF")])
10187
10188 (define_insn "*absxf2_1"
10189   [(set (match_operand:XF 0 "register_operand" "=f")
10190         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10191   "TARGET_80387"
10192   "fabs"
10193   [(set_attr "type" "fsgn")
10194    (set_attr "mode" "DF")])
10195
10196 (define_insn "*negextendsfdf2"
10197   [(set (match_operand:DF 0 "register_operand" "=f")
10198         (neg:DF (float_extend:DF
10199                   (match_operand:SF 1 "register_operand" "0"))))]
10200   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10201   "fchs"
10202   [(set_attr "type" "fsgn")
10203    (set_attr "mode" "DF")])
10204
10205 (define_insn "*negextenddfxf2"
10206   [(set (match_operand:XF 0 "register_operand" "=f")
10207         (neg:XF (float_extend:XF
10208                   (match_operand:DF 1 "register_operand" "0"))))]
10209   "TARGET_80387"
10210   "fchs"
10211   [(set_attr "type" "fsgn")
10212    (set_attr "mode" "XF")])
10213
10214 (define_insn "*negextendsfxf2"
10215   [(set (match_operand:XF 0 "register_operand" "=f")
10216         (neg:XF (float_extend:XF
10217                   (match_operand:SF 1 "register_operand" "0"))))]
10218   "TARGET_80387"
10219   "fchs"
10220   [(set_attr "type" "fsgn")
10221    (set_attr "mode" "XF")])
10222
10223 (define_insn "*absextendsfdf2"
10224   [(set (match_operand:DF 0 "register_operand" "=f")
10225         (abs:DF (float_extend:DF
10226                   (match_operand:SF 1 "register_operand" "0"))))]
10227   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10228   "fabs"
10229   [(set_attr "type" "fsgn")
10230    (set_attr "mode" "DF")])
10231
10232 (define_insn "*absextenddfxf2"
10233   [(set (match_operand:XF 0 "register_operand" "=f")
10234         (abs:XF (float_extend:XF
10235           (match_operand:DF 1 "register_operand" "0"))))]
10236   "TARGET_80387"
10237   "fabs"
10238   [(set_attr "type" "fsgn")
10239    (set_attr "mode" "XF")])
10240
10241 (define_insn "*absextendsfxf2"
10242   [(set (match_operand:XF 0 "register_operand" "=f")
10243         (abs:XF (float_extend:XF
10244           (match_operand:SF 1 "register_operand" "0"))))]
10245   "TARGET_80387"
10246   "fabs"
10247   [(set_attr "type" "fsgn")
10248    (set_attr "mode" "XF")])
10249 \f
10250 ;; One complement instructions
10251
10252 (define_expand "one_cmpldi2"
10253   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10254         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10255   "TARGET_64BIT"
10256   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10257
10258 (define_insn "*one_cmpldi2_1_rex64"
10259   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10260         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10261   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10262   "not{q}\t%0"
10263   [(set_attr "type" "negnot")
10264    (set_attr "mode" "DI")])
10265
10266 (define_insn "*one_cmpldi2_2_rex64"
10267   [(set (reg FLAGS_REG)
10268         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10269                  (const_int 0)))
10270    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10271         (not:DI (match_dup 1)))]
10272   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10273    && ix86_unary_operator_ok (NOT, DImode, operands)"
10274   "#"
10275   [(set_attr "type" "alu1")
10276    (set_attr "mode" "DI")])
10277
10278 (define_split
10279   [(set (match_operand 0 "flags_reg_operand" "")
10280         (match_operator 2 "compare_operator"
10281           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10282            (const_int 0)]))
10283    (set (match_operand:DI 1 "nonimmediate_operand" "")
10284         (not:DI (match_dup 3)))]
10285   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10286   [(parallel [(set (match_dup 0)
10287                    (match_op_dup 2
10288                      [(xor:DI (match_dup 3) (const_int -1))
10289                       (const_int 0)]))
10290               (set (match_dup 1)
10291                    (xor:DI (match_dup 3) (const_int -1)))])]
10292   "")
10293
10294 (define_expand "one_cmplsi2"
10295   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10296         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10297   ""
10298   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10299
10300 (define_insn "*one_cmplsi2_1"
10301   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10302         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10303   "ix86_unary_operator_ok (NOT, SImode, operands)"
10304   "not{l}\t%0"
10305   [(set_attr "type" "negnot")
10306    (set_attr "mode" "SI")])
10307
10308 ;; ??? Currently never generated - xor is used instead.
10309 (define_insn "*one_cmplsi2_1_zext"
10310   [(set (match_operand:DI 0 "register_operand" "=r")
10311         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10312   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10313   "not{l}\t%k0"
10314   [(set_attr "type" "negnot")
10315    (set_attr "mode" "SI")])
10316
10317 (define_insn "*one_cmplsi2_2"
10318   [(set (reg FLAGS_REG)
10319         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10320                  (const_int 0)))
10321    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10322         (not:SI (match_dup 1)))]
10323   "ix86_match_ccmode (insn, CCNOmode)
10324    && ix86_unary_operator_ok (NOT, SImode, operands)"
10325   "#"
10326   [(set_attr "type" "alu1")
10327    (set_attr "mode" "SI")])
10328
10329 (define_split
10330   [(set (match_operand 0 "flags_reg_operand" "")
10331         (match_operator 2 "compare_operator"
10332           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10333            (const_int 0)]))
10334    (set (match_operand:SI 1 "nonimmediate_operand" "")
10335         (not:SI (match_dup 3)))]
10336   "ix86_match_ccmode (insn, CCNOmode)"
10337   [(parallel [(set (match_dup 0)
10338                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10339                                     (const_int 0)]))
10340               (set (match_dup 1)
10341                    (xor:SI (match_dup 3) (const_int -1)))])]
10342   "")
10343
10344 ;; ??? Currently never generated - xor is used instead.
10345 (define_insn "*one_cmplsi2_2_zext"
10346   [(set (reg FLAGS_REG)
10347         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10348                  (const_int 0)))
10349    (set (match_operand:DI 0 "register_operand" "=r")
10350         (zero_extend:DI (not:SI (match_dup 1))))]
10351   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10352    && ix86_unary_operator_ok (NOT, SImode, operands)"
10353   "#"
10354   [(set_attr "type" "alu1")
10355    (set_attr "mode" "SI")])
10356
10357 (define_split
10358   [(set (match_operand 0 "flags_reg_operand" "")
10359         (match_operator 2 "compare_operator"
10360           [(not:SI (match_operand:SI 3 "register_operand" ""))
10361            (const_int 0)]))
10362    (set (match_operand:DI 1 "register_operand" "")
10363         (zero_extend:DI (not:SI (match_dup 3))))]
10364   "ix86_match_ccmode (insn, CCNOmode)"
10365   [(parallel [(set (match_dup 0)
10366                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10367                                     (const_int 0)]))
10368               (set (match_dup 1)
10369                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10370   "")
10371
10372 (define_expand "one_cmplhi2"
10373   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10374         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10375   "TARGET_HIMODE_MATH"
10376   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10377
10378 (define_insn "*one_cmplhi2_1"
10379   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10380         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10381   "ix86_unary_operator_ok (NOT, HImode, operands)"
10382   "not{w}\t%0"
10383   [(set_attr "type" "negnot")
10384    (set_attr "mode" "HI")])
10385
10386 (define_insn "*one_cmplhi2_2"
10387   [(set (reg FLAGS_REG)
10388         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10389                  (const_int 0)))
10390    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10391         (not:HI (match_dup 1)))]
10392   "ix86_match_ccmode (insn, CCNOmode)
10393    && ix86_unary_operator_ok (NEG, HImode, operands)"
10394   "#"
10395   [(set_attr "type" "alu1")
10396    (set_attr "mode" "HI")])
10397
10398 (define_split
10399   [(set (match_operand 0 "flags_reg_operand" "")
10400         (match_operator 2 "compare_operator"
10401           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10402            (const_int 0)]))
10403    (set (match_operand:HI 1 "nonimmediate_operand" "")
10404         (not:HI (match_dup 3)))]
10405   "ix86_match_ccmode (insn, CCNOmode)"
10406   [(parallel [(set (match_dup 0)
10407                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10408                                     (const_int 0)]))
10409               (set (match_dup 1)
10410                    (xor:HI (match_dup 3) (const_int -1)))])]
10411   "")
10412
10413 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10414 (define_expand "one_cmplqi2"
10415   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10416         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10417   "TARGET_QIMODE_MATH"
10418   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10419
10420 (define_insn "*one_cmplqi2_1"
10421   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10422         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10423   "ix86_unary_operator_ok (NOT, QImode, operands)"
10424   "@
10425    not{b}\t%0
10426    not{l}\t%k0"
10427   [(set_attr "type" "negnot")
10428    (set_attr "mode" "QI,SI")])
10429
10430 (define_insn "*one_cmplqi2_2"
10431   [(set (reg FLAGS_REG)
10432         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10433                  (const_int 0)))
10434    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10435         (not:QI (match_dup 1)))]
10436   "ix86_match_ccmode (insn, CCNOmode)
10437    && ix86_unary_operator_ok (NOT, QImode, operands)"
10438   "#"
10439   [(set_attr "type" "alu1")
10440    (set_attr "mode" "QI")])
10441
10442 (define_split
10443   [(set (match_operand 0 "flags_reg_operand" "")
10444         (match_operator 2 "compare_operator"
10445           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10446            (const_int 0)]))
10447    (set (match_operand:QI 1 "nonimmediate_operand" "")
10448         (not:QI (match_dup 3)))]
10449   "ix86_match_ccmode (insn, CCNOmode)"
10450   [(parallel [(set (match_dup 0)
10451                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10452                                     (const_int 0)]))
10453               (set (match_dup 1)
10454                    (xor:QI (match_dup 3) (const_int -1)))])]
10455   "")
10456 \f
10457 ;; Arithmetic shift instructions
10458
10459 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10460 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10461 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10462 ;; from the assembler input.
10463 ;;
10464 ;; This instruction shifts the target reg/mem as usual, but instead of
10465 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10466 ;; is a left shift double, bits are taken from the high order bits of
10467 ;; reg, else if the insn is a shift right double, bits are taken from the
10468 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10469 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10470 ;;
10471 ;; Since sh[lr]d does not change the `reg' operand, that is done
10472 ;; separately, making all shifts emit pairs of shift double and normal
10473 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10474 ;; support a 63 bit shift, each shift where the count is in a reg expands
10475 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10476 ;;
10477 ;; If the shift count is a constant, we need never emit more than one
10478 ;; shift pair, instead using moves and sign extension for counts greater
10479 ;; than 31.
10480
10481 (define_expand "ashlti3"
10482   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10483                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10484                               (match_operand:QI 2 "nonmemory_operand" "")))
10485               (clobber (reg:CC FLAGS_REG))])]
10486   "TARGET_64BIT"
10487 {
10488   if (! immediate_operand (operands[2], QImode))
10489     {
10490       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10491       DONE;
10492     }
10493   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10494   DONE;
10495 })
10496
10497 (define_insn "ashlti3_1"
10498   [(set (match_operand:TI 0 "register_operand" "=r")
10499         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10500                    (match_operand:QI 2 "register_operand" "c")))
10501    (clobber (match_scratch:DI 3 "=&r"))
10502    (clobber (reg:CC FLAGS_REG))]
10503   "TARGET_64BIT"
10504   "#"
10505   [(set_attr "type" "multi")])
10506
10507 (define_insn "*ashlti3_2"
10508   [(set (match_operand:TI 0 "register_operand" "=r")
10509         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10510                    (match_operand:QI 2 "immediate_operand" "O")))
10511    (clobber (reg:CC FLAGS_REG))]
10512   "TARGET_64BIT"
10513   "#"
10514   [(set_attr "type" "multi")])
10515
10516 (define_split
10517   [(set (match_operand:TI 0 "register_operand" "")
10518         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10519                    (match_operand:QI 2 "register_operand" "")))
10520    (clobber (match_scratch:DI 3 ""))
10521    (clobber (reg:CC FLAGS_REG))]
10522   "TARGET_64BIT && reload_completed"
10523   [(const_int 0)]
10524   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10525
10526 (define_split
10527   [(set (match_operand:TI 0 "register_operand" "")
10528         (ashift:TI (match_operand:TI 1 "register_operand" "")
10529                    (match_operand:QI 2 "immediate_operand" "")))
10530    (clobber (reg:CC FLAGS_REG))]
10531   "TARGET_64BIT && reload_completed"
10532   [(const_int 0)]
10533   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10534
10535 (define_insn "x86_64_shld"
10536   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10537         (ior:DI (ashift:DI (match_dup 0)
10538                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10539                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10540                   (minus:QI (const_int 64) (match_dup 2)))))
10541    (clobber (reg:CC FLAGS_REG))]
10542   "TARGET_64BIT"
10543   "@
10544    shld{q}\t{%2, %1, %0|%0, %1, %2}
10545    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10546   [(set_attr "type" "ishift")
10547    (set_attr "prefix_0f" "1")
10548    (set_attr "mode" "DI")
10549    (set_attr "athlon_decode" "vector")
10550    (set_attr "amdfam10_decode" "vector")])   
10551
10552 (define_expand "x86_64_shift_adj"
10553   [(set (reg:CCZ FLAGS_REG)
10554         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10555                              (const_int 64))
10556                      (const_int 0)))
10557    (set (match_operand:DI 0 "register_operand" "")
10558         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10559                          (match_operand:DI 1 "register_operand" "")
10560                          (match_dup 0)))
10561    (set (match_dup 1)
10562         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10563                          (match_operand:DI 3 "register_operand" "r")
10564                          (match_dup 1)))]
10565   "TARGET_64BIT"
10566   "")
10567
10568 (define_expand "ashldi3"
10569   [(set (match_operand:DI 0 "shiftdi_operand" "")
10570         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10571                    (match_operand:QI 2 "nonmemory_operand" "")))]
10572   ""
10573   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10574
10575 (define_insn "*ashldi3_1_rex64"
10576   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10577         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10578                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10579    (clobber (reg:CC FLAGS_REG))]
10580   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10581 {
10582   switch (get_attr_type (insn))
10583     {
10584     case TYPE_ALU:
10585       gcc_assert (operands[2] == const1_rtx);
10586       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10587       return "add{q}\t%0, %0";
10588
10589     case TYPE_LEA:
10590       gcc_assert (CONST_INT_P (operands[2]));
10591       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10592       operands[1] = gen_rtx_MULT (DImode, operands[1],
10593                                   GEN_INT (1 << INTVAL (operands[2])));
10594       return "lea{q}\t{%a1, %0|%0, %a1}";
10595
10596     default:
10597       if (REG_P (operands[2]))
10598         return "sal{q}\t{%b2, %0|%0, %b2}";
10599       else if (operands[2] == const1_rtx
10600                && (TARGET_SHIFT1 || optimize_size))
10601         return "sal{q}\t%0";
10602       else
10603         return "sal{q}\t{%2, %0|%0, %2}";
10604     }
10605 }
10606   [(set (attr "type")
10607      (cond [(eq_attr "alternative" "1")
10608               (const_string "lea")
10609             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10610                           (const_int 0))
10611                       (match_operand 0 "register_operand" ""))
10612                  (match_operand 2 "const1_operand" ""))
10613               (const_string "alu")
10614            ]
10615            (const_string "ishift")))
10616    (set_attr "mode" "DI")])
10617
10618 ;; Convert lea to the lea pattern to avoid flags dependency.
10619 (define_split
10620   [(set (match_operand:DI 0 "register_operand" "")
10621         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10622                    (match_operand:QI 2 "immediate_operand" "")))
10623    (clobber (reg:CC FLAGS_REG))]
10624   "TARGET_64BIT && reload_completed
10625    && true_regnum (operands[0]) != true_regnum (operands[1])"
10626   [(set (match_dup 0)
10627         (mult:DI (match_dup 1)
10628                  (match_dup 2)))]
10629   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10630
10631 ;; This pattern can't accept a variable shift count, since shifts by
10632 ;; zero don't affect the flags.  We assume that shifts by constant
10633 ;; zero are optimized away.
10634 (define_insn "*ashldi3_cmp_rex64"
10635   [(set (reg FLAGS_REG)
10636         (compare
10637           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10638                      (match_operand:QI 2 "immediate_operand" "e"))
10639           (const_int 0)))
10640    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10641         (ashift:DI (match_dup 1) (match_dup 2)))]
10642   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10643    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10644    && (optimize_size
10645        || !TARGET_PARTIAL_FLAG_REG_STALL
10646        || (operands[2] == const1_rtx
10647            && (TARGET_SHIFT1
10648                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10649 {
10650   switch (get_attr_type (insn))
10651     {
10652     case TYPE_ALU:
10653       gcc_assert (operands[2] == const1_rtx);
10654       return "add{q}\t%0, %0";
10655
10656     default:
10657       if (REG_P (operands[2]))
10658         return "sal{q}\t{%b2, %0|%0, %b2}";
10659       else if (operands[2] == const1_rtx
10660                && (TARGET_SHIFT1 || optimize_size))
10661         return "sal{q}\t%0";
10662       else
10663         return "sal{q}\t{%2, %0|%0, %2}";
10664     }
10665 }
10666   [(set (attr "type")
10667      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10668                           (const_int 0))
10669                       (match_operand 0 "register_operand" ""))
10670                  (match_operand 2 "const1_operand" ""))
10671               (const_string "alu")
10672            ]
10673            (const_string "ishift")))
10674    (set_attr "mode" "DI")])
10675
10676 (define_insn "*ashldi3_cconly_rex64"
10677   [(set (reg FLAGS_REG)
10678         (compare
10679           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10680                      (match_operand:QI 2 "immediate_operand" "e"))
10681           (const_int 0)))
10682    (clobber (match_scratch:DI 0 "=r"))]
10683   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10684    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10685    && (optimize_size
10686        || !TARGET_PARTIAL_FLAG_REG_STALL
10687        || (operands[2] == const1_rtx
10688            && (TARGET_SHIFT1
10689                || TARGET_DOUBLE_WITH_ADD)))"
10690 {
10691   switch (get_attr_type (insn))
10692     {
10693     case TYPE_ALU:
10694       gcc_assert (operands[2] == const1_rtx);
10695       return "add{q}\t%0, %0";
10696
10697     default:
10698       if (REG_P (operands[2]))
10699         return "sal{q}\t{%b2, %0|%0, %b2}";
10700       else if (operands[2] == const1_rtx
10701                && (TARGET_SHIFT1 || optimize_size))
10702         return "sal{q}\t%0";
10703       else
10704         return "sal{q}\t{%2, %0|%0, %2}";
10705     }
10706 }
10707   [(set (attr "type")
10708      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10709                           (const_int 0))
10710                       (match_operand 0 "register_operand" ""))
10711                  (match_operand 2 "const1_operand" ""))
10712               (const_string "alu")
10713            ]
10714            (const_string "ishift")))
10715    (set_attr "mode" "DI")])
10716
10717 (define_insn "*ashldi3_1"
10718   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10719         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10720                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10721    (clobber (reg:CC FLAGS_REG))]
10722   "!TARGET_64BIT"
10723   "#"
10724   [(set_attr "type" "multi")])
10725
10726 ;; By default we don't ask for a scratch register, because when DImode
10727 ;; values are manipulated, registers are already at a premium.  But if
10728 ;; we have one handy, we won't turn it away.
10729 (define_peephole2
10730   [(match_scratch:SI 3 "r")
10731    (parallel [(set (match_operand:DI 0 "register_operand" "")
10732                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10733                               (match_operand:QI 2 "nonmemory_operand" "")))
10734               (clobber (reg:CC FLAGS_REG))])
10735    (match_dup 3)]
10736   "!TARGET_64BIT && TARGET_CMOVE"
10737   [(const_int 0)]
10738   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10739
10740 (define_split
10741   [(set (match_operand:DI 0 "register_operand" "")
10742         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10743                    (match_operand:QI 2 "nonmemory_operand" "")))
10744    (clobber (reg:CC FLAGS_REG))]
10745   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10746                      ? flow2_completed : reload_completed)"
10747   [(const_int 0)]
10748   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10749
10750 (define_insn "x86_shld_1"
10751   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10752         (ior:SI (ashift:SI (match_dup 0)
10753                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10754                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10755                   (minus:QI (const_int 32) (match_dup 2)))))
10756    (clobber (reg:CC FLAGS_REG))]
10757   ""
10758   "@
10759    shld{l}\t{%2, %1, %0|%0, %1, %2}
10760    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10761   [(set_attr "type" "ishift")
10762    (set_attr "prefix_0f" "1")
10763    (set_attr "mode" "SI")
10764    (set_attr "pent_pair" "np")
10765    (set_attr "athlon_decode" "vector")
10766    (set_attr "amdfam10_decode" "vector")])   
10767
10768 (define_expand "x86_shift_adj_1"
10769   [(set (reg:CCZ FLAGS_REG)
10770         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10771                              (const_int 32))
10772                      (const_int 0)))
10773    (set (match_operand:SI 0 "register_operand" "")
10774         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10775                          (match_operand:SI 1 "register_operand" "")
10776                          (match_dup 0)))
10777    (set (match_dup 1)
10778         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10779                          (match_operand:SI 3 "register_operand" "r")
10780                          (match_dup 1)))]
10781   "TARGET_CMOVE"
10782   "")
10783
10784 (define_expand "x86_shift_adj_2"
10785   [(use (match_operand:SI 0 "register_operand" ""))
10786    (use (match_operand:SI 1 "register_operand" ""))
10787    (use (match_operand:QI 2 "register_operand" ""))]
10788   ""
10789 {
10790   rtx label = gen_label_rtx ();
10791   rtx tmp;
10792
10793   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10794
10795   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10796   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10797   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10798                               gen_rtx_LABEL_REF (VOIDmode, label),
10799                               pc_rtx);
10800   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10801   JUMP_LABEL (tmp) = label;
10802
10803   emit_move_insn (operands[0], operands[1]);
10804   ix86_expand_clear (operands[1]);
10805
10806   emit_label (label);
10807   LABEL_NUSES (label) = 1;
10808
10809   DONE;
10810 })
10811
10812 (define_expand "ashlsi3"
10813   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10814         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10815                    (match_operand:QI 2 "nonmemory_operand" "")))
10816    (clobber (reg:CC FLAGS_REG))]
10817   ""
10818   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10819
10820 (define_insn "*ashlsi3_1"
10821   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10822         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10823                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10824    (clobber (reg:CC FLAGS_REG))]
10825   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10826 {
10827   switch (get_attr_type (insn))
10828     {
10829     case TYPE_ALU:
10830       gcc_assert (operands[2] == const1_rtx);
10831       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10832       return "add{l}\t%0, %0";
10833
10834     case TYPE_LEA:
10835       return "#";
10836
10837     default:
10838       if (REG_P (operands[2]))
10839         return "sal{l}\t{%b2, %0|%0, %b2}";
10840       else if (operands[2] == const1_rtx
10841                && (TARGET_SHIFT1 || optimize_size))
10842         return "sal{l}\t%0";
10843       else
10844         return "sal{l}\t{%2, %0|%0, %2}";
10845     }
10846 }
10847   [(set (attr "type")
10848      (cond [(eq_attr "alternative" "1")
10849               (const_string "lea")
10850             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10851                           (const_int 0))
10852                       (match_operand 0 "register_operand" ""))
10853                  (match_operand 2 "const1_operand" ""))
10854               (const_string "alu")
10855            ]
10856            (const_string "ishift")))
10857    (set_attr "mode" "SI")])
10858
10859 ;; Convert lea to the lea pattern to avoid flags dependency.
10860 (define_split
10861   [(set (match_operand 0 "register_operand" "")
10862         (ashift (match_operand 1 "index_register_operand" "")
10863                 (match_operand:QI 2 "const_int_operand" "")))
10864    (clobber (reg:CC FLAGS_REG))]
10865   "reload_completed
10866    && true_regnum (operands[0]) != true_regnum (operands[1])
10867    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10868   [(const_int 0)]
10869 {
10870   rtx pat;
10871   enum machine_mode mode = GET_MODE (operands[0]);
10872
10873   if (GET_MODE_SIZE (mode) < 4)
10874     operands[0] = gen_lowpart (SImode, operands[0]);
10875   if (mode != Pmode)
10876     operands[1] = gen_lowpart (Pmode, operands[1]);
10877   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10878
10879   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10880   if (Pmode != SImode)
10881     pat = gen_rtx_SUBREG (SImode, pat, 0);
10882   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10883   DONE;
10884 })
10885
10886 ;; Rare case of shifting RSP is handled by generating move and shift
10887 (define_split
10888   [(set (match_operand 0 "register_operand" "")
10889         (ashift (match_operand 1 "register_operand" "")
10890                 (match_operand:QI 2 "const_int_operand" "")))
10891    (clobber (reg:CC FLAGS_REG))]
10892   "reload_completed
10893    && true_regnum (operands[0]) != true_regnum (operands[1])"
10894   [(const_int 0)]
10895 {
10896   rtx pat, clob;
10897   emit_move_insn (operands[0], operands[1]);
10898   pat = gen_rtx_SET (VOIDmode, operands[0],
10899                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10900                                      operands[0], operands[2]));
10901   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10902   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10903   DONE;
10904 })
10905
10906 (define_insn "*ashlsi3_1_zext"
10907   [(set (match_operand:DI 0 "register_operand" "=r,r")
10908         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10909                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10910    (clobber (reg:CC FLAGS_REG))]
10911   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10912 {
10913   switch (get_attr_type (insn))
10914     {
10915     case TYPE_ALU:
10916       gcc_assert (operands[2] == const1_rtx);
10917       return "add{l}\t%k0, %k0";
10918
10919     case TYPE_LEA:
10920       return "#";
10921
10922     default:
10923       if (REG_P (operands[2]))
10924         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10925       else if (operands[2] == const1_rtx
10926                && (TARGET_SHIFT1 || optimize_size))
10927         return "sal{l}\t%k0";
10928       else
10929         return "sal{l}\t{%2, %k0|%k0, %2}";
10930     }
10931 }
10932   [(set (attr "type")
10933      (cond [(eq_attr "alternative" "1")
10934               (const_string "lea")
10935             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10936                      (const_int 0))
10937                  (match_operand 2 "const1_operand" ""))
10938               (const_string "alu")
10939            ]
10940            (const_string "ishift")))
10941    (set_attr "mode" "SI")])
10942
10943 ;; Convert lea to the lea pattern to avoid flags dependency.
10944 (define_split
10945   [(set (match_operand:DI 0 "register_operand" "")
10946         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10947                                 (match_operand:QI 2 "const_int_operand" ""))))
10948    (clobber (reg:CC FLAGS_REG))]
10949   "TARGET_64BIT && reload_completed
10950    && true_regnum (operands[0]) != true_regnum (operands[1])"
10951   [(set (match_dup 0) (zero_extend:DI
10952                         (subreg:SI (mult:SI (match_dup 1)
10953                                             (match_dup 2)) 0)))]
10954 {
10955   operands[1] = gen_lowpart (Pmode, operands[1]);
10956   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10957 })
10958
10959 ;; This pattern can't accept a variable shift count, since shifts by
10960 ;; zero don't affect the flags.  We assume that shifts by constant
10961 ;; zero are optimized away.
10962 (define_insn "*ashlsi3_cmp"
10963   [(set (reg FLAGS_REG)
10964         (compare
10965           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10966                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10967           (const_int 0)))
10968    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10969         (ashift:SI (match_dup 1) (match_dup 2)))]
10970   "ix86_match_ccmode (insn, CCGOCmode)
10971    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10972    && (optimize_size
10973        || !TARGET_PARTIAL_FLAG_REG_STALL
10974        || (operands[2] == const1_rtx
10975            && (TARGET_SHIFT1
10976                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10977 {
10978   switch (get_attr_type (insn))
10979     {
10980     case TYPE_ALU:
10981       gcc_assert (operands[2] == const1_rtx);
10982       return "add{l}\t%0, %0";
10983
10984     default:
10985       if (REG_P (operands[2]))
10986         return "sal{l}\t{%b2, %0|%0, %b2}";
10987       else if (operands[2] == const1_rtx
10988                && (TARGET_SHIFT1 || optimize_size))
10989         return "sal{l}\t%0";
10990       else
10991         return "sal{l}\t{%2, %0|%0, %2}";
10992     }
10993 }
10994   [(set (attr "type")
10995      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10996                           (const_int 0))
10997                       (match_operand 0 "register_operand" ""))
10998                  (match_operand 2 "const1_operand" ""))
10999               (const_string "alu")
11000            ]
11001            (const_string "ishift")))
11002    (set_attr "mode" "SI")])
11003
11004 (define_insn "*ashlsi3_cconly"
11005   [(set (reg FLAGS_REG)
11006         (compare
11007           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11008                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11009           (const_int 0)))
11010    (clobber (match_scratch:SI 0 "=r"))]
11011   "ix86_match_ccmode (insn, CCGOCmode)
11012    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11013    && (optimize_size
11014        || !TARGET_PARTIAL_FLAG_REG_STALL
11015        || (operands[2] == const1_rtx
11016            && (TARGET_SHIFT1
11017                || TARGET_DOUBLE_WITH_ADD)))"
11018 {
11019   switch (get_attr_type (insn))
11020     {
11021     case TYPE_ALU:
11022       gcc_assert (operands[2] == const1_rtx);
11023       return "add{l}\t%0, %0";
11024
11025     default:
11026       if (REG_P (operands[2]))
11027         return "sal{l}\t{%b2, %0|%0, %b2}";
11028       else if (operands[2] == const1_rtx
11029                && (TARGET_SHIFT1 || optimize_size))
11030         return "sal{l}\t%0";
11031       else
11032         return "sal{l}\t{%2, %0|%0, %2}";
11033     }
11034 }
11035   [(set (attr "type")
11036      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11037                           (const_int 0))
11038                       (match_operand 0 "register_operand" ""))
11039                  (match_operand 2 "const1_operand" ""))
11040               (const_string "alu")
11041            ]
11042            (const_string "ishift")))
11043    (set_attr "mode" "SI")])
11044
11045 (define_insn "*ashlsi3_cmp_zext"
11046   [(set (reg FLAGS_REG)
11047         (compare
11048           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11049                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11050           (const_int 0)))
11051    (set (match_operand:DI 0 "register_operand" "=r")
11052         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11053   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11054    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11055    && (optimize_size
11056        || !TARGET_PARTIAL_FLAG_REG_STALL
11057        || (operands[2] == const1_rtx
11058            && (TARGET_SHIFT1
11059                || TARGET_DOUBLE_WITH_ADD)))"
11060 {
11061   switch (get_attr_type (insn))
11062     {
11063     case TYPE_ALU:
11064       gcc_assert (operands[2] == const1_rtx);
11065       return "add{l}\t%k0, %k0";
11066
11067     default:
11068       if (REG_P (operands[2]))
11069         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11070       else if (operands[2] == const1_rtx
11071                && (TARGET_SHIFT1 || optimize_size))
11072         return "sal{l}\t%k0";
11073       else
11074         return "sal{l}\t{%2, %k0|%k0, %2}";
11075     }
11076 }
11077   [(set (attr "type")
11078      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11079                      (const_int 0))
11080                  (match_operand 2 "const1_operand" ""))
11081               (const_string "alu")
11082            ]
11083            (const_string "ishift")))
11084    (set_attr "mode" "SI")])
11085
11086 (define_expand "ashlhi3"
11087   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11088         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11089                    (match_operand:QI 2 "nonmemory_operand" "")))
11090    (clobber (reg:CC FLAGS_REG))]
11091   "TARGET_HIMODE_MATH"
11092   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11093
11094 (define_insn "*ashlhi3_1_lea"
11095   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11096         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11097                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11098    (clobber (reg:CC FLAGS_REG))]
11099   "!TARGET_PARTIAL_REG_STALL
11100    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11101 {
11102   switch (get_attr_type (insn))
11103     {
11104     case TYPE_LEA:
11105       return "#";
11106     case TYPE_ALU:
11107       gcc_assert (operands[2] == const1_rtx);
11108       return "add{w}\t%0, %0";
11109
11110     default:
11111       if (REG_P (operands[2]))
11112         return "sal{w}\t{%b2, %0|%0, %b2}";
11113       else if (operands[2] == const1_rtx
11114                && (TARGET_SHIFT1 || optimize_size))
11115         return "sal{w}\t%0";
11116       else
11117         return "sal{w}\t{%2, %0|%0, %2}";
11118     }
11119 }
11120   [(set (attr "type")
11121      (cond [(eq_attr "alternative" "1")
11122               (const_string "lea")
11123             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11124                           (const_int 0))
11125                       (match_operand 0 "register_operand" ""))
11126                  (match_operand 2 "const1_operand" ""))
11127               (const_string "alu")
11128            ]
11129            (const_string "ishift")))
11130    (set_attr "mode" "HI,SI")])
11131
11132 (define_insn "*ashlhi3_1"
11133   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11134         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11135                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11136    (clobber (reg:CC FLAGS_REG))]
11137   "TARGET_PARTIAL_REG_STALL
11138    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11139 {
11140   switch (get_attr_type (insn))
11141     {
11142     case TYPE_ALU:
11143       gcc_assert (operands[2] == const1_rtx);
11144       return "add{w}\t%0, %0";
11145
11146     default:
11147       if (REG_P (operands[2]))
11148         return "sal{w}\t{%b2, %0|%0, %b2}";
11149       else if (operands[2] == const1_rtx
11150                && (TARGET_SHIFT1 || optimize_size))
11151         return "sal{w}\t%0";
11152       else
11153         return "sal{w}\t{%2, %0|%0, %2}";
11154     }
11155 }
11156   [(set (attr "type")
11157      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11158                           (const_int 0))
11159                       (match_operand 0 "register_operand" ""))
11160                  (match_operand 2 "const1_operand" ""))
11161               (const_string "alu")
11162            ]
11163            (const_string "ishift")))
11164    (set_attr "mode" "HI")])
11165
11166 ;; This pattern can't accept a variable shift count, since shifts by
11167 ;; zero don't affect the flags.  We assume that shifts by constant
11168 ;; zero are optimized away.
11169 (define_insn "*ashlhi3_cmp"
11170   [(set (reg FLAGS_REG)
11171         (compare
11172           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11173                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11174           (const_int 0)))
11175    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11176         (ashift:HI (match_dup 1) (match_dup 2)))]
11177   "ix86_match_ccmode (insn, CCGOCmode)
11178    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11179    && (optimize_size
11180        || !TARGET_PARTIAL_FLAG_REG_STALL
11181        || (operands[2] == const1_rtx
11182            && (TARGET_SHIFT1
11183                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11184 {
11185   switch (get_attr_type (insn))
11186     {
11187     case TYPE_ALU:
11188       gcc_assert (operands[2] == const1_rtx);
11189       return "add{w}\t%0, %0";
11190
11191     default:
11192       if (REG_P (operands[2]))
11193         return "sal{w}\t{%b2, %0|%0, %b2}";
11194       else if (operands[2] == const1_rtx
11195                && (TARGET_SHIFT1 || optimize_size))
11196         return "sal{w}\t%0";
11197       else
11198         return "sal{w}\t{%2, %0|%0, %2}";
11199     }
11200 }
11201   [(set (attr "type")
11202      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11203                           (const_int 0))
11204                       (match_operand 0 "register_operand" ""))
11205                  (match_operand 2 "const1_operand" ""))
11206               (const_string "alu")
11207            ]
11208            (const_string "ishift")))
11209    (set_attr "mode" "HI")])
11210
11211 (define_insn "*ashlhi3_cconly"
11212   [(set (reg FLAGS_REG)
11213         (compare
11214           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11215                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11216           (const_int 0)))
11217    (clobber (match_scratch:HI 0 "=r"))]
11218   "ix86_match_ccmode (insn, CCGOCmode)
11219    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11220    && (optimize_size
11221        || !TARGET_PARTIAL_FLAG_REG_STALL
11222        || (operands[2] == const1_rtx
11223            && (TARGET_SHIFT1
11224                || TARGET_DOUBLE_WITH_ADD)))"
11225 {
11226   switch (get_attr_type (insn))
11227     {
11228     case TYPE_ALU:
11229       gcc_assert (operands[2] == const1_rtx);
11230       return "add{w}\t%0, %0";
11231
11232     default:
11233       if (REG_P (operands[2]))
11234         return "sal{w}\t{%b2, %0|%0, %b2}";
11235       else if (operands[2] == const1_rtx
11236                && (TARGET_SHIFT1 || optimize_size))
11237         return "sal{w}\t%0";
11238       else
11239         return "sal{w}\t{%2, %0|%0, %2}";
11240     }
11241 }
11242   [(set (attr "type")
11243      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11244                           (const_int 0))
11245                       (match_operand 0 "register_operand" ""))
11246                  (match_operand 2 "const1_operand" ""))
11247               (const_string "alu")
11248            ]
11249            (const_string "ishift")))
11250    (set_attr "mode" "HI")])
11251
11252 (define_expand "ashlqi3"
11253   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11254         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11255                    (match_operand:QI 2 "nonmemory_operand" "")))
11256    (clobber (reg:CC FLAGS_REG))]
11257   "TARGET_QIMODE_MATH"
11258   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11259
11260 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11261
11262 (define_insn "*ashlqi3_1_lea"
11263   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11264         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11265                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11266    (clobber (reg:CC FLAGS_REG))]
11267   "!TARGET_PARTIAL_REG_STALL
11268    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11269 {
11270   switch (get_attr_type (insn))
11271     {
11272     case TYPE_LEA:
11273       return "#";
11274     case TYPE_ALU:
11275       gcc_assert (operands[2] == const1_rtx);
11276       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11277         return "add{l}\t%k0, %k0";
11278       else
11279         return "add{b}\t%0, %0";
11280
11281     default:
11282       if (REG_P (operands[2]))
11283         {
11284           if (get_attr_mode (insn) == MODE_SI)
11285             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11286           else
11287             return "sal{b}\t{%b2, %0|%0, %b2}";
11288         }
11289       else if (operands[2] == const1_rtx
11290                && (TARGET_SHIFT1 || optimize_size))
11291         {
11292           if (get_attr_mode (insn) == MODE_SI)
11293             return "sal{l}\t%0";
11294           else
11295             return "sal{b}\t%0";
11296         }
11297       else
11298         {
11299           if (get_attr_mode (insn) == MODE_SI)
11300             return "sal{l}\t{%2, %k0|%k0, %2}";
11301           else
11302             return "sal{b}\t{%2, %0|%0, %2}";
11303         }
11304     }
11305 }
11306   [(set (attr "type")
11307      (cond [(eq_attr "alternative" "2")
11308               (const_string "lea")
11309             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11310                           (const_int 0))
11311                       (match_operand 0 "register_operand" ""))
11312                  (match_operand 2 "const1_operand" ""))
11313               (const_string "alu")
11314            ]
11315            (const_string "ishift")))
11316    (set_attr "mode" "QI,SI,SI")])
11317
11318 (define_insn "*ashlqi3_1"
11319   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11320         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11321                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11322    (clobber (reg:CC FLAGS_REG))]
11323   "TARGET_PARTIAL_REG_STALL
11324    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11325 {
11326   switch (get_attr_type (insn))
11327     {
11328     case TYPE_ALU:
11329       gcc_assert (operands[2] == const1_rtx);
11330       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11331         return "add{l}\t%k0, %k0";
11332       else
11333         return "add{b}\t%0, %0";
11334
11335     default:
11336       if (REG_P (operands[2]))
11337         {
11338           if (get_attr_mode (insn) == MODE_SI)
11339             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11340           else
11341             return "sal{b}\t{%b2, %0|%0, %b2}";
11342         }
11343       else if (operands[2] == const1_rtx
11344                && (TARGET_SHIFT1 || optimize_size))
11345         {
11346           if (get_attr_mode (insn) == MODE_SI)
11347             return "sal{l}\t%0";
11348           else
11349             return "sal{b}\t%0";
11350         }
11351       else
11352         {
11353           if (get_attr_mode (insn) == MODE_SI)
11354             return "sal{l}\t{%2, %k0|%k0, %2}";
11355           else
11356             return "sal{b}\t{%2, %0|%0, %2}";
11357         }
11358     }
11359 }
11360   [(set (attr "type")
11361      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11362                           (const_int 0))
11363                       (match_operand 0 "register_operand" ""))
11364                  (match_operand 2 "const1_operand" ""))
11365               (const_string "alu")
11366            ]
11367            (const_string "ishift")))
11368    (set_attr "mode" "QI,SI")])
11369
11370 ;; This pattern can't accept a variable shift count, since shifts by
11371 ;; zero don't affect the flags.  We assume that shifts by constant
11372 ;; zero are optimized away.
11373 (define_insn "*ashlqi3_cmp"
11374   [(set (reg FLAGS_REG)
11375         (compare
11376           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11377                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11378           (const_int 0)))
11379    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11380         (ashift:QI (match_dup 1) (match_dup 2)))]
11381   "ix86_match_ccmode (insn, CCGOCmode)
11382    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11383    && (optimize_size
11384        || !TARGET_PARTIAL_FLAG_REG_STALL
11385        || (operands[2] == const1_rtx
11386            && (TARGET_SHIFT1
11387                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11388 {
11389   switch (get_attr_type (insn))
11390     {
11391     case TYPE_ALU:
11392       gcc_assert (operands[2] == const1_rtx);
11393       return "add{b}\t%0, %0";
11394
11395     default:
11396       if (REG_P (operands[2]))
11397         return "sal{b}\t{%b2, %0|%0, %b2}";
11398       else if (operands[2] == const1_rtx
11399                && (TARGET_SHIFT1 || optimize_size))
11400         return "sal{b}\t%0";
11401       else
11402         return "sal{b}\t{%2, %0|%0, %2}";
11403     }
11404 }
11405   [(set (attr "type")
11406      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11407                           (const_int 0))
11408                       (match_operand 0 "register_operand" ""))
11409                  (match_operand 2 "const1_operand" ""))
11410               (const_string "alu")
11411            ]
11412            (const_string "ishift")))
11413    (set_attr "mode" "QI")])
11414
11415 (define_insn "*ashlqi3_cconly"
11416   [(set (reg FLAGS_REG)
11417         (compare
11418           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11419                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11420           (const_int 0)))
11421    (clobber (match_scratch:QI 0 "=q"))]
11422   "ix86_match_ccmode (insn, CCGOCmode)
11423    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11424    && (optimize_size
11425        || !TARGET_PARTIAL_FLAG_REG_STALL
11426        || (operands[2] == const1_rtx
11427            && (TARGET_SHIFT1
11428                || TARGET_DOUBLE_WITH_ADD)))"
11429 {
11430   switch (get_attr_type (insn))
11431     {
11432     case TYPE_ALU:
11433       gcc_assert (operands[2] == const1_rtx);
11434       return "add{b}\t%0, %0";
11435
11436     default:
11437       if (REG_P (operands[2]))
11438         return "sal{b}\t{%b2, %0|%0, %b2}";
11439       else if (operands[2] == const1_rtx
11440                && (TARGET_SHIFT1 || optimize_size))
11441         return "sal{b}\t%0";
11442       else
11443         return "sal{b}\t{%2, %0|%0, %2}";
11444     }
11445 }
11446   [(set (attr "type")
11447      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11448                           (const_int 0))
11449                       (match_operand 0 "register_operand" ""))
11450                  (match_operand 2 "const1_operand" ""))
11451               (const_string "alu")
11452            ]
11453            (const_string "ishift")))
11454    (set_attr "mode" "QI")])
11455
11456 ;; See comment above `ashldi3' about how this works.
11457
11458 (define_expand "ashrti3"
11459   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11460                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11461                                 (match_operand:QI 2 "nonmemory_operand" "")))
11462               (clobber (reg:CC FLAGS_REG))])]
11463   "TARGET_64BIT"
11464 {
11465   if (! immediate_operand (operands[2], QImode))
11466     {
11467       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11468       DONE;
11469     }
11470   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11471   DONE;
11472 })
11473
11474 (define_insn "ashrti3_1"
11475   [(set (match_operand:TI 0 "register_operand" "=r")
11476         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11477                      (match_operand:QI 2 "register_operand" "c")))
11478    (clobber (match_scratch:DI 3 "=&r"))
11479    (clobber (reg:CC FLAGS_REG))]
11480   "TARGET_64BIT"
11481   "#"
11482   [(set_attr "type" "multi")])
11483
11484 (define_insn "*ashrti3_2"
11485   [(set (match_operand:TI 0 "register_operand" "=r")
11486         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11487                      (match_operand:QI 2 "immediate_operand" "O")))
11488    (clobber (reg:CC FLAGS_REG))]
11489   "TARGET_64BIT"
11490   "#"
11491   [(set_attr "type" "multi")])
11492
11493 (define_split
11494   [(set (match_operand:TI 0 "register_operand" "")
11495         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11496                      (match_operand:QI 2 "register_operand" "")))
11497    (clobber (match_scratch:DI 3 ""))
11498    (clobber (reg:CC FLAGS_REG))]
11499   "TARGET_64BIT && reload_completed"
11500   [(const_int 0)]
11501   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11502
11503 (define_split
11504   [(set (match_operand:TI 0 "register_operand" "")
11505         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11506                      (match_operand:QI 2 "immediate_operand" "")))
11507    (clobber (reg:CC FLAGS_REG))]
11508   "TARGET_64BIT && reload_completed"
11509   [(const_int 0)]
11510   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11511
11512 (define_insn "x86_64_shrd"
11513   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11514         (ior:DI (ashiftrt:DI (match_dup 0)
11515                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11516                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11517                   (minus:QI (const_int 64) (match_dup 2)))))
11518    (clobber (reg:CC FLAGS_REG))]
11519   "TARGET_64BIT"
11520   "@
11521    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11522    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11523   [(set_attr "type" "ishift")
11524    (set_attr "prefix_0f" "1")
11525    (set_attr "mode" "DI")
11526    (set_attr "athlon_decode" "vector")
11527    (set_attr "amdfam10_decode" "vector")])   
11528
11529 (define_expand "ashrdi3"
11530   [(set (match_operand:DI 0 "shiftdi_operand" "")
11531         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11532                      (match_operand:QI 2 "nonmemory_operand" "")))]
11533   ""
11534   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11535
11536 (define_insn "*ashrdi3_63_rex64"
11537   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11538         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11539                      (match_operand:DI 2 "const_int_operand" "i,i")))
11540    (clobber (reg:CC FLAGS_REG))]
11541   "TARGET_64BIT && INTVAL (operands[2]) == 63
11542    && (TARGET_USE_CLTD || optimize_size)
11543    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11544   "@
11545    {cqto|cqo}
11546    sar{q}\t{%2, %0|%0, %2}"
11547   [(set_attr "type" "imovx,ishift")
11548    (set_attr "prefix_0f" "0,*")
11549    (set_attr "length_immediate" "0,*")
11550    (set_attr "modrm" "0,1")
11551    (set_attr "mode" "DI")])
11552
11553 (define_insn "*ashrdi3_1_one_bit_rex64"
11554   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11555         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11556                      (match_operand:QI 2 "const1_operand" "")))
11557    (clobber (reg:CC FLAGS_REG))]
11558   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11559    && (TARGET_SHIFT1 || optimize_size)"
11560   "sar{q}\t%0"
11561   [(set_attr "type" "ishift")
11562    (set (attr "length")
11563      (if_then_else (match_operand:DI 0 "register_operand" "")
11564         (const_string "2")
11565         (const_string "*")))])
11566
11567 (define_insn "*ashrdi3_1_rex64"
11568   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11569         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11570                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11571    (clobber (reg:CC FLAGS_REG))]
11572   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11573   "@
11574    sar{q}\t{%2, %0|%0, %2}
11575    sar{q}\t{%b2, %0|%0, %b2}"
11576   [(set_attr "type" "ishift")
11577    (set_attr "mode" "DI")])
11578
11579 ;; This pattern can't accept a variable shift count, since shifts by
11580 ;; zero don't affect the flags.  We assume that shifts by constant
11581 ;; zero are optimized away.
11582 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11583   [(set (reg FLAGS_REG)
11584         (compare
11585           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11586                        (match_operand:QI 2 "const1_operand" ""))
11587           (const_int 0)))
11588    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11589         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11590   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11591    && (TARGET_SHIFT1 || optimize_size)
11592    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11593   "sar{q}\t%0"
11594   [(set_attr "type" "ishift")
11595    (set (attr "length")
11596      (if_then_else (match_operand:DI 0 "register_operand" "")
11597         (const_string "2")
11598         (const_string "*")))])
11599
11600 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11601   [(set (reg FLAGS_REG)
11602         (compare
11603           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11604                        (match_operand:QI 2 "const1_operand" ""))
11605           (const_int 0)))
11606    (clobber (match_scratch:DI 0 "=r"))]
11607   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11608    && (TARGET_SHIFT1 || optimize_size)
11609    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11610   "sar{q}\t%0"
11611   [(set_attr "type" "ishift")
11612    (set_attr "length" "2")])
11613
11614 ;; This pattern can't accept a variable shift count, since shifts by
11615 ;; zero don't affect the flags.  We assume that shifts by constant
11616 ;; zero are optimized away.
11617 (define_insn "*ashrdi3_cmp_rex64"
11618   [(set (reg FLAGS_REG)
11619         (compare
11620           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11621                        (match_operand:QI 2 "const_int_operand" "n"))
11622           (const_int 0)))
11623    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11624         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11625   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11626    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11627    && (optimize_size
11628        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11629   "sar{q}\t{%2, %0|%0, %2}"
11630   [(set_attr "type" "ishift")
11631    (set_attr "mode" "DI")])
11632
11633 (define_insn "*ashrdi3_cconly_rex64"
11634   [(set (reg FLAGS_REG)
11635         (compare
11636           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11637                        (match_operand:QI 2 "const_int_operand" "n"))
11638           (const_int 0)))
11639    (clobber (match_scratch:DI 0 "=r"))]
11640   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11641    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11642    && (optimize_size
11643        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11644   "sar{q}\t{%2, %0|%0, %2}"
11645   [(set_attr "type" "ishift")
11646    (set_attr "mode" "DI")])
11647
11648 (define_insn "*ashrdi3_1"
11649   [(set (match_operand:DI 0 "register_operand" "=r")
11650         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11651                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11652    (clobber (reg:CC FLAGS_REG))]
11653   "!TARGET_64BIT"
11654   "#"
11655   [(set_attr "type" "multi")])
11656
11657 ;; By default we don't ask for a scratch register, because when DImode
11658 ;; values are manipulated, registers are already at a premium.  But if
11659 ;; we have one handy, we won't turn it away.
11660 (define_peephole2
11661   [(match_scratch:SI 3 "r")
11662    (parallel [(set (match_operand:DI 0 "register_operand" "")
11663                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11664                                 (match_operand:QI 2 "nonmemory_operand" "")))
11665               (clobber (reg:CC FLAGS_REG))])
11666    (match_dup 3)]
11667   "!TARGET_64BIT && TARGET_CMOVE"
11668   [(const_int 0)]
11669   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11670
11671 (define_split
11672   [(set (match_operand:DI 0 "register_operand" "")
11673         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11674                      (match_operand:QI 2 "nonmemory_operand" "")))
11675    (clobber (reg:CC FLAGS_REG))]
11676   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11677                      ? flow2_completed : reload_completed)"
11678   [(const_int 0)]
11679   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11680
11681 (define_insn "x86_shrd_1"
11682   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11683         (ior:SI (ashiftrt:SI (match_dup 0)
11684                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11685                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11686                   (minus:QI (const_int 32) (match_dup 2)))))
11687    (clobber (reg:CC FLAGS_REG))]
11688   ""
11689   "@
11690    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11691    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11692   [(set_attr "type" "ishift")
11693    (set_attr "prefix_0f" "1")
11694    (set_attr "pent_pair" "np")
11695    (set_attr "mode" "SI")])
11696
11697 (define_expand "x86_shift_adj_3"
11698   [(use (match_operand:SI 0 "register_operand" ""))
11699    (use (match_operand:SI 1 "register_operand" ""))
11700    (use (match_operand:QI 2 "register_operand" ""))]
11701   ""
11702 {
11703   rtx label = gen_label_rtx ();
11704   rtx tmp;
11705
11706   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11707
11708   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11709   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11710   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11711                               gen_rtx_LABEL_REF (VOIDmode, label),
11712                               pc_rtx);
11713   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11714   JUMP_LABEL (tmp) = label;
11715
11716   emit_move_insn (operands[0], operands[1]);
11717   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11718
11719   emit_label (label);
11720   LABEL_NUSES (label) = 1;
11721
11722   DONE;
11723 })
11724
11725 (define_insn "ashrsi3_31"
11726   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11727         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11728                      (match_operand:SI 2 "const_int_operand" "i,i")))
11729    (clobber (reg:CC FLAGS_REG))]
11730   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11731    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11732   "@
11733    {cltd|cdq}
11734    sar{l}\t{%2, %0|%0, %2}"
11735   [(set_attr "type" "imovx,ishift")
11736    (set_attr "prefix_0f" "0,*")
11737    (set_attr "length_immediate" "0,*")
11738    (set_attr "modrm" "0,1")
11739    (set_attr "mode" "SI")])
11740
11741 (define_insn "*ashrsi3_31_zext"
11742   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11743         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11744                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11745    (clobber (reg:CC FLAGS_REG))]
11746   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11747    && INTVAL (operands[2]) == 31
11748    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11749   "@
11750    {cltd|cdq}
11751    sar{l}\t{%2, %k0|%k0, %2}"
11752   [(set_attr "type" "imovx,ishift")
11753    (set_attr "prefix_0f" "0,*")
11754    (set_attr "length_immediate" "0,*")
11755    (set_attr "modrm" "0,1")
11756    (set_attr "mode" "SI")])
11757
11758 (define_expand "ashrsi3"
11759   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11760         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11761                      (match_operand:QI 2 "nonmemory_operand" "")))
11762    (clobber (reg:CC FLAGS_REG))]
11763   ""
11764   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11765
11766 (define_insn "*ashrsi3_1_one_bit"
11767   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11768         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11769                      (match_operand:QI 2 "const1_operand" "")))
11770    (clobber (reg:CC FLAGS_REG))]
11771   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11772    && (TARGET_SHIFT1 || optimize_size)"
11773   "sar{l}\t%0"
11774   [(set_attr "type" "ishift")
11775    (set (attr "length")
11776      (if_then_else (match_operand:SI 0 "register_operand" "")
11777         (const_string "2")
11778         (const_string "*")))])
11779
11780 (define_insn "*ashrsi3_1_one_bit_zext"
11781   [(set (match_operand:DI 0 "register_operand" "=r")
11782         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11783                                      (match_operand:QI 2 "const1_operand" ""))))
11784    (clobber (reg:CC FLAGS_REG))]
11785   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11786    && (TARGET_SHIFT1 || optimize_size)"
11787   "sar{l}\t%k0"
11788   [(set_attr "type" "ishift")
11789    (set_attr "length" "2")])
11790
11791 (define_insn "*ashrsi3_1"
11792   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11793         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11794                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11795    (clobber (reg:CC FLAGS_REG))]
11796   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11797   "@
11798    sar{l}\t{%2, %0|%0, %2}
11799    sar{l}\t{%b2, %0|%0, %b2}"
11800   [(set_attr "type" "ishift")
11801    (set_attr "mode" "SI")])
11802
11803 (define_insn "*ashrsi3_1_zext"
11804   [(set (match_operand:DI 0 "register_operand" "=r,r")
11805         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11806                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11807    (clobber (reg:CC FLAGS_REG))]
11808   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11809   "@
11810    sar{l}\t{%2, %k0|%k0, %2}
11811    sar{l}\t{%b2, %k0|%k0, %b2}"
11812   [(set_attr "type" "ishift")
11813    (set_attr "mode" "SI")])
11814
11815 ;; This pattern can't accept a variable shift count, since shifts by
11816 ;; zero don't affect the flags.  We assume that shifts by constant
11817 ;; zero are optimized away.
11818 (define_insn "*ashrsi3_one_bit_cmp"
11819   [(set (reg FLAGS_REG)
11820         (compare
11821           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11822                        (match_operand:QI 2 "const1_operand" ""))
11823           (const_int 0)))
11824    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11825         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11826   "ix86_match_ccmode (insn, CCGOCmode)
11827    && (TARGET_SHIFT1 || optimize_size)
11828    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11829   "sar{l}\t%0"
11830   [(set_attr "type" "ishift")
11831    (set (attr "length")
11832      (if_then_else (match_operand:SI 0 "register_operand" "")
11833         (const_string "2")
11834         (const_string "*")))])
11835
11836 (define_insn "*ashrsi3_one_bit_cconly"
11837   [(set (reg FLAGS_REG)
11838         (compare
11839           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11840                        (match_operand:QI 2 "const1_operand" ""))
11841           (const_int 0)))
11842    (clobber (match_scratch:SI 0 "=r"))]
11843   "ix86_match_ccmode (insn, CCGOCmode)
11844    && (TARGET_SHIFT1 || optimize_size)
11845    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11846   "sar{l}\t%0"
11847   [(set_attr "type" "ishift")
11848    (set_attr "length" "2")])
11849
11850 (define_insn "*ashrsi3_one_bit_cmp_zext"
11851   [(set (reg FLAGS_REG)
11852         (compare
11853           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11854                        (match_operand:QI 2 "const1_operand" ""))
11855           (const_int 0)))
11856    (set (match_operand:DI 0 "register_operand" "=r")
11857         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11858   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11859    && (TARGET_SHIFT1 || optimize_size)
11860    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11861   "sar{l}\t%k0"
11862   [(set_attr "type" "ishift")
11863    (set_attr "length" "2")])
11864
11865 ;; This pattern can't accept a variable shift count, since shifts by
11866 ;; zero don't affect the flags.  We assume that shifts by constant
11867 ;; zero are optimized away.
11868 (define_insn "*ashrsi3_cmp"
11869   [(set (reg FLAGS_REG)
11870         (compare
11871           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11872                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11873           (const_int 0)))
11874    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11875         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11876   "ix86_match_ccmode (insn, CCGOCmode)
11877    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11878    && (optimize_size
11879        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11880   "sar{l}\t{%2, %0|%0, %2}"
11881   [(set_attr "type" "ishift")
11882    (set_attr "mode" "SI")])
11883
11884 (define_insn "*ashrsi3_cconly"
11885   [(set (reg FLAGS_REG)
11886         (compare
11887           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11888                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11889           (const_int 0)))
11890    (clobber (match_scratch:SI 0 "=r"))]
11891   "ix86_match_ccmode (insn, CCGOCmode)
11892    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11893    && (optimize_size
11894        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11895   "sar{l}\t{%2, %0|%0, %2}"
11896   [(set_attr "type" "ishift")
11897    (set_attr "mode" "SI")])
11898
11899 (define_insn "*ashrsi3_cmp_zext"
11900   [(set (reg FLAGS_REG)
11901         (compare
11902           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11903                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11904           (const_int 0)))
11905    (set (match_operand:DI 0 "register_operand" "=r")
11906         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11907   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11908    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11909    && (optimize_size
11910        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11911   "sar{l}\t{%2, %k0|%k0, %2}"
11912   [(set_attr "type" "ishift")
11913    (set_attr "mode" "SI")])
11914
11915 (define_expand "ashrhi3"
11916   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11917         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11918                      (match_operand:QI 2 "nonmemory_operand" "")))
11919    (clobber (reg:CC FLAGS_REG))]
11920   "TARGET_HIMODE_MATH"
11921   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11922
11923 (define_insn "*ashrhi3_1_one_bit"
11924   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11925         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11926                      (match_operand:QI 2 "const1_operand" "")))
11927    (clobber (reg:CC FLAGS_REG))]
11928   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11929    && (TARGET_SHIFT1 || optimize_size)"
11930   "sar{w}\t%0"
11931   [(set_attr "type" "ishift")
11932    (set (attr "length")
11933      (if_then_else (match_operand 0 "register_operand" "")
11934         (const_string "2")
11935         (const_string "*")))])
11936
11937 (define_insn "*ashrhi3_1"
11938   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11939         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11940                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11941    (clobber (reg:CC FLAGS_REG))]
11942   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11943   "@
11944    sar{w}\t{%2, %0|%0, %2}
11945    sar{w}\t{%b2, %0|%0, %b2}"
11946   [(set_attr "type" "ishift")
11947    (set_attr "mode" "HI")])
11948
11949 ;; This pattern can't accept a variable shift count, since shifts by
11950 ;; zero don't affect the flags.  We assume that shifts by constant
11951 ;; zero are optimized away.
11952 (define_insn "*ashrhi3_one_bit_cmp"
11953   [(set (reg FLAGS_REG)
11954         (compare
11955           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11956                        (match_operand:QI 2 "const1_operand" ""))
11957           (const_int 0)))
11958    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11959         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11960   "ix86_match_ccmode (insn, CCGOCmode)
11961    && (TARGET_SHIFT1 || optimize_size)
11962    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11963   "sar{w}\t%0"
11964   [(set_attr "type" "ishift")
11965    (set (attr "length")
11966      (if_then_else (match_operand 0 "register_operand" "")
11967         (const_string "2")
11968         (const_string "*")))])
11969
11970 (define_insn "*ashrhi3_one_bit_cconly"
11971   [(set (reg FLAGS_REG)
11972         (compare
11973           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11974                        (match_operand:QI 2 "const1_operand" ""))
11975           (const_int 0)))
11976    (clobber (match_scratch:HI 0 "=r"))]
11977   "ix86_match_ccmode (insn, CCGOCmode)
11978    && (TARGET_SHIFT1 || optimize_size)
11979    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11980   "sar{w}\t%0"
11981   [(set_attr "type" "ishift")
11982    (set_attr "length" "2")])
11983
11984 ;; This pattern can't accept a variable shift count, since shifts by
11985 ;; zero don't affect the flags.  We assume that shifts by constant
11986 ;; zero are optimized away.
11987 (define_insn "*ashrhi3_cmp"
11988   [(set (reg FLAGS_REG)
11989         (compare
11990           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11991                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11992           (const_int 0)))
11993    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11994         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11995   "ix86_match_ccmode (insn, CCGOCmode)
11996    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11997    && (optimize_size
11998        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11999   "sar{w}\t{%2, %0|%0, %2}"
12000   [(set_attr "type" "ishift")
12001    (set_attr "mode" "HI")])
12002
12003 (define_insn "*ashrhi3_cconly"
12004   [(set (reg FLAGS_REG)
12005         (compare
12006           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12007                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12008           (const_int 0)))
12009    (clobber (match_scratch:HI 0 "=r"))]
12010   "ix86_match_ccmode (insn, CCGOCmode)
12011    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12012    && (optimize_size
12013        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12014   "sar{w}\t{%2, %0|%0, %2}"
12015   [(set_attr "type" "ishift")
12016    (set_attr "mode" "HI")])
12017
12018 (define_expand "ashrqi3"
12019   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12020         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12021                      (match_operand:QI 2 "nonmemory_operand" "")))
12022    (clobber (reg:CC FLAGS_REG))]
12023   "TARGET_QIMODE_MATH"
12024   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12025
12026 (define_insn "*ashrqi3_1_one_bit"
12027   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12028         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12029                      (match_operand:QI 2 "const1_operand" "")))
12030    (clobber (reg:CC FLAGS_REG))]
12031   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12032    && (TARGET_SHIFT1 || optimize_size)"
12033   "sar{b}\t%0"
12034   [(set_attr "type" "ishift")
12035    (set (attr "length")
12036      (if_then_else (match_operand 0 "register_operand" "")
12037         (const_string "2")
12038         (const_string "*")))])
12039
12040 (define_insn "*ashrqi3_1_one_bit_slp"
12041   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12042         (ashiftrt:QI (match_dup 0)
12043                      (match_operand:QI 1 "const1_operand" "")))
12044    (clobber (reg:CC FLAGS_REG))]
12045   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12046    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
12047    && (TARGET_SHIFT1 || optimize_size)"
12048   "sar{b}\t%0"
12049   [(set_attr "type" "ishift1")
12050    (set (attr "length")
12051      (if_then_else (match_operand 0 "register_operand" "")
12052         (const_string "2")
12053         (const_string "*")))])
12054
12055 (define_insn "*ashrqi3_1"
12056   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12057         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12058                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12059    (clobber (reg:CC FLAGS_REG))]
12060   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12061   "@
12062    sar{b}\t{%2, %0|%0, %2}
12063    sar{b}\t{%b2, %0|%0, %b2}"
12064   [(set_attr "type" "ishift")
12065    (set_attr "mode" "QI")])
12066
12067 (define_insn "*ashrqi3_1_slp"
12068   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12069         (ashiftrt:QI (match_dup 0)
12070                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12071    (clobber (reg:CC FLAGS_REG))]
12072   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12073    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12074   "@
12075    sar{b}\t{%1, %0|%0, %1}
12076    sar{b}\t{%b1, %0|%0, %b1}"
12077   [(set_attr "type" "ishift1")
12078    (set_attr "mode" "QI")])
12079
12080 ;; This pattern can't accept a variable shift count, since shifts by
12081 ;; zero don't affect the flags.  We assume that shifts by constant
12082 ;; zero are optimized away.
12083 (define_insn "*ashrqi3_one_bit_cmp"
12084   [(set (reg FLAGS_REG)
12085         (compare
12086           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12087                        (match_operand:QI 2 "const1_operand" "I"))
12088           (const_int 0)))
12089    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12090         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12091   "ix86_match_ccmode (insn, CCGOCmode)
12092    && (TARGET_SHIFT1 || optimize_size)
12093    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12094   "sar{b}\t%0"
12095   [(set_attr "type" "ishift")
12096    (set (attr "length")
12097      (if_then_else (match_operand 0 "register_operand" "")
12098         (const_string "2")
12099         (const_string "*")))])
12100
12101 (define_insn "*ashrqi3_one_bit_cconly"
12102   [(set (reg FLAGS_REG)
12103         (compare
12104           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12105                        (match_operand:QI 2 "const1_operand" "I"))
12106           (const_int 0)))
12107    (clobber (match_scratch:QI 0 "=q"))]
12108   "ix86_match_ccmode (insn, CCGOCmode)
12109    && (TARGET_SHIFT1 || optimize_size)
12110    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12111   "sar{b}\t%0"
12112   [(set_attr "type" "ishift")
12113    (set_attr "length" "2")])
12114
12115 ;; This pattern can't accept a variable shift count, since shifts by
12116 ;; zero don't affect the flags.  We assume that shifts by constant
12117 ;; zero are optimized away.
12118 (define_insn "*ashrqi3_cmp"
12119   [(set (reg FLAGS_REG)
12120         (compare
12121           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12122                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12123           (const_int 0)))
12124    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12125         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12126   "ix86_match_ccmode (insn, CCGOCmode)
12127    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12128    && (optimize_size
12129        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12130   "sar{b}\t{%2, %0|%0, %2}"
12131   [(set_attr "type" "ishift")
12132    (set_attr "mode" "QI")])
12133
12134 (define_insn "*ashrqi3_cconly"
12135   [(set (reg FLAGS_REG)
12136         (compare
12137           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12138                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12139           (const_int 0)))
12140    (clobber (match_scratch:QI 0 "=q"))]
12141   "ix86_match_ccmode (insn, CCGOCmode)
12142    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12143    && (optimize_size
12144        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12145   "sar{b}\t{%2, %0|%0, %2}"
12146   [(set_attr "type" "ishift")
12147    (set_attr "mode" "QI")])
12148
12149 \f
12150 ;; Logical shift instructions
12151
12152 ;; See comment above `ashldi3' about how this works.
12153
12154 (define_expand "lshrti3"
12155   [(parallel [(set (match_operand:TI 0 "register_operand" "")
12156                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12157                                 (match_operand:QI 2 "nonmemory_operand" "")))
12158               (clobber (reg:CC FLAGS_REG))])]
12159   "TARGET_64BIT"
12160 {
12161   if (! immediate_operand (operands[2], QImode))
12162     {
12163       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12164       DONE;
12165     }
12166   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12167   DONE;
12168 })
12169
12170 (define_insn "lshrti3_1"
12171   [(set (match_operand:TI 0 "register_operand" "=r")
12172         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12173                      (match_operand:QI 2 "register_operand" "c")))
12174    (clobber (match_scratch:DI 3 "=&r"))
12175    (clobber (reg:CC FLAGS_REG))]
12176   "TARGET_64BIT"
12177   "#"
12178   [(set_attr "type" "multi")])
12179
12180 (define_insn "*lshrti3_2"
12181   [(set (match_operand:TI 0 "register_operand" "=r")
12182         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12183                      (match_operand:QI 2 "immediate_operand" "O")))
12184    (clobber (reg:CC FLAGS_REG))]
12185   "TARGET_64BIT"
12186   "#"
12187   [(set_attr "type" "multi")])
12188
12189 (define_split
12190   [(set (match_operand:TI 0 "register_operand" "")
12191         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12192                      (match_operand:QI 2 "register_operand" "")))
12193    (clobber (match_scratch:DI 3 ""))
12194    (clobber (reg:CC FLAGS_REG))]
12195   "TARGET_64BIT && reload_completed"
12196   [(const_int 0)]
12197   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12198
12199 (define_split
12200   [(set (match_operand:TI 0 "register_operand" "")
12201         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12202                      (match_operand:QI 2 "immediate_operand" "")))
12203    (clobber (reg:CC FLAGS_REG))]
12204   "TARGET_64BIT && reload_completed"
12205   [(const_int 0)]
12206   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12207
12208 (define_expand "lshrdi3"
12209   [(set (match_operand:DI 0 "shiftdi_operand" "")
12210         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12211                      (match_operand:QI 2 "nonmemory_operand" "")))]
12212   ""
12213   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12214
12215 (define_insn "*lshrdi3_1_one_bit_rex64"
12216   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12217         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12218                      (match_operand:QI 2 "const1_operand" "")))
12219    (clobber (reg:CC FLAGS_REG))]
12220   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12221    && (TARGET_SHIFT1 || optimize_size)"
12222   "shr{q}\t%0"
12223   [(set_attr "type" "ishift")
12224    (set (attr "length")
12225      (if_then_else (match_operand:DI 0 "register_operand" "")
12226         (const_string "2")
12227         (const_string "*")))])
12228
12229 (define_insn "*lshrdi3_1_rex64"
12230   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12231         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12232                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12233    (clobber (reg:CC FLAGS_REG))]
12234   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12235   "@
12236    shr{q}\t{%2, %0|%0, %2}
12237    shr{q}\t{%b2, %0|%0, %b2}"
12238   [(set_attr "type" "ishift")
12239    (set_attr "mode" "DI")])
12240
12241 ;; This pattern can't accept a variable shift count, since shifts by
12242 ;; zero don't affect the flags.  We assume that shifts by constant
12243 ;; zero are optimized away.
12244 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12245   [(set (reg FLAGS_REG)
12246         (compare
12247           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12248                        (match_operand:QI 2 "const1_operand" ""))
12249           (const_int 0)))
12250    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12251         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12252   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12253    && (TARGET_SHIFT1 || optimize_size)
12254    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12255   "shr{q}\t%0"
12256   [(set_attr "type" "ishift")
12257    (set (attr "length")
12258      (if_then_else (match_operand:DI 0 "register_operand" "")
12259         (const_string "2")
12260         (const_string "*")))])
12261
12262 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12263   [(set (reg FLAGS_REG)
12264         (compare
12265           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12266                        (match_operand:QI 2 "const1_operand" ""))
12267           (const_int 0)))
12268    (clobber (match_scratch:DI 0 "=r"))]
12269   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12270    && (TARGET_SHIFT1 || optimize_size)
12271    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12272   "shr{q}\t%0"
12273   [(set_attr "type" "ishift")
12274    (set_attr "length" "2")])
12275
12276 ;; This pattern can't accept a variable shift count, since shifts by
12277 ;; zero don't affect the flags.  We assume that shifts by constant
12278 ;; zero are optimized away.
12279 (define_insn "*lshrdi3_cmp_rex64"
12280   [(set (reg FLAGS_REG)
12281         (compare
12282           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12283                        (match_operand:QI 2 "const_int_operand" "e"))
12284           (const_int 0)))
12285    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12286         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12287   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12288    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12289    && (optimize_size
12290        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12291   "shr{q}\t{%2, %0|%0, %2}"
12292   [(set_attr "type" "ishift")
12293    (set_attr "mode" "DI")])
12294
12295 (define_insn "*lshrdi3_cconly_rex64"
12296   [(set (reg FLAGS_REG)
12297         (compare
12298           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12299                        (match_operand:QI 2 "const_int_operand" "e"))
12300           (const_int 0)))
12301    (clobber (match_scratch:DI 0 "=r"))]
12302   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12303    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12304    && (optimize_size
12305        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12306   "shr{q}\t{%2, %0|%0, %2}"
12307   [(set_attr "type" "ishift")
12308    (set_attr "mode" "DI")])
12309
12310 (define_insn "*lshrdi3_1"
12311   [(set (match_operand:DI 0 "register_operand" "=r")
12312         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12313                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12314    (clobber (reg:CC FLAGS_REG))]
12315   "!TARGET_64BIT"
12316   "#"
12317   [(set_attr "type" "multi")])
12318
12319 ;; By default we don't ask for a scratch register, because when DImode
12320 ;; values are manipulated, registers are already at a premium.  But if
12321 ;; we have one handy, we won't turn it away.
12322 (define_peephole2
12323   [(match_scratch:SI 3 "r")
12324    (parallel [(set (match_operand:DI 0 "register_operand" "")
12325                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12326                                 (match_operand:QI 2 "nonmemory_operand" "")))
12327               (clobber (reg:CC FLAGS_REG))])
12328    (match_dup 3)]
12329   "!TARGET_64BIT && TARGET_CMOVE"
12330   [(const_int 0)]
12331   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12332
12333 (define_split
12334   [(set (match_operand:DI 0 "register_operand" "")
12335         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12336                      (match_operand:QI 2 "nonmemory_operand" "")))
12337    (clobber (reg:CC FLAGS_REG))]
12338   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12339                      ? flow2_completed : reload_completed)"
12340   [(const_int 0)]
12341   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12342
12343 (define_expand "lshrsi3"
12344   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12345         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12346                      (match_operand:QI 2 "nonmemory_operand" "")))
12347    (clobber (reg:CC FLAGS_REG))]
12348   ""
12349   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12350
12351 (define_insn "*lshrsi3_1_one_bit"
12352   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12353         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12354                      (match_operand:QI 2 "const1_operand" "")))
12355    (clobber (reg:CC FLAGS_REG))]
12356   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12357    && (TARGET_SHIFT1 || optimize_size)"
12358   "shr{l}\t%0"
12359   [(set_attr "type" "ishift")
12360    (set (attr "length")
12361      (if_then_else (match_operand:SI 0 "register_operand" "")
12362         (const_string "2")
12363         (const_string "*")))])
12364
12365 (define_insn "*lshrsi3_1_one_bit_zext"
12366   [(set (match_operand:DI 0 "register_operand" "=r")
12367         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12368                      (match_operand:QI 2 "const1_operand" "")))
12369    (clobber (reg:CC FLAGS_REG))]
12370   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12371    && (TARGET_SHIFT1 || optimize_size)"
12372   "shr{l}\t%k0"
12373   [(set_attr "type" "ishift")
12374    (set_attr "length" "2")])
12375
12376 (define_insn "*lshrsi3_1"
12377   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12378         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12379                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12380    (clobber (reg:CC FLAGS_REG))]
12381   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12382   "@
12383    shr{l}\t{%2, %0|%0, %2}
12384    shr{l}\t{%b2, %0|%0, %b2}"
12385   [(set_attr "type" "ishift")
12386    (set_attr "mode" "SI")])
12387
12388 (define_insn "*lshrsi3_1_zext"
12389   [(set (match_operand:DI 0 "register_operand" "=r,r")
12390         (zero_extend:DI
12391           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12392                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12393    (clobber (reg:CC FLAGS_REG))]
12394   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12395   "@
12396    shr{l}\t{%2, %k0|%k0, %2}
12397    shr{l}\t{%b2, %k0|%k0, %b2}"
12398   [(set_attr "type" "ishift")
12399    (set_attr "mode" "SI")])
12400
12401 ;; This pattern can't accept a variable shift count, since shifts by
12402 ;; zero don't affect the flags.  We assume that shifts by constant
12403 ;; zero are optimized away.
12404 (define_insn "*lshrsi3_one_bit_cmp"
12405   [(set (reg FLAGS_REG)
12406         (compare
12407           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12408                        (match_operand:QI 2 "const1_operand" ""))
12409           (const_int 0)))
12410    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12411         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12412   "ix86_match_ccmode (insn, CCGOCmode)
12413    && (TARGET_SHIFT1 || optimize_size)
12414    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12415   "shr{l}\t%0"
12416   [(set_attr "type" "ishift")
12417    (set (attr "length")
12418      (if_then_else (match_operand:SI 0 "register_operand" "")
12419         (const_string "2")
12420         (const_string "*")))])
12421
12422 (define_insn "*lshrsi3_one_bit_cconly"
12423   [(set (reg FLAGS_REG)
12424         (compare
12425           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12426                        (match_operand:QI 2 "const1_operand" ""))
12427           (const_int 0)))
12428    (clobber (match_scratch:SI 0 "=r"))]
12429   "ix86_match_ccmode (insn, CCGOCmode)
12430    && (TARGET_SHIFT1 || optimize_size)
12431    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12432   "shr{l}\t%0"
12433   [(set_attr "type" "ishift")
12434    (set_attr "length" "2")])
12435
12436 (define_insn "*lshrsi3_cmp_one_bit_zext"
12437   [(set (reg FLAGS_REG)
12438         (compare
12439           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12440                        (match_operand:QI 2 "const1_operand" ""))
12441           (const_int 0)))
12442    (set (match_operand:DI 0 "register_operand" "=r")
12443         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12444   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12445    && (TARGET_SHIFT1 || optimize_size)
12446    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12447   "shr{l}\t%k0"
12448   [(set_attr "type" "ishift")
12449    (set_attr "length" "2")])
12450
12451 ;; This pattern can't accept a variable shift count, since shifts by
12452 ;; zero don't affect the flags.  We assume that shifts by constant
12453 ;; zero are optimized away.
12454 (define_insn "*lshrsi3_cmp"
12455   [(set (reg FLAGS_REG)
12456         (compare
12457           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12458                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12459           (const_int 0)))
12460    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12461         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12462   "ix86_match_ccmode (insn, CCGOCmode)
12463    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12464    && (optimize_size
12465        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12466   "shr{l}\t{%2, %0|%0, %2}"
12467   [(set_attr "type" "ishift")
12468    (set_attr "mode" "SI")])
12469
12470 (define_insn "*lshrsi3_cconly"
12471   [(set (reg FLAGS_REG)
12472       (compare
12473         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12474                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12475         (const_int 0)))
12476    (clobber (match_scratch:SI 0 "=r"))]
12477   "ix86_match_ccmode (insn, CCGOCmode)
12478    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12479    && (optimize_size
12480        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12481   "shr{l}\t{%2, %0|%0, %2}"
12482   [(set_attr "type" "ishift")
12483    (set_attr "mode" "SI")])
12484
12485 (define_insn "*lshrsi3_cmp_zext"
12486   [(set (reg FLAGS_REG)
12487         (compare
12488           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12489                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12490           (const_int 0)))
12491    (set (match_operand:DI 0 "register_operand" "=r")
12492         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12493   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12494    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12495    && (optimize_size
12496        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12497   "shr{l}\t{%2, %k0|%k0, %2}"
12498   [(set_attr "type" "ishift")
12499    (set_attr "mode" "SI")])
12500
12501 (define_expand "lshrhi3"
12502   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12503         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12504                      (match_operand:QI 2 "nonmemory_operand" "")))
12505    (clobber (reg:CC FLAGS_REG))]
12506   "TARGET_HIMODE_MATH"
12507   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12508
12509 (define_insn "*lshrhi3_1_one_bit"
12510   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12511         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12512                      (match_operand:QI 2 "const1_operand" "")))
12513    (clobber (reg:CC FLAGS_REG))]
12514   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12515    && (TARGET_SHIFT1 || optimize_size)"
12516   "shr{w}\t%0"
12517   [(set_attr "type" "ishift")
12518    (set (attr "length")
12519      (if_then_else (match_operand 0 "register_operand" "")
12520         (const_string "2")
12521         (const_string "*")))])
12522
12523 (define_insn "*lshrhi3_1"
12524   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12525         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12526                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12527    (clobber (reg:CC FLAGS_REG))]
12528   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12529   "@
12530    shr{w}\t{%2, %0|%0, %2}
12531    shr{w}\t{%b2, %0|%0, %b2}"
12532   [(set_attr "type" "ishift")
12533    (set_attr "mode" "HI")])
12534
12535 ;; This pattern can't accept a variable shift count, since shifts by
12536 ;; zero don't affect the flags.  We assume that shifts by constant
12537 ;; zero are optimized away.
12538 (define_insn "*lshrhi3_one_bit_cmp"
12539   [(set (reg FLAGS_REG)
12540         (compare
12541           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12542                        (match_operand:QI 2 "const1_operand" ""))
12543           (const_int 0)))
12544    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12545         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12546   "ix86_match_ccmode (insn, CCGOCmode)
12547    && (TARGET_SHIFT1 || optimize_size)
12548    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12549   "shr{w}\t%0"
12550   [(set_attr "type" "ishift")
12551    (set (attr "length")
12552      (if_then_else (match_operand:SI 0 "register_operand" "")
12553         (const_string "2")
12554         (const_string "*")))])
12555
12556 (define_insn "*lshrhi3_one_bit_cconly"
12557   [(set (reg FLAGS_REG)
12558         (compare
12559           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12560                        (match_operand:QI 2 "const1_operand" ""))
12561           (const_int 0)))
12562    (clobber (match_scratch:HI 0 "=r"))]
12563   "ix86_match_ccmode (insn, CCGOCmode)
12564    && (TARGET_SHIFT1 || optimize_size)
12565    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12566   "shr{w}\t%0"
12567   [(set_attr "type" "ishift")
12568    (set_attr "length" "2")])
12569
12570 ;; This pattern can't accept a variable shift count, since shifts by
12571 ;; zero don't affect the flags.  We assume that shifts by constant
12572 ;; zero are optimized away.
12573 (define_insn "*lshrhi3_cmp"
12574   [(set (reg FLAGS_REG)
12575         (compare
12576           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12577                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12578           (const_int 0)))
12579    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12580         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12581   "ix86_match_ccmode (insn, CCGOCmode)
12582    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12583    && (optimize_size
12584        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12585   "shr{w}\t{%2, %0|%0, %2}"
12586   [(set_attr "type" "ishift")
12587    (set_attr "mode" "HI")])
12588
12589 (define_insn "*lshrhi3_cconly"
12590   [(set (reg FLAGS_REG)
12591         (compare
12592           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12593                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12594           (const_int 0)))
12595    (clobber (match_scratch:HI 0 "=r"))]
12596   "ix86_match_ccmode (insn, CCGOCmode)
12597    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12598    && (optimize_size
12599        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12600   "shr{w}\t{%2, %0|%0, %2}"
12601   [(set_attr "type" "ishift")
12602    (set_attr "mode" "HI")])
12603
12604 (define_expand "lshrqi3"
12605   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12606         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12607                      (match_operand:QI 2 "nonmemory_operand" "")))
12608    (clobber (reg:CC FLAGS_REG))]
12609   "TARGET_QIMODE_MATH"
12610   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12611
12612 (define_insn "*lshrqi3_1_one_bit"
12613   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12614         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12615                      (match_operand:QI 2 "const1_operand" "")))
12616    (clobber (reg:CC FLAGS_REG))]
12617   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12618    && (TARGET_SHIFT1 || optimize_size)"
12619   "shr{b}\t%0"
12620   [(set_attr "type" "ishift")
12621    (set (attr "length")
12622      (if_then_else (match_operand 0 "register_operand" "")
12623         (const_string "2")
12624         (const_string "*")))])
12625
12626 (define_insn "*lshrqi3_1_one_bit_slp"
12627   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12628         (lshiftrt:QI (match_dup 0)
12629                      (match_operand:QI 1 "const1_operand" "")))
12630    (clobber (reg:CC FLAGS_REG))]
12631   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12632    && (TARGET_SHIFT1 || optimize_size)"
12633   "shr{b}\t%0"
12634   [(set_attr "type" "ishift1")
12635    (set (attr "length")
12636      (if_then_else (match_operand 0 "register_operand" "")
12637         (const_string "2")
12638         (const_string "*")))])
12639
12640 (define_insn "*lshrqi3_1"
12641   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12642         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12643                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12644    (clobber (reg:CC FLAGS_REG))]
12645   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12646   "@
12647    shr{b}\t{%2, %0|%0, %2}
12648    shr{b}\t{%b2, %0|%0, %b2}"
12649   [(set_attr "type" "ishift")
12650    (set_attr "mode" "QI")])
12651
12652 (define_insn "*lshrqi3_1_slp"
12653   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12654         (lshiftrt:QI (match_dup 0)
12655                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12656    (clobber (reg:CC FLAGS_REG))]
12657   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12658    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12659   "@
12660    shr{b}\t{%1, %0|%0, %1}
12661    shr{b}\t{%b1, %0|%0, %b1}"
12662   [(set_attr "type" "ishift1")
12663    (set_attr "mode" "QI")])
12664
12665 ;; This pattern can't accept a variable shift count, since shifts by
12666 ;; zero don't affect the flags.  We assume that shifts by constant
12667 ;; zero are optimized away.
12668 (define_insn "*lshrqi2_one_bit_cmp"
12669   [(set (reg FLAGS_REG)
12670         (compare
12671           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12672                        (match_operand:QI 2 "const1_operand" ""))
12673           (const_int 0)))
12674    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12675         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12676   "ix86_match_ccmode (insn, CCGOCmode)
12677    && (TARGET_SHIFT1 || optimize_size)
12678    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12679   "shr{b}\t%0"
12680   [(set_attr "type" "ishift")
12681    (set (attr "length")
12682      (if_then_else (match_operand:SI 0 "register_operand" "")
12683         (const_string "2")
12684         (const_string "*")))])
12685
12686 (define_insn "*lshrqi2_one_bit_cconly"
12687   [(set (reg FLAGS_REG)
12688         (compare
12689           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12690                        (match_operand:QI 2 "const1_operand" ""))
12691           (const_int 0)))
12692    (clobber (match_scratch:QI 0 "=q"))]
12693   "ix86_match_ccmode (insn, CCGOCmode)
12694    && (TARGET_SHIFT1 || optimize_size)
12695    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12696   "shr{b}\t%0"
12697   [(set_attr "type" "ishift")
12698    (set_attr "length" "2")])
12699
12700 ;; This pattern can't accept a variable shift count, since shifts by
12701 ;; zero don't affect the flags.  We assume that shifts by constant
12702 ;; zero are optimized away.
12703 (define_insn "*lshrqi2_cmp"
12704   [(set (reg FLAGS_REG)
12705         (compare
12706           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12707                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12708           (const_int 0)))
12709    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12710         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12711   "ix86_match_ccmode (insn, CCGOCmode)
12712    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12713    && (optimize_size
12714        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12715   "shr{b}\t{%2, %0|%0, %2}"
12716   [(set_attr "type" "ishift")
12717    (set_attr "mode" "QI")])
12718
12719 (define_insn "*lshrqi2_cconly"
12720   [(set (reg FLAGS_REG)
12721         (compare
12722           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12723                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12724           (const_int 0)))
12725    (clobber (match_scratch:QI 0 "=q"))]
12726   "ix86_match_ccmode (insn, CCGOCmode)
12727    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12728    && (optimize_size
12729        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12730   "shr{b}\t{%2, %0|%0, %2}"
12731   [(set_attr "type" "ishift")
12732    (set_attr "mode" "QI")])
12733 \f
12734 ;; Rotate instructions
12735
12736 (define_expand "rotldi3"
12737   [(set (match_operand:DI 0 "shiftdi_operand" "")
12738         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12739                    (match_operand:QI 2 "nonmemory_operand" "")))
12740    (clobber (reg:CC FLAGS_REG))]
12741  ""
12742 {
12743   if (TARGET_64BIT)
12744     {
12745       ix86_expand_binary_operator (ROTATE, DImode, operands);
12746       DONE;
12747     }
12748   if (!const_1_to_31_operand (operands[2], VOIDmode))
12749     FAIL;
12750   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12751   DONE;
12752 })
12753
12754 ;; Implement rotation using two double-precision shift instructions
12755 ;; and a scratch register.
12756 (define_insn_and_split "ix86_rotldi3"
12757  [(set (match_operand:DI 0 "register_operand" "=r")
12758        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12759                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12760   (clobber (reg:CC FLAGS_REG))
12761   (clobber (match_scratch:SI 3 "=&r"))]
12762  "!TARGET_64BIT"
12763  ""
12764  "&& reload_completed"
12765  [(set (match_dup 3) (match_dup 4))
12766   (parallel
12767    [(set (match_dup 4)
12768          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12769                  (lshiftrt:SI (match_dup 5)
12770                               (minus:QI (const_int 32) (match_dup 2)))))
12771     (clobber (reg:CC FLAGS_REG))])
12772   (parallel
12773    [(set (match_dup 5)
12774          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12775                  (lshiftrt:SI (match_dup 3)
12776                               (minus:QI (const_int 32) (match_dup 2)))))
12777     (clobber (reg:CC FLAGS_REG))])]
12778  "split_di (operands, 1, operands + 4, operands + 5);")
12779
12780 (define_insn "*rotlsi3_1_one_bit_rex64"
12781   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12782         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12783                    (match_operand:QI 2 "const1_operand" "")))
12784    (clobber (reg:CC FLAGS_REG))]
12785   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12786    && (TARGET_SHIFT1 || optimize_size)"
12787   "rol{q}\t%0"
12788   [(set_attr "type" "rotate")
12789    (set (attr "length")
12790      (if_then_else (match_operand:DI 0 "register_operand" "")
12791         (const_string "2")
12792         (const_string "*")))])
12793
12794 (define_insn "*rotldi3_1_rex64"
12795   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12796         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12797                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12798    (clobber (reg:CC FLAGS_REG))]
12799   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12800   "@
12801    rol{q}\t{%2, %0|%0, %2}
12802    rol{q}\t{%b2, %0|%0, %b2}"
12803   [(set_attr "type" "rotate")
12804    (set_attr "mode" "DI")])
12805
12806 (define_expand "rotlsi3"
12807   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12808         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12809                    (match_operand:QI 2 "nonmemory_operand" "")))
12810    (clobber (reg:CC FLAGS_REG))]
12811   ""
12812   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12813
12814 (define_insn "*rotlsi3_1_one_bit"
12815   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12816         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12817                    (match_operand:QI 2 "const1_operand" "")))
12818    (clobber (reg:CC FLAGS_REG))]
12819   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12820    && (TARGET_SHIFT1 || optimize_size)"
12821   "rol{l}\t%0"
12822   [(set_attr "type" "rotate")
12823    (set (attr "length")
12824      (if_then_else (match_operand:SI 0 "register_operand" "")
12825         (const_string "2")
12826         (const_string "*")))])
12827
12828 (define_insn "*rotlsi3_1_one_bit_zext"
12829   [(set (match_operand:DI 0 "register_operand" "=r")
12830         (zero_extend:DI
12831           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12832                      (match_operand:QI 2 "const1_operand" ""))))
12833    (clobber (reg:CC FLAGS_REG))]
12834   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12835    && (TARGET_SHIFT1 || optimize_size)"
12836   "rol{l}\t%k0"
12837   [(set_attr "type" "rotate")
12838    (set_attr "length" "2")])
12839
12840 (define_insn "*rotlsi3_1"
12841   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12842         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12843                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12844    (clobber (reg:CC FLAGS_REG))]
12845   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12846   "@
12847    rol{l}\t{%2, %0|%0, %2}
12848    rol{l}\t{%b2, %0|%0, %b2}"
12849   [(set_attr "type" "rotate")
12850    (set_attr "mode" "SI")])
12851
12852 (define_insn "*rotlsi3_1_zext"
12853   [(set (match_operand:DI 0 "register_operand" "=r,r")
12854         (zero_extend:DI
12855           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12856                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12857    (clobber (reg:CC FLAGS_REG))]
12858   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12859   "@
12860    rol{l}\t{%2, %k0|%k0, %2}
12861    rol{l}\t{%b2, %k0|%k0, %b2}"
12862   [(set_attr "type" "rotate")
12863    (set_attr "mode" "SI")])
12864
12865 (define_expand "rotlhi3"
12866   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12867         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12868                    (match_operand:QI 2 "nonmemory_operand" "")))
12869    (clobber (reg:CC FLAGS_REG))]
12870   "TARGET_HIMODE_MATH"
12871   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12872
12873 (define_insn "*rotlhi3_1_one_bit"
12874   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12875         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12876                    (match_operand:QI 2 "const1_operand" "")))
12877    (clobber (reg:CC FLAGS_REG))]
12878   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12879    && (TARGET_SHIFT1 || optimize_size)"
12880   "rol{w}\t%0"
12881   [(set_attr "type" "rotate")
12882    (set (attr "length")
12883      (if_then_else (match_operand 0 "register_operand" "")
12884         (const_string "2")
12885         (const_string "*")))])
12886
12887 (define_insn "*rotlhi3_1"
12888   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12889         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12890                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12891    (clobber (reg:CC FLAGS_REG))]
12892   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12893   "@
12894    rol{w}\t{%2, %0|%0, %2}
12895    rol{w}\t{%b2, %0|%0, %b2}"
12896   [(set_attr "type" "rotate")
12897    (set_attr "mode" "HI")])
12898
12899 (define_split
12900  [(set (match_operand:HI 0 "register_operand" "")
12901        (rotate:HI (match_dup 0) (const_int 8)))
12902   (clobber (reg:CC FLAGS_REG))]
12903  "reload_completed"
12904  [(parallel [(set (strict_low_part (match_dup 0))
12905                   (bswap:HI (match_dup 0)))
12906              (clobber (reg:CC FLAGS_REG))])]
12907  "")
12908
12909 (define_expand "rotlqi3"
12910   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12911         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12912                    (match_operand:QI 2 "nonmemory_operand" "")))
12913    (clobber (reg:CC FLAGS_REG))]
12914   "TARGET_QIMODE_MATH"
12915   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12916
12917 (define_insn "*rotlqi3_1_one_bit_slp"
12918   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12919         (rotate:QI (match_dup 0)
12920                    (match_operand:QI 1 "const1_operand" "")))
12921    (clobber (reg:CC FLAGS_REG))]
12922   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12923    && (TARGET_SHIFT1 || optimize_size)"
12924   "rol{b}\t%0"
12925   [(set_attr "type" "rotate1")
12926    (set (attr "length")
12927      (if_then_else (match_operand 0 "register_operand" "")
12928         (const_string "2")
12929         (const_string "*")))])
12930
12931 (define_insn "*rotlqi3_1_one_bit"
12932   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12933         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12934                    (match_operand:QI 2 "const1_operand" "")))
12935    (clobber (reg:CC FLAGS_REG))]
12936   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12937    && (TARGET_SHIFT1 || optimize_size)"
12938   "rol{b}\t%0"
12939   [(set_attr "type" "rotate")
12940    (set (attr "length")
12941      (if_then_else (match_operand 0 "register_operand" "")
12942         (const_string "2")
12943         (const_string "*")))])
12944
12945 (define_insn "*rotlqi3_1_slp"
12946   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12947         (rotate:QI (match_dup 0)
12948                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12949    (clobber (reg:CC FLAGS_REG))]
12950   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12951    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12952   "@
12953    rol{b}\t{%1, %0|%0, %1}
12954    rol{b}\t{%b1, %0|%0, %b1}"
12955   [(set_attr "type" "rotate1")
12956    (set_attr "mode" "QI")])
12957
12958 (define_insn "*rotlqi3_1"
12959   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12960         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12961                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12962    (clobber (reg:CC FLAGS_REG))]
12963   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12964   "@
12965    rol{b}\t{%2, %0|%0, %2}
12966    rol{b}\t{%b2, %0|%0, %b2}"
12967   [(set_attr "type" "rotate")
12968    (set_attr "mode" "QI")])
12969
12970 (define_expand "rotrdi3"
12971   [(set (match_operand:DI 0 "shiftdi_operand" "")
12972         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12973                    (match_operand:QI 2 "nonmemory_operand" "")))
12974    (clobber (reg:CC FLAGS_REG))]
12975  ""
12976 {
12977   if (TARGET_64BIT)
12978     {
12979       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12980       DONE;
12981     }
12982   if (!const_1_to_31_operand (operands[2], VOIDmode))
12983     FAIL;
12984   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12985   DONE;
12986 })
12987
12988 ;; Implement rotation using two double-precision shift instructions
12989 ;; and a scratch register.
12990 (define_insn_and_split "ix86_rotrdi3"
12991  [(set (match_operand:DI 0 "register_operand" "=r")
12992        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12993                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12994   (clobber (reg:CC FLAGS_REG))
12995   (clobber (match_scratch:SI 3 "=&r"))]
12996  "!TARGET_64BIT"
12997  ""
12998  "&& reload_completed"
12999  [(set (match_dup 3) (match_dup 4))
13000   (parallel
13001    [(set (match_dup 4)
13002          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13003                  (ashift:SI (match_dup 5)
13004                             (minus:QI (const_int 32) (match_dup 2)))))
13005     (clobber (reg:CC FLAGS_REG))])
13006   (parallel
13007    [(set (match_dup 5)
13008          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13009                  (ashift:SI (match_dup 3)
13010                             (minus:QI (const_int 32) (match_dup 2)))))
13011     (clobber (reg:CC FLAGS_REG))])]
13012  "split_di (operands, 1, operands + 4, operands + 5);")
13013
13014 (define_insn "*rotrdi3_1_one_bit_rex64"
13015   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13016         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13017                      (match_operand:QI 2 "const1_operand" "")))
13018    (clobber (reg:CC FLAGS_REG))]
13019   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
13020    && (TARGET_SHIFT1 || optimize_size)"
13021   "ror{q}\t%0"
13022   [(set_attr "type" "rotate")
13023    (set (attr "length")
13024      (if_then_else (match_operand:DI 0 "register_operand" "")
13025         (const_string "2")
13026         (const_string "*")))])
13027
13028 (define_insn "*rotrdi3_1_rex64"
13029   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13030         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13031                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13032    (clobber (reg:CC FLAGS_REG))]
13033   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13034   "@
13035    ror{q}\t{%2, %0|%0, %2}
13036    ror{q}\t{%b2, %0|%0, %b2}"
13037   [(set_attr "type" "rotate")
13038    (set_attr "mode" "DI")])
13039
13040 (define_expand "rotrsi3"
13041   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13042         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13043                      (match_operand:QI 2 "nonmemory_operand" "")))
13044    (clobber (reg:CC FLAGS_REG))]
13045   ""
13046   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13047
13048 (define_insn "*rotrsi3_1_one_bit"
13049   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13050         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13051                      (match_operand:QI 2 "const1_operand" "")))
13052    (clobber (reg:CC FLAGS_REG))]
13053   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
13054    && (TARGET_SHIFT1 || optimize_size)"
13055   "ror{l}\t%0"
13056   [(set_attr "type" "rotate")
13057    (set (attr "length")
13058      (if_then_else (match_operand:SI 0 "register_operand" "")
13059         (const_string "2")
13060         (const_string "*")))])
13061
13062 (define_insn "*rotrsi3_1_one_bit_zext"
13063   [(set (match_operand:DI 0 "register_operand" "=r")
13064         (zero_extend:DI
13065           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13066                        (match_operand:QI 2 "const1_operand" ""))))
13067    (clobber (reg:CC FLAGS_REG))]
13068   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
13069    && (TARGET_SHIFT1 || optimize_size)"
13070   "ror{l}\t%k0"
13071   [(set_attr "type" "rotate")
13072    (set (attr "length")
13073      (if_then_else (match_operand:SI 0 "register_operand" "")
13074         (const_string "2")
13075         (const_string "*")))])
13076
13077 (define_insn "*rotrsi3_1"
13078   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13079         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13080                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13081    (clobber (reg:CC FLAGS_REG))]
13082   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13083   "@
13084    ror{l}\t{%2, %0|%0, %2}
13085    ror{l}\t{%b2, %0|%0, %b2}"
13086   [(set_attr "type" "rotate")
13087    (set_attr "mode" "SI")])
13088
13089 (define_insn "*rotrsi3_1_zext"
13090   [(set (match_operand:DI 0 "register_operand" "=r,r")
13091         (zero_extend:DI
13092           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13093                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13094    (clobber (reg:CC FLAGS_REG))]
13095   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13096   "@
13097    ror{l}\t{%2, %k0|%k0, %2}
13098    ror{l}\t{%b2, %k0|%k0, %b2}"
13099   [(set_attr "type" "rotate")
13100    (set_attr "mode" "SI")])
13101
13102 (define_expand "rotrhi3"
13103   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13104         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13105                      (match_operand:QI 2 "nonmemory_operand" "")))
13106    (clobber (reg:CC FLAGS_REG))]
13107   "TARGET_HIMODE_MATH"
13108   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13109
13110 (define_insn "*rotrhi3_one_bit"
13111   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13112         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13113                      (match_operand:QI 2 "const1_operand" "")))
13114    (clobber (reg:CC FLAGS_REG))]
13115   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
13116    && (TARGET_SHIFT1 || optimize_size)"
13117   "ror{w}\t%0"
13118   [(set_attr "type" "rotate")
13119    (set (attr "length")
13120      (if_then_else (match_operand 0 "register_operand" "")
13121         (const_string "2")
13122         (const_string "*")))])
13123
13124 (define_insn "*rotrhi3_1"
13125   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13126         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13127                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13128    (clobber (reg:CC FLAGS_REG))]
13129   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13130   "@
13131    ror{w}\t{%2, %0|%0, %2}
13132    ror{w}\t{%b2, %0|%0, %b2}"
13133   [(set_attr "type" "rotate")
13134    (set_attr "mode" "HI")])
13135
13136 (define_split
13137  [(set (match_operand:HI 0 "register_operand" "")
13138        (rotatert:HI (match_dup 0) (const_int 8)))
13139   (clobber (reg:CC FLAGS_REG))]
13140  "reload_completed"
13141  [(parallel [(set (strict_low_part (match_dup 0))
13142                   (bswap:HI (match_dup 0)))
13143              (clobber (reg:CC FLAGS_REG))])]
13144  "")
13145
13146 (define_expand "rotrqi3"
13147   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13148         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13149                      (match_operand:QI 2 "nonmemory_operand" "")))
13150    (clobber (reg:CC FLAGS_REG))]
13151   "TARGET_QIMODE_MATH"
13152   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13153
13154 (define_insn "*rotrqi3_1_one_bit"
13155   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13156         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13157                      (match_operand:QI 2 "const1_operand" "")))
13158    (clobber (reg:CC FLAGS_REG))]
13159   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
13160    && (TARGET_SHIFT1 || optimize_size)"
13161   "ror{b}\t%0"
13162   [(set_attr "type" "rotate")
13163    (set (attr "length")
13164      (if_then_else (match_operand 0 "register_operand" "")
13165         (const_string "2")
13166         (const_string "*")))])
13167
13168 (define_insn "*rotrqi3_1_one_bit_slp"
13169   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13170         (rotatert:QI (match_dup 0)
13171                      (match_operand:QI 1 "const1_operand" "")))
13172    (clobber (reg:CC FLAGS_REG))]
13173   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13174    && (TARGET_SHIFT1 || optimize_size)"
13175   "ror{b}\t%0"
13176   [(set_attr "type" "rotate1")
13177    (set (attr "length")
13178      (if_then_else (match_operand 0 "register_operand" "")
13179         (const_string "2")
13180         (const_string "*")))])
13181
13182 (define_insn "*rotrqi3_1"
13183   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13184         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13185                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13186    (clobber (reg:CC FLAGS_REG))]
13187   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13188   "@
13189    ror{b}\t{%2, %0|%0, %2}
13190    ror{b}\t{%b2, %0|%0, %b2}"
13191   [(set_attr "type" "rotate")
13192    (set_attr "mode" "QI")])
13193
13194 (define_insn "*rotrqi3_1_slp"
13195   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13196         (rotatert:QI (match_dup 0)
13197                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13198    (clobber (reg:CC FLAGS_REG))]
13199   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13200    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13201   "@
13202    ror{b}\t{%1, %0|%0, %1}
13203    ror{b}\t{%b1, %0|%0, %b1}"
13204   [(set_attr "type" "rotate1")
13205    (set_attr "mode" "QI")])
13206 \f
13207 ;; Bit set / bit test instructions
13208
13209 (define_expand "extv"
13210   [(set (match_operand:SI 0 "register_operand" "")
13211         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13212                          (match_operand:SI 2 "const8_operand" "")
13213                          (match_operand:SI 3 "const8_operand" "")))]
13214   ""
13215 {
13216   /* Handle extractions from %ah et al.  */
13217   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13218     FAIL;
13219
13220   /* From mips.md: extract_bit_field doesn't verify that our source
13221      matches the predicate, so check it again here.  */
13222   if (! ext_register_operand (operands[1], VOIDmode))
13223     FAIL;
13224 })
13225
13226 (define_expand "extzv"
13227   [(set (match_operand:SI 0 "register_operand" "")
13228         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13229                          (match_operand:SI 2 "const8_operand" "")
13230                          (match_operand:SI 3 "const8_operand" "")))]
13231   ""
13232 {
13233   /* Handle extractions from %ah et al.  */
13234   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13235     FAIL;
13236
13237   /* From mips.md: extract_bit_field doesn't verify that our source
13238      matches the predicate, so check it again here.  */
13239   if (! ext_register_operand (operands[1], VOIDmode))
13240     FAIL;
13241 })
13242
13243 (define_expand "insv"
13244   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13245                       (match_operand 1 "const8_operand" "")
13246                       (match_operand 2 "const8_operand" ""))
13247         (match_operand 3 "register_operand" ""))]
13248   ""
13249 {
13250   /* Handle insertions to %ah et al.  */
13251   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13252     FAIL;
13253
13254   /* From mips.md: insert_bit_field doesn't verify that our source
13255      matches the predicate, so check it again here.  */
13256   if (! ext_register_operand (operands[0], VOIDmode))
13257     FAIL;
13258
13259   if (TARGET_64BIT)
13260     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13261   else
13262     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13263
13264   DONE;
13265 })
13266
13267 ;; %%% bts, btr, btc, bt.
13268 ;; In general these instructions are *slow* when applied to memory,
13269 ;; since they enforce atomic operation.  When applied to registers,
13270 ;; it depends on the cpu implementation.  They're never faster than
13271 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13272 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13273 ;; within the instruction itself, so operating on bits in the high
13274 ;; 32-bits of a register becomes easier.
13275 ;;
13276 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13277 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13278 ;; negdf respectively, so they can never be disabled entirely.
13279
13280 (define_insn "*btsq"
13281   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13282                          (const_int 1)
13283                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13284         (const_int 1))
13285    (clobber (reg:CC FLAGS_REG))]
13286   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13287   "bts{q} %1,%0"
13288   [(set_attr "type" "alu1")])
13289
13290 (define_insn "*btrq"
13291   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13292                          (const_int 1)
13293                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13294         (const_int 0))
13295    (clobber (reg:CC FLAGS_REG))]
13296   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13297   "btr{q} %1,%0"
13298   [(set_attr "type" "alu1")])
13299
13300 (define_insn "*btcq"
13301   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13302                          (const_int 1)
13303                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13304         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13305    (clobber (reg:CC FLAGS_REG))]
13306   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13307   "btc{q} %1,%0"
13308   [(set_attr "type" "alu1")])
13309
13310 ;; Allow Nocona to avoid these instructions if a register is available.
13311
13312 (define_peephole2
13313   [(match_scratch:DI 2 "r")
13314    (parallel [(set (zero_extract:DI
13315                      (match_operand:DI 0 "register_operand" "")
13316                      (const_int 1)
13317                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13318                    (const_int 1))
13319               (clobber (reg:CC FLAGS_REG))])]
13320   "TARGET_64BIT && !TARGET_USE_BT"
13321   [(const_int 0)]
13322 {
13323   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13324   rtx op1;
13325
13326   if (HOST_BITS_PER_WIDE_INT >= 64)
13327     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13328   else if (i < HOST_BITS_PER_WIDE_INT)
13329     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13330   else
13331     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13332
13333   op1 = immed_double_const (lo, hi, DImode);
13334   if (i >= 31)
13335     {
13336       emit_move_insn (operands[2], op1);
13337       op1 = operands[2];
13338     }
13339
13340   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13341   DONE;
13342 })
13343
13344 (define_peephole2
13345   [(match_scratch:DI 2 "r")
13346    (parallel [(set (zero_extract:DI
13347                      (match_operand:DI 0 "register_operand" "")
13348                      (const_int 1)
13349                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13350                    (const_int 0))
13351               (clobber (reg:CC FLAGS_REG))])]
13352   "TARGET_64BIT && !TARGET_USE_BT"
13353   [(const_int 0)]
13354 {
13355   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13356   rtx op1;
13357
13358   if (HOST_BITS_PER_WIDE_INT >= 64)
13359     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13360   else if (i < HOST_BITS_PER_WIDE_INT)
13361     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13362   else
13363     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13364
13365   op1 = immed_double_const (~lo, ~hi, DImode);
13366   if (i >= 32)
13367     {
13368       emit_move_insn (operands[2], op1);
13369       op1 = operands[2];
13370     }
13371
13372   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13373   DONE;
13374 })
13375
13376 (define_peephole2
13377   [(match_scratch:DI 2 "r")
13378    (parallel [(set (zero_extract:DI
13379                      (match_operand:DI 0 "register_operand" "")
13380                      (const_int 1)
13381                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13382               (not:DI (zero_extract:DI
13383                         (match_dup 0) (const_int 1) (match_dup 1))))
13384               (clobber (reg:CC FLAGS_REG))])]
13385   "TARGET_64BIT && !TARGET_USE_BT"
13386   [(const_int 0)]
13387 {
13388   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13389   rtx op1;
13390
13391   if (HOST_BITS_PER_WIDE_INT >= 64)
13392     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13393   else if (i < HOST_BITS_PER_WIDE_INT)
13394     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13395   else
13396     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13397
13398   op1 = immed_double_const (lo, hi, DImode);
13399   if (i >= 31)
13400     {
13401       emit_move_insn (operands[2], op1);
13402       op1 = operands[2];
13403     }
13404
13405   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13406   DONE;
13407 })
13408 \f
13409 ;; Store-flag instructions.
13410
13411 ;; For all sCOND expanders, also expand the compare or test insn that
13412 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13413
13414 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13415 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13416 ;; way, which can later delete the movzx if only QImode is needed.
13417
13418 (define_expand "seq"
13419   [(set (match_operand:QI 0 "register_operand" "")
13420         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13421   ""
13422   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13423
13424 (define_expand "sne"
13425   [(set (match_operand:QI 0 "register_operand" "")
13426         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13427   ""
13428   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13429
13430 (define_expand "sgt"
13431   [(set (match_operand:QI 0 "register_operand" "")
13432         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13433   ""
13434   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13435
13436 (define_expand "sgtu"
13437   [(set (match_operand:QI 0 "register_operand" "")
13438         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13439   ""
13440   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13441
13442 (define_expand "slt"
13443   [(set (match_operand:QI 0 "register_operand" "")
13444         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13445   ""
13446   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13447
13448 (define_expand "sltu"
13449   [(set (match_operand:QI 0 "register_operand" "")
13450         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13451   ""
13452   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13453
13454 (define_expand "sge"
13455   [(set (match_operand:QI 0 "register_operand" "")
13456         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13457   ""
13458   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13459
13460 (define_expand "sgeu"
13461   [(set (match_operand:QI 0 "register_operand" "")
13462         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13463   ""
13464   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13465
13466 (define_expand "sle"
13467   [(set (match_operand:QI 0 "register_operand" "")
13468         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13469   ""
13470   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13471
13472 (define_expand "sleu"
13473   [(set (match_operand:QI 0 "register_operand" "")
13474         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13475   ""
13476   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13477
13478 (define_expand "sunordered"
13479   [(set (match_operand:QI 0 "register_operand" "")
13480         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13481   "TARGET_80387 || TARGET_SSE"
13482   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13483
13484 (define_expand "sordered"
13485   [(set (match_operand:QI 0 "register_operand" "")
13486         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13487   "TARGET_80387"
13488   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13489
13490 (define_expand "suneq"
13491   [(set (match_operand:QI 0 "register_operand" "")
13492         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13493   "TARGET_80387 || TARGET_SSE"
13494   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13495
13496 (define_expand "sunge"
13497   [(set (match_operand:QI 0 "register_operand" "")
13498         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13499   "TARGET_80387 || TARGET_SSE"
13500   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13501
13502 (define_expand "sungt"
13503   [(set (match_operand:QI 0 "register_operand" "")
13504         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13505   "TARGET_80387 || TARGET_SSE"
13506   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13507
13508 (define_expand "sunle"
13509   [(set (match_operand:QI 0 "register_operand" "")
13510         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13511   "TARGET_80387 || TARGET_SSE"
13512   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13513
13514 (define_expand "sunlt"
13515   [(set (match_operand:QI 0 "register_operand" "")
13516         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13517   "TARGET_80387 || TARGET_SSE"
13518   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13519
13520 (define_expand "sltgt"
13521   [(set (match_operand:QI 0 "register_operand" "")
13522         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13523   "TARGET_80387 || TARGET_SSE"
13524   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13525
13526 (define_insn "*setcc_1"
13527   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13528         (match_operator:QI 1 "ix86_comparison_operator"
13529           [(reg FLAGS_REG) (const_int 0)]))]
13530   ""
13531   "set%C1\t%0"
13532   [(set_attr "type" "setcc")
13533    (set_attr "mode" "QI")])
13534
13535 (define_insn "*setcc_2"
13536   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13537         (match_operator:QI 1 "ix86_comparison_operator"
13538           [(reg FLAGS_REG) (const_int 0)]))]
13539   ""
13540   "set%C1\t%0"
13541   [(set_attr "type" "setcc")
13542    (set_attr "mode" "QI")])
13543
13544 ;; In general it is not safe to assume too much about CCmode registers,
13545 ;; so simplify-rtx stops when it sees a second one.  Under certain
13546 ;; conditions this is safe on x86, so help combine not create
13547 ;;
13548 ;;      seta    %al
13549 ;;      testb   %al, %al
13550 ;;      sete    %al
13551
13552 (define_split
13553   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13554         (ne:QI (match_operator 1 "ix86_comparison_operator"
13555                  [(reg FLAGS_REG) (const_int 0)])
13556             (const_int 0)))]
13557   ""
13558   [(set (match_dup 0) (match_dup 1))]
13559 {
13560   PUT_MODE (operands[1], QImode);
13561 })
13562
13563 (define_split
13564   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13565         (ne:QI (match_operator 1 "ix86_comparison_operator"
13566                  [(reg FLAGS_REG) (const_int 0)])
13567             (const_int 0)))]
13568   ""
13569   [(set (match_dup 0) (match_dup 1))]
13570 {
13571   PUT_MODE (operands[1], QImode);
13572 })
13573
13574 (define_split
13575   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13576         (eq:QI (match_operator 1 "ix86_comparison_operator"
13577                  [(reg FLAGS_REG) (const_int 0)])
13578             (const_int 0)))]
13579   ""
13580   [(set (match_dup 0) (match_dup 1))]
13581 {
13582   rtx new_op1 = copy_rtx (operands[1]);
13583   operands[1] = new_op1;
13584   PUT_MODE (new_op1, QImode);
13585   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13586                                              GET_MODE (XEXP (new_op1, 0))));
13587
13588   /* Make sure that (a) the CCmode we have for the flags is strong
13589      enough for the reversed compare or (b) we have a valid FP compare.  */
13590   if (! ix86_comparison_operator (new_op1, VOIDmode))
13591     FAIL;
13592 })
13593
13594 (define_split
13595   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13596         (eq:QI (match_operator 1 "ix86_comparison_operator"
13597                  [(reg FLAGS_REG) (const_int 0)])
13598             (const_int 0)))]
13599   ""
13600   [(set (match_dup 0) (match_dup 1))]
13601 {
13602   rtx new_op1 = copy_rtx (operands[1]);
13603   operands[1] = new_op1;
13604   PUT_MODE (new_op1, QImode);
13605   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13606                                              GET_MODE (XEXP (new_op1, 0))));
13607
13608   /* Make sure that (a) the CCmode we have for the flags is strong
13609      enough for the reversed compare or (b) we have a valid FP compare.  */
13610   if (! ix86_comparison_operator (new_op1, VOIDmode))
13611     FAIL;
13612 })
13613
13614 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13615 ;; subsequent logical operations are used to imitate conditional moves.
13616 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13617 ;; it directly.
13618
13619 (define_insn "*sse_setccsf"
13620   [(set (match_operand:SF 0 "register_operand" "=x")
13621         (match_operator:SF 1 "sse_comparison_operator"
13622           [(match_operand:SF 2 "register_operand" "0")
13623            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13624   "TARGET_SSE"
13625   "cmp%D1ss\t{%3, %0|%0, %3}"
13626   [(set_attr "type" "ssecmp")
13627    (set_attr "mode" "SF")])
13628
13629 (define_insn "*sse_setccdf"
13630   [(set (match_operand:DF 0 "register_operand" "=x")
13631         (match_operator:DF 1 "sse_comparison_operator"
13632           [(match_operand:DF 2 "register_operand" "0")
13633            (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13634   "TARGET_SSE2"
13635   "cmp%D1sd\t{%3, %0|%0, %3}"
13636   [(set_attr "type" "ssecmp")
13637    (set_attr "mode" "DF")])
13638 \f
13639 ;; Basic conditional jump instructions.
13640 ;; We ignore the overflow flag for signed branch instructions.
13641
13642 ;; For all bCOND expanders, also expand the compare or test insn that
13643 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13644
13645 (define_expand "beq"
13646   [(set (pc)
13647         (if_then_else (match_dup 1)
13648                       (label_ref (match_operand 0 "" ""))
13649                       (pc)))]
13650   ""
13651   "ix86_expand_branch (EQ, operands[0]); DONE;")
13652
13653 (define_expand "bne"
13654   [(set (pc)
13655         (if_then_else (match_dup 1)
13656                       (label_ref (match_operand 0 "" ""))
13657                       (pc)))]
13658   ""
13659   "ix86_expand_branch (NE, operands[0]); DONE;")
13660
13661 (define_expand "bgt"
13662   [(set (pc)
13663         (if_then_else (match_dup 1)
13664                       (label_ref (match_operand 0 "" ""))
13665                       (pc)))]
13666   ""
13667   "ix86_expand_branch (GT, operands[0]); DONE;")
13668
13669 (define_expand "bgtu"
13670   [(set (pc)
13671         (if_then_else (match_dup 1)
13672                       (label_ref (match_operand 0 "" ""))
13673                       (pc)))]
13674   ""
13675   "ix86_expand_branch (GTU, operands[0]); DONE;")
13676
13677 (define_expand "blt"
13678   [(set (pc)
13679         (if_then_else (match_dup 1)
13680                       (label_ref (match_operand 0 "" ""))
13681                       (pc)))]
13682   ""
13683   "ix86_expand_branch (LT, operands[0]); DONE;")
13684
13685 (define_expand "bltu"
13686   [(set (pc)
13687         (if_then_else (match_dup 1)
13688                       (label_ref (match_operand 0 "" ""))
13689                       (pc)))]
13690   ""
13691   "ix86_expand_branch (LTU, operands[0]); DONE;")
13692
13693 (define_expand "bge"
13694   [(set (pc)
13695         (if_then_else (match_dup 1)
13696                       (label_ref (match_operand 0 "" ""))
13697                       (pc)))]
13698   ""
13699   "ix86_expand_branch (GE, operands[0]); DONE;")
13700
13701 (define_expand "bgeu"
13702   [(set (pc)
13703         (if_then_else (match_dup 1)
13704                       (label_ref (match_operand 0 "" ""))
13705                       (pc)))]
13706   ""
13707   "ix86_expand_branch (GEU, operands[0]); DONE;")
13708
13709 (define_expand "ble"
13710   [(set (pc)
13711         (if_then_else (match_dup 1)
13712                       (label_ref (match_operand 0 "" ""))
13713                       (pc)))]
13714   ""
13715   "ix86_expand_branch (LE, operands[0]); DONE;")
13716
13717 (define_expand "bleu"
13718   [(set (pc)
13719         (if_then_else (match_dup 1)
13720                       (label_ref (match_operand 0 "" ""))
13721                       (pc)))]
13722   ""
13723   "ix86_expand_branch (LEU, operands[0]); DONE;")
13724
13725 (define_expand "bunordered"
13726   [(set (pc)
13727         (if_then_else (match_dup 1)
13728                       (label_ref (match_operand 0 "" ""))
13729                       (pc)))]
13730   "TARGET_80387 || TARGET_SSE_MATH"
13731   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13732
13733 (define_expand "bordered"
13734   [(set (pc)
13735         (if_then_else (match_dup 1)
13736                       (label_ref (match_operand 0 "" ""))
13737                       (pc)))]
13738   "TARGET_80387 || TARGET_SSE_MATH"
13739   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13740
13741 (define_expand "buneq"
13742   [(set (pc)
13743         (if_then_else (match_dup 1)
13744                       (label_ref (match_operand 0 "" ""))
13745                       (pc)))]
13746   "TARGET_80387 || TARGET_SSE_MATH"
13747   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13748
13749 (define_expand "bunge"
13750   [(set (pc)
13751         (if_then_else (match_dup 1)
13752                       (label_ref (match_operand 0 "" ""))
13753                       (pc)))]
13754   "TARGET_80387 || TARGET_SSE_MATH"
13755   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13756
13757 (define_expand "bungt"
13758   [(set (pc)
13759         (if_then_else (match_dup 1)
13760                       (label_ref (match_operand 0 "" ""))
13761                       (pc)))]
13762   "TARGET_80387 || TARGET_SSE_MATH"
13763   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13764
13765 (define_expand "bunle"
13766   [(set (pc)
13767         (if_then_else (match_dup 1)
13768                       (label_ref (match_operand 0 "" ""))
13769                       (pc)))]
13770   "TARGET_80387 || TARGET_SSE_MATH"
13771   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13772
13773 (define_expand "bunlt"
13774   [(set (pc)
13775         (if_then_else (match_dup 1)
13776                       (label_ref (match_operand 0 "" ""))
13777                       (pc)))]
13778   "TARGET_80387 || TARGET_SSE_MATH"
13779   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13780
13781 (define_expand "bltgt"
13782   [(set (pc)
13783         (if_then_else (match_dup 1)
13784                       (label_ref (match_operand 0 "" ""))
13785                       (pc)))]
13786   "TARGET_80387 || TARGET_SSE_MATH"
13787   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13788
13789 (define_insn "*jcc_1"
13790   [(set (pc)
13791         (if_then_else (match_operator 1 "ix86_comparison_operator"
13792                                       [(reg FLAGS_REG) (const_int 0)])
13793                       (label_ref (match_operand 0 "" ""))
13794                       (pc)))]
13795   ""
13796   "%+j%C1\t%l0"
13797   [(set_attr "type" "ibr")
13798    (set_attr "modrm" "0")
13799    (set (attr "length")
13800            (if_then_else (and (ge (minus (match_dup 0) (pc))
13801                                   (const_int -126))
13802                               (lt (minus (match_dup 0) (pc))
13803                                   (const_int 128)))
13804              (const_int 2)
13805              (const_int 6)))])
13806
13807 (define_insn "*jcc_2"
13808   [(set (pc)
13809         (if_then_else (match_operator 1 "ix86_comparison_operator"
13810                                       [(reg FLAGS_REG) (const_int 0)])
13811                       (pc)
13812                       (label_ref (match_operand 0 "" ""))))]
13813   ""
13814   "%+j%c1\t%l0"
13815   [(set_attr "type" "ibr")
13816    (set_attr "modrm" "0")
13817    (set (attr "length")
13818            (if_then_else (and (ge (minus (match_dup 0) (pc))
13819                                   (const_int -126))
13820                               (lt (minus (match_dup 0) (pc))
13821                                   (const_int 128)))
13822              (const_int 2)
13823              (const_int 6)))])
13824
13825 ;; In general it is not safe to assume too much about CCmode registers,
13826 ;; so simplify-rtx stops when it sees a second one.  Under certain
13827 ;; conditions this is safe on x86, so help combine not create
13828 ;;
13829 ;;      seta    %al
13830 ;;      testb   %al, %al
13831 ;;      je      Lfoo
13832
13833 (define_split
13834   [(set (pc)
13835         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13836                                       [(reg FLAGS_REG) (const_int 0)])
13837                           (const_int 0))
13838                       (label_ref (match_operand 1 "" ""))
13839                       (pc)))]
13840   ""
13841   [(set (pc)
13842         (if_then_else (match_dup 0)
13843                       (label_ref (match_dup 1))
13844                       (pc)))]
13845 {
13846   PUT_MODE (operands[0], VOIDmode);
13847 })
13848
13849 (define_split
13850   [(set (pc)
13851         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13852                                       [(reg FLAGS_REG) (const_int 0)])
13853                           (const_int 0))
13854                       (label_ref (match_operand 1 "" ""))
13855                       (pc)))]
13856   ""
13857   [(set (pc)
13858         (if_then_else (match_dup 0)
13859                       (label_ref (match_dup 1))
13860                       (pc)))]
13861 {
13862   rtx new_op0 = copy_rtx (operands[0]);
13863   operands[0] = new_op0;
13864   PUT_MODE (new_op0, VOIDmode);
13865   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13866                                              GET_MODE (XEXP (new_op0, 0))));
13867
13868   /* Make sure that (a) the CCmode we have for the flags is strong
13869      enough for the reversed compare or (b) we have a valid FP compare.  */
13870   if (! ix86_comparison_operator (new_op0, VOIDmode))
13871     FAIL;
13872 })
13873
13874 ;; Define combination compare-and-branch fp compare instructions to use
13875 ;; during early optimization.  Splitting the operation apart early makes
13876 ;; for bad code when we want to reverse the operation.
13877
13878 (define_insn "*fp_jcc_1_mixed"
13879   [(set (pc)
13880         (if_then_else (match_operator 0 "comparison_operator"
13881                         [(match_operand 1 "register_operand" "f,x")
13882                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13883           (label_ref (match_operand 3 "" ""))
13884           (pc)))
13885    (clobber (reg:CCFP FPSR_REG))
13886    (clobber (reg:CCFP FLAGS_REG))]
13887   "TARGET_MIX_SSE_I387
13888    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13889    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13890    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13891   "#")
13892
13893 (define_insn "*fp_jcc_1_sse"
13894   [(set (pc)
13895         (if_then_else (match_operator 0 "comparison_operator"
13896                         [(match_operand 1 "register_operand" "x")
13897                          (match_operand 2 "nonimmediate_operand" "xm")])
13898           (label_ref (match_operand 3 "" ""))
13899           (pc)))
13900    (clobber (reg:CCFP FPSR_REG))
13901    (clobber (reg:CCFP FLAGS_REG))]
13902   "TARGET_SSE_MATH
13903    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13904    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13905    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13906   "#")
13907
13908 (define_insn "*fp_jcc_1_387"
13909   [(set (pc)
13910         (if_then_else (match_operator 0 "comparison_operator"
13911                         [(match_operand 1 "register_operand" "f")
13912                          (match_operand 2 "register_operand" "f")])
13913           (label_ref (match_operand 3 "" ""))
13914           (pc)))
13915    (clobber (reg:CCFP FPSR_REG))
13916    (clobber (reg:CCFP FLAGS_REG))]
13917   "TARGET_CMOVE && TARGET_80387
13918    && FLOAT_MODE_P (GET_MODE (operands[1]))
13919    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13920    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13921   "#")
13922
13923 (define_insn "*fp_jcc_2_mixed"
13924   [(set (pc)
13925         (if_then_else (match_operator 0 "comparison_operator"
13926                         [(match_operand 1 "register_operand" "f,x")
13927                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13928           (pc)
13929           (label_ref (match_operand 3 "" ""))))
13930    (clobber (reg:CCFP FPSR_REG))
13931    (clobber (reg:CCFP FLAGS_REG))]
13932   "TARGET_MIX_SSE_I387
13933    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13934    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13935    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13936   "#")
13937
13938 (define_insn "*fp_jcc_2_sse"
13939   [(set (pc)
13940         (if_then_else (match_operator 0 "comparison_operator"
13941                         [(match_operand 1 "register_operand" "x")
13942                          (match_operand 2 "nonimmediate_operand" "xm")])
13943           (pc)
13944           (label_ref (match_operand 3 "" ""))))
13945    (clobber (reg:CCFP FPSR_REG))
13946    (clobber (reg:CCFP FLAGS_REG))]
13947   "TARGET_SSE_MATH
13948    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13949    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13950    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13951   "#")
13952
13953 (define_insn "*fp_jcc_2_387"
13954   [(set (pc)
13955         (if_then_else (match_operator 0 "comparison_operator"
13956                         [(match_operand 1 "register_operand" "f")
13957                          (match_operand 2 "register_operand" "f")])
13958           (pc)
13959           (label_ref (match_operand 3 "" ""))))
13960    (clobber (reg:CCFP FPSR_REG))
13961    (clobber (reg:CCFP FLAGS_REG))]
13962   "TARGET_CMOVE && TARGET_80387
13963    && FLOAT_MODE_P (GET_MODE (operands[1]))
13964    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13965    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13966   "#")
13967
13968 (define_insn "*fp_jcc_3_387"
13969   [(set (pc)
13970         (if_then_else (match_operator 0 "comparison_operator"
13971                         [(match_operand 1 "register_operand" "f")
13972                          (match_operand 2 "nonimmediate_operand" "fm")])
13973           (label_ref (match_operand 3 "" ""))
13974           (pc)))
13975    (clobber (reg:CCFP FPSR_REG))
13976    (clobber (reg:CCFP FLAGS_REG))
13977    (clobber (match_scratch:HI 4 "=a"))]
13978   "TARGET_80387
13979    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13980    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13981    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13982    && SELECT_CC_MODE (GET_CODE (operands[0]),
13983                       operands[1], operands[2]) == CCFPmode
13984    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13985   "#")
13986
13987 (define_insn "*fp_jcc_4_387"
13988   [(set (pc)
13989         (if_then_else (match_operator 0 "comparison_operator"
13990                         [(match_operand 1 "register_operand" "f")
13991                          (match_operand 2 "nonimmediate_operand" "fm")])
13992           (pc)
13993           (label_ref (match_operand 3 "" ""))))
13994    (clobber (reg:CCFP FPSR_REG))
13995    (clobber (reg:CCFP FLAGS_REG))
13996    (clobber (match_scratch:HI 4 "=a"))]
13997   "TARGET_80387
13998    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13999    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14000    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14001    && SELECT_CC_MODE (GET_CODE (operands[0]),
14002                       operands[1], operands[2]) == CCFPmode
14003    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14004   "#")
14005
14006 (define_insn "*fp_jcc_5_387"
14007   [(set (pc)
14008         (if_then_else (match_operator 0 "comparison_operator"
14009                         [(match_operand 1 "register_operand" "f")
14010                          (match_operand 2 "register_operand" "f")])
14011           (label_ref (match_operand 3 "" ""))
14012           (pc)))
14013    (clobber (reg:CCFP FPSR_REG))
14014    (clobber (reg:CCFP FLAGS_REG))
14015    (clobber (match_scratch:HI 4 "=a"))]
14016   "TARGET_80387
14017    && FLOAT_MODE_P (GET_MODE (operands[1]))
14018    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14019    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14020   "#")
14021
14022 (define_insn "*fp_jcc_6_387"
14023   [(set (pc)
14024         (if_then_else (match_operator 0 "comparison_operator"
14025                         [(match_operand 1 "register_operand" "f")
14026                          (match_operand 2 "register_operand" "f")])
14027           (pc)
14028           (label_ref (match_operand 3 "" ""))))
14029    (clobber (reg:CCFP FPSR_REG))
14030    (clobber (reg:CCFP FLAGS_REG))
14031    (clobber (match_scratch:HI 4 "=a"))]
14032   "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_7_387"
14039   [(set (pc)
14040         (if_then_else (match_operator 0 "comparison_operator"
14041                         [(match_operand 1 "register_operand" "f")
14042                          (match_operand 2 "const0_operand" "X")])
14043           (label_ref (match_operand 3 "" ""))
14044           (pc)))
14045    (clobber (reg:CCFP FPSR_REG))
14046    (clobber (reg:CCFP FLAGS_REG))
14047    (clobber (match_scratch:HI 4 "=a"))]
14048   "TARGET_80387
14049    && FLOAT_MODE_P (GET_MODE (operands[1]))
14050    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14051    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14052    && SELECT_CC_MODE (GET_CODE (operands[0]),
14053                       operands[1], operands[2]) == CCFPmode
14054    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14055   "#")
14056
14057 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14058 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14059 ;; with a precedence over other operators and is always put in the first
14060 ;; place. Swap condition and operands to match ficom instruction.
14061
14062 (define_insn "*fp_jcc_8<mode>_387"
14063   [(set (pc)
14064         (if_then_else (match_operator 0 "comparison_operator"
14065                         [(match_operator 1 "float_operator"
14066                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14067                            (match_operand 3 "register_operand" "f,f")])
14068           (label_ref (match_operand 4 "" ""))
14069           (pc)))
14070    (clobber (reg:CCFP FPSR_REG))
14071    (clobber (reg:CCFP FLAGS_REG))
14072    (clobber (match_scratch:HI 5 "=a,a"))]
14073   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14074    && FLOAT_MODE_P (GET_MODE (operands[3]))
14075    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14076    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14077    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14078    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14079   "#")
14080
14081 (define_split
14082   [(set (pc)
14083         (if_then_else (match_operator 0 "comparison_operator"
14084                         [(match_operand 1 "register_operand" "")
14085                          (match_operand 2 "nonimmediate_operand" "")])
14086           (match_operand 3 "" "")
14087           (match_operand 4 "" "")))
14088    (clobber (reg:CCFP FPSR_REG))
14089    (clobber (reg:CCFP FLAGS_REG))]
14090   "reload_completed"
14091   [(const_int 0)]
14092 {
14093   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14094                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14095   DONE;
14096 })
14097
14098 (define_split
14099   [(set (pc)
14100         (if_then_else (match_operator 0 "comparison_operator"
14101                         [(match_operand 1 "register_operand" "")
14102                          (match_operand 2 "general_operand" "")])
14103           (match_operand 3 "" "")
14104           (match_operand 4 "" "")))
14105    (clobber (reg:CCFP FPSR_REG))
14106    (clobber (reg:CCFP FLAGS_REG))
14107    (clobber (match_scratch:HI 5 "=a"))]
14108   "reload_completed"
14109   [(const_int 0)]
14110 {
14111   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14112                         operands[3], operands[4], operands[5], NULL_RTX);
14113   DONE;
14114 })
14115
14116 (define_split
14117   [(set (pc)
14118         (if_then_else (match_operator 0 "comparison_operator"
14119                         [(match_operator 1 "float_operator"
14120                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14121                            (match_operand 3 "register_operand" "")])
14122           (match_operand 4 "" "")
14123           (match_operand 5 "" "")))
14124    (clobber (reg:CCFP FPSR_REG))
14125    (clobber (reg:CCFP FLAGS_REG))
14126    (clobber (match_scratch:HI 6 "=a"))]
14127   "reload_completed"
14128   [(const_int 0)]
14129 {
14130   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14131   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14132                         operands[3], operands[7],
14133                         operands[4], operands[5], operands[6], NULL_RTX);
14134   DONE;
14135 })
14136
14137 ;; %%% Kill this when reload knows how to do it.
14138 (define_split
14139   [(set (pc)
14140         (if_then_else (match_operator 0 "comparison_operator"
14141                         [(match_operator 1 "float_operator"
14142                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14143                            (match_operand 3 "register_operand" "")])
14144           (match_operand 4 "" "")
14145           (match_operand 5 "" "")))
14146    (clobber (reg:CCFP FPSR_REG))
14147    (clobber (reg:CCFP FLAGS_REG))
14148    (clobber (match_scratch:HI 6 "=a"))]
14149   "reload_completed"
14150   [(const_int 0)]
14151 {
14152   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14153   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14154   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14155                         operands[3], operands[7],
14156                         operands[4], operands[5], operands[6], operands[2]);
14157   DONE;
14158 })
14159 \f
14160 ;; Unconditional and other jump instructions
14161
14162 (define_insn "jump"
14163   [(set (pc)
14164         (label_ref (match_operand 0 "" "")))]
14165   ""
14166   "jmp\t%l0"
14167   [(set_attr "type" "ibr")
14168    (set (attr "length")
14169            (if_then_else (and (ge (minus (match_dup 0) (pc))
14170                                   (const_int -126))
14171                               (lt (minus (match_dup 0) (pc))
14172                                   (const_int 128)))
14173              (const_int 2)
14174              (const_int 5)))
14175    (set_attr "modrm" "0")])
14176
14177 (define_expand "indirect_jump"
14178   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14179   ""
14180   "")
14181
14182 (define_insn "*indirect_jump"
14183   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14184   "!TARGET_64BIT"
14185   "jmp\t%A0"
14186   [(set_attr "type" "ibr")
14187    (set_attr "length_immediate" "0")])
14188
14189 (define_insn "*indirect_jump_rtx64"
14190   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14191   "TARGET_64BIT"
14192   "jmp\t%A0"
14193   [(set_attr "type" "ibr")
14194    (set_attr "length_immediate" "0")])
14195
14196 (define_expand "tablejump"
14197   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14198               (use (label_ref (match_operand 1 "" "")))])]
14199   ""
14200 {
14201   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14202      relative.  Convert the relative address to an absolute address.  */
14203   if (flag_pic)
14204     {
14205       rtx op0, op1;
14206       enum rtx_code code;
14207
14208       /* We can't use @GOTOFF for text labels on VxWorks;
14209          see gotoff_operand.  */
14210       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14211         {
14212           code = PLUS;
14213           op0 = operands[0];
14214           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14215         }
14216       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14217         {
14218           code = PLUS;
14219           op0 = operands[0];
14220           op1 = pic_offset_table_rtx;
14221         }
14222       else
14223         {
14224           code = MINUS;
14225           op0 = pic_offset_table_rtx;
14226           op1 = operands[0];
14227         }
14228
14229       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14230                                          OPTAB_DIRECT);
14231     }
14232 })
14233
14234 (define_insn "*tablejump_1"
14235   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14236    (use (label_ref (match_operand 1 "" "")))]
14237   "!TARGET_64BIT"
14238   "jmp\t%A0"
14239   [(set_attr "type" "ibr")
14240    (set_attr "length_immediate" "0")])
14241
14242 (define_insn "*tablejump_1_rtx64"
14243   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14244    (use (label_ref (match_operand 1 "" "")))]
14245   "TARGET_64BIT"
14246   "jmp\t%A0"
14247   [(set_attr "type" "ibr")
14248    (set_attr "length_immediate" "0")])
14249 \f
14250 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14251
14252 (define_peephole2
14253   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14254    (set (match_operand:QI 1 "register_operand" "")
14255         (match_operator:QI 2 "ix86_comparison_operator"
14256           [(reg FLAGS_REG) (const_int 0)]))
14257    (set (match_operand 3 "q_regs_operand" "")
14258         (zero_extend (match_dup 1)))]
14259   "(peep2_reg_dead_p (3, operands[1])
14260     || operands_match_p (operands[1], operands[3]))
14261    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14262   [(set (match_dup 4) (match_dup 0))
14263    (set (strict_low_part (match_dup 5))
14264         (match_dup 2))]
14265 {
14266   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14267   operands[5] = gen_lowpart (QImode, operands[3]);
14268   ix86_expand_clear (operands[3]);
14269 })
14270
14271 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14272
14273 (define_peephole2
14274   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14275    (set (match_operand:QI 1 "register_operand" "")
14276         (match_operator:QI 2 "ix86_comparison_operator"
14277           [(reg FLAGS_REG) (const_int 0)]))
14278    (parallel [(set (match_operand 3 "q_regs_operand" "")
14279                    (zero_extend (match_dup 1)))
14280               (clobber (reg:CC FLAGS_REG))])]
14281   "(peep2_reg_dead_p (3, operands[1])
14282     || operands_match_p (operands[1], operands[3]))
14283    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14284   [(set (match_dup 4) (match_dup 0))
14285    (set (strict_low_part (match_dup 5))
14286         (match_dup 2))]
14287 {
14288   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14289   operands[5] = gen_lowpart (QImode, operands[3]);
14290   ix86_expand_clear (operands[3]);
14291 })
14292 \f
14293 ;; Call instructions.
14294
14295 ;; The predicates normally associated with named expanders are not properly
14296 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14297 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14298
14299 ;; Call subroutine returning no value.
14300
14301 (define_expand "call_pop"
14302   [(parallel [(call (match_operand:QI 0 "" "")
14303                     (match_operand:SI 1 "" ""))
14304               (set (reg:SI SP_REG)
14305                    (plus:SI (reg:SI SP_REG)
14306                             (match_operand:SI 3 "" "")))])]
14307   "!TARGET_64BIT"
14308 {
14309   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14310   DONE;
14311 })
14312
14313 (define_insn "*call_pop_0"
14314   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14315          (match_operand:SI 1 "" ""))
14316    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14317                             (match_operand:SI 2 "immediate_operand" "")))]
14318   "!TARGET_64BIT"
14319 {
14320   if (SIBLING_CALL_P (insn))
14321     return "jmp\t%P0";
14322   else
14323     return "call\t%P0";
14324 }
14325   [(set_attr "type" "call")])
14326
14327 (define_insn "*call_pop_1"
14328   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14329          (match_operand:SI 1 "" ""))
14330    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14331                             (match_operand:SI 2 "immediate_operand" "i")))]
14332   "!TARGET_64BIT"
14333 {
14334   if (constant_call_address_operand (operands[0], Pmode))
14335     {
14336       if (SIBLING_CALL_P (insn))
14337         return "jmp\t%P0";
14338       else
14339         return "call\t%P0";
14340     }
14341   if (SIBLING_CALL_P (insn))
14342     return "jmp\t%A0";
14343   else
14344     return "call\t%A0";
14345 }
14346   [(set_attr "type" "call")])
14347
14348 (define_expand "call"
14349   [(call (match_operand:QI 0 "" "")
14350          (match_operand 1 "" ""))
14351    (use (match_operand 2 "" ""))]
14352   ""
14353 {
14354   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14355   DONE;
14356 })
14357
14358 (define_expand "sibcall"
14359   [(call (match_operand:QI 0 "" "")
14360          (match_operand 1 "" ""))
14361    (use (match_operand 2 "" ""))]
14362   ""
14363 {
14364   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14365   DONE;
14366 })
14367
14368 (define_insn "*call_0"
14369   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14370          (match_operand 1 "" ""))]
14371   ""
14372 {
14373   if (SIBLING_CALL_P (insn))
14374     return "jmp\t%P0";
14375   else
14376     return "call\t%P0";
14377 }
14378   [(set_attr "type" "call")])
14379
14380 (define_insn "*call_1"
14381   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14382          (match_operand 1 "" ""))]
14383   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14384 {
14385   if (constant_call_address_operand (operands[0], Pmode))
14386     return "call\t%P0";
14387   return "call\t%A0";
14388 }
14389   [(set_attr "type" "call")])
14390
14391 (define_insn "*sibcall_1"
14392   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14393          (match_operand 1 "" ""))]
14394   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14395 {
14396   if (constant_call_address_operand (operands[0], Pmode))
14397     return "jmp\t%P0";
14398   return "jmp\t%A0";
14399 }
14400   [(set_attr "type" "call")])
14401
14402 (define_insn "*call_1_rex64"
14403   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14404          (match_operand 1 "" ""))]
14405   "!SIBLING_CALL_P (insn) && TARGET_64BIT
14406    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14407 {
14408   if (constant_call_address_operand (operands[0], Pmode))
14409     return "call\t%P0";
14410   return "call\t%A0";
14411 }
14412   [(set_attr "type" "call")])
14413
14414 (define_insn "*call_1_rex64_large"
14415   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14416          (match_operand 1 "" ""))]
14417   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14418   "call\t%A0"
14419   [(set_attr "type" "call")])
14420
14421 (define_insn "*sibcall_1_rex64"
14422   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14423          (match_operand 1 "" ""))]
14424   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14425   "jmp\t%P0"
14426   [(set_attr "type" "call")])
14427
14428 (define_insn "*sibcall_1_rex64_v"
14429   [(call (mem:QI (reg:DI R11_REG))
14430          (match_operand 0 "" ""))]
14431   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14432   "jmp\t*%%r11"
14433   [(set_attr "type" "call")])
14434
14435
14436 ;; Call subroutine, returning value in operand 0
14437
14438 (define_expand "call_value_pop"
14439   [(parallel [(set (match_operand 0 "" "")
14440                    (call (match_operand:QI 1 "" "")
14441                          (match_operand:SI 2 "" "")))
14442               (set (reg:SI SP_REG)
14443                    (plus:SI (reg:SI SP_REG)
14444                             (match_operand:SI 4 "" "")))])]
14445   "!TARGET_64BIT"
14446 {
14447   ix86_expand_call (operands[0], operands[1], operands[2],
14448                     operands[3], operands[4], 0);
14449   DONE;
14450 })
14451
14452 (define_expand "call_value"
14453   [(set (match_operand 0 "" "")
14454         (call (match_operand:QI 1 "" "")
14455               (match_operand:SI 2 "" "")))
14456    (use (match_operand:SI 3 "" ""))]
14457   ;; Operand 2 not used on the i386.
14458   ""
14459 {
14460   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14461   DONE;
14462 })
14463
14464 (define_expand "sibcall_value"
14465   [(set (match_operand 0 "" "")
14466         (call (match_operand:QI 1 "" "")
14467               (match_operand:SI 2 "" "")))
14468    (use (match_operand:SI 3 "" ""))]
14469   ;; Operand 2 not used on the i386.
14470   ""
14471 {
14472   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14473   DONE;
14474 })
14475
14476 ;; Call subroutine returning any type.
14477
14478 (define_expand "untyped_call"
14479   [(parallel [(call (match_operand 0 "" "")
14480                     (const_int 0))
14481               (match_operand 1 "" "")
14482               (match_operand 2 "" "")])]
14483   ""
14484 {
14485   int i;
14486
14487   /* In order to give reg-stack an easier job in validating two
14488      coprocessor registers as containing a possible return value,
14489      simply pretend the untyped call returns a complex long double
14490      value.  */
14491
14492   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14493                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14494                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14495                     NULL, 0);
14496
14497   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14498     {
14499       rtx set = XVECEXP (operands[2], 0, i);
14500       emit_move_insn (SET_DEST (set), SET_SRC (set));
14501     }
14502
14503   /* The optimizer does not know that the call sets the function value
14504      registers we stored in the result block.  We avoid problems by
14505      claiming that all hard registers are used and clobbered at this
14506      point.  */
14507   emit_insn (gen_blockage (const0_rtx));
14508
14509   DONE;
14510 })
14511 \f
14512 ;; Prologue and epilogue instructions
14513
14514 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14515 ;; all of memory.  This blocks insns from being moved across this point.
14516
14517 (define_insn "blockage"
14518   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14519   ""
14520   ""
14521   [(set_attr "length" "0")])
14522
14523 ;; Insn emitted into the body of a function to return from a function.
14524 ;; This is only done if the function's epilogue is known to be simple.
14525 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14526
14527 (define_expand "return"
14528   [(return)]
14529   "ix86_can_use_return_insn_p ()"
14530 {
14531   if (current_function_pops_args)
14532     {
14533       rtx popc = GEN_INT (current_function_pops_args);
14534       emit_jump_insn (gen_return_pop_internal (popc));
14535       DONE;
14536     }
14537 })
14538
14539 (define_insn "return_internal"
14540   [(return)]
14541   "reload_completed"
14542   "ret"
14543   [(set_attr "length" "1")
14544    (set_attr "length_immediate" "0")
14545    (set_attr "modrm" "0")])
14546
14547 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14548 ;; instruction Athlon and K8 have.
14549
14550 (define_insn "return_internal_long"
14551   [(return)
14552    (unspec [(const_int 0)] UNSPEC_REP)]
14553   "reload_completed"
14554   "rep {;} ret"
14555   [(set_attr "length" "1")
14556    (set_attr "length_immediate" "0")
14557    (set_attr "prefix_rep" "1")
14558    (set_attr "modrm" "0")])
14559
14560 (define_insn "return_pop_internal"
14561   [(return)
14562    (use (match_operand:SI 0 "const_int_operand" ""))]
14563   "reload_completed"
14564   "ret\t%0"
14565   [(set_attr "length" "3")
14566    (set_attr "length_immediate" "2")
14567    (set_attr "modrm" "0")])
14568
14569 (define_insn "return_indirect_internal"
14570   [(return)
14571    (use (match_operand:SI 0 "register_operand" "r"))]
14572   "reload_completed"
14573   "jmp\t%A0"
14574   [(set_attr "type" "ibr")
14575    (set_attr "length_immediate" "0")])
14576
14577 (define_insn "nop"
14578   [(const_int 0)]
14579   ""
14580   "nop"
14581   [(set_attr "length" "1")
14582    (set_attr "length_immediate" "0")
14583    (set_attr "modrm" "0")])
14584
14585 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14586 ;; branch prediction penalty for the third jump in a 16-byte
14587 ;; block on K8.
14588
14589 (define_insn "align"
14590   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14591   ""
14592 {
14593 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14594   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14595 #else
14596   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14597      The align insn is used to avoid 3 jump instructions in the row to improve
14598      branch prediction and the benefits hardly outweigh the cost of extra 8
14599      nops on the average inserted by full alignment pseudo operation.  */
14600 #endif
14601   return "";
14602 }
14603   [(set_attr "length" "16")])
14604
14605 (define_expand "prologue"
14606   [(const_int 1)]
14607   ""
14608   "ix86_expand_prologue (); DONE;")
14609
14610 (define_insn "set_got"
14611   [(set (match_operand:SI 0 "register_operand" "=r")
14612         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14613    (clobber (reg:CC FLAGS_REG))]
14614   "!TARGET_64BIT"
14615   { return output_set_got (operands[0], NULL_RTX); }
14616   [(set_attr "type" "multi")
14617    (set_attr "length" "12")])
14618
14619 (define_insn "set_got_labelled"
14620   [(set (match_operand:SI 0 "register_operand" "=r")
14621         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14622          UNSPEC_SET_GOT))
14623    (clobber (reg:CC FLAGS_REG))]
14624   "!TARGET_64BIT"
14625   { return output_set_got (operands[0], operands[1]); }
14626   [(set_attr "type" "multi")
14627    (set_attr "length" "12")])
14628
14629 (define_insn "set_got_rex64"
14630   [(set (match_operand:DI 0 "register_operand" "=r")
14631         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14632   "TARGET_64BIT"
14633   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14634   [(set_attr "type" "lea")
14635    (set_attr "length" "6")])
14636
14637 (define_insn "set_rip_rex64"
14638   [(set (match_operand:DI 0 "register_operand" "=r")
14639         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14640   "TARGET_64BIT"
14641   "lea{q}\t%l1(%%rip), %0"
14642   [(set_attr "type" "lea")
14643    (set_attr "length" "6")])
14644
14645 (define_insn "set_got_offset_rex64"
14646   [(set (match_operand:DI 0 "register_operand" "=r")
14647         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
14648   "TARGET_64BIT"
14649   "movabs{q}\t$_GLOBAL_OFFSET_TABLE_-%l1, %0"
14650   [(set_attr "type" "imov")
14651    (set_attr "length" "11")])
14652
14653 (define_expand "epilogue"
14654   [(const_int 1)]
14655   ""
14656   "ix86_expand_epilogue (1); DONE;")
14657
14658 (define_expand "sibcall_epilogue"
14659   [(const_int 1)]
14660   ""
14661   "ix86_expand_epilogue (0); DONE;")
14662
14663 (define_expand "eh_return"
14664   [(use (match_operand 0 "register_operand" ""))]
14665   ""
14666 {
14667   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14668
14669   /* Tricky bit: we write the address of the handler to which we will
14670      be returning into someone else's stack frame, one word below the
14671      stack address we wish to restore.  */
14672   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14673   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14674   tmp = gen_rtx_MEM (Pmode, tmp);
14675   emit_move_insn (tmp, ra);
14676
14677   if (Pmode == SImode)
14678     emit_jump_insn (gen_eh_return_si (sa));
14679   else
14680     emit_jump_insn (gen_eh_return_di (sa));
14681   emit_barrier ();
14682   DONE;
14683 })
14684
14685 (define_insn_and_split "eh_return_si"
14686   [(set (pc)
14687         (unspec [(match_operand:SI 0 "register_operand" "c")]
14688                  UNSPEC_EH_RETURN))]
14689   "!TARGET_64BIT"
14690   "#"
14691   "reload_completed"
14692   [(const_int 1)]
14693   "ix86_expand_epilogue (2); DONE;")
14694
14695 (define_insn_and_split "eh_return_di"
14696   [(set (pc)
14697         (unspec [(match_operand:DI 0 "register_operand" "c")]
14698                  UNSPEC_EH_RETURN))]
14699   "TARGET_64BIT"
14700   "#"
14701   "reload_completed"
14702   [(const_int 1)]
14703   "ix86_expand_epilogue (2); DONE;")
14704
14705 (define_insn "leave"
14706   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14707    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14708    (clobber (mem:BLK (scratch)))]
14709   "!TARGET_64BIT"
14710   "leave"
14711   [(set_attr "type" "leave")])
14712
14713 (define_insn "leave_rex64"
14714   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14715    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14716    (clobber (mem:BLK (scratch)))]
14717   "TARGET_64BIT"
14718   "leave"
14719   [(set_attr "type" "leave")])
14720 \f
14721 (define_expand "ffssi2"
14722   [(parallel
14723      [(set (match_operand:SI 0 "register_operand" "")
14724            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14725       (clobber (match_scratch:SI 2 ""))
14726       (clobber (reg:CC FLAGS_REG))])]
14727   ""
14728   "")
14729
14730 (define_insn_and_split "*ffs_cmove"
14731   [(set (match_operand:SI 0 "register_operand" "=r")
14732         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14733    (clobber (match_scratch:SI 2 "=&r"))
14734    (clobber (reg:CC FLAGS_REG))]
14735   "TARGET_CMOVE"
14736   "#"
14737   "&& reload_completed"
14738   [(set (match_dup 2) (const_int -1))
14739    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14740               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14741    (set (match_dup 0) (if_then_else:SI
14742                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14743                         (match_dup 2)
14744                         (match_dup 0)))
14745    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14746               (clobber (reg:CC FLAGS_REG))])]
14747   "")
14748
14749 (define_insn_and_split "*ffs_no_cmove"
14750   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14751         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14752    (clobber (match_scratch:SI 2 "=&q"))
14753    (clobber (reg:CC FLAGS_REG))]
14754   ""
14755   "#"
14756   "reload_completed"
14757   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14758               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14759    (set (strict_low_part (match_dup 3))
14760         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14761    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14762               (clobber (reg:CC FLAGS_REG))])
14763    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14764               (clobber (reg:CC FLAGS_REG))])
14765    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14766               (clobber (reg:CC FLAGS_REG))])]
14767 {
14768   operands[3] = gen_lowpart (QImode, operands[2]);
14769   ix86_expand_clear (operands[2]);
14770 })
14771
14772 (define_insn "*ffssi_1"
14773   [(set (reg:CCZ FLAGS_REG)
14774         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14775                      (const_int 0)))
14776    (set (match_operand:SI 0 "register_operand" "=r")
14777         (ctz:SI (match_dup 1)))]
14778   ""
14779   "bsf{l}\t{%1, %0|%0, %1}"
14780   [(set_attr "prefix_0f" "1")])
14781
14782 (define_expand "ffsdi2"
14783   [(parallel
14784      [(set (match_operand:DI 0 "register_operand" "")
14785            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14786       (clobber (match_scratch:DI 2 ""))
14787       (clobber (reg:CC FLAGS_REG))])]
14788   "TARGET_64BIT && TARGET_CMOVE"
14789   "")
14790
14791 (define_insn_and_split "*ffs_rex64"
14792   [(set (match_operand:DI 0 "register_operand" "=r")
14793         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14794    (clobber (match_scratch:DI 2 "=&r"))
14795    (clobber (reg:CC FLAGS_REG))]
14796   "TARGET_64BIT && TARGET_CMOVE"
14797   "#"
14798   "&& reload_completed"
14799   [(set (match_dup 2) (const_int -1))
14800    (parallel [(set (reg:CCZ FLAGS_REG)
14801                    (compare:CCZ (match_dup 1) (const_int 0)))
14802               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14803    (set (match_dup 0) (if_then_else:DI
14804                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14805                         (match_dup 2)
14806                         (match_dup 0)))
14807    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14808               (clobber (reg:CC FLAGS_REG))])]
14809   "")
14810
14811 (define_insn "*ffsdi_1"
14812   [(set (reg:CCZ FLAGS_REG)
14813         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14814                      (const_int 0)))
14815    (set (match_operand:DI 0 "register_operand" "=r")
14816         (ctz:DI (match_dup 1)))]
14817   "TARGET_64BIT"
14818   "bsf{q}\t{%1, %0|%0, %1}"
14819   [(set_attr "prefix_0f" "1")])
14820
14821 (define_insn "ctzsi2"
14822   [(set (match_operand:SI 0 "register_operand" "=r")
14823         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14824    (clobber (reg:CC FLAGS_REG))]
14825   ""
14826   "bsf{l}\t{%1, %0|%0, %1}"
14827   [(set_attr "prefix_0f" "1")])
14828
14829 (define_insn "ctzdi2"
14830   [(set (match_operand:DI 0 "register_operand" "=r")
14831         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14832    (clobber (reg:CC FLAGS_REG))]
14833   "TARGET_64BIT"
14834   "bsf{q}\t{%1, %0|%0, %1}"
14835   [(set_attr "prefix_0f" "1")])
14836
14837 (define_expand "clzsi2"
14838   [(parallel
14839      [(set (match_operand:SI 0 "register_operand" "")
14840            (minus:SI (const_int 31)
14841                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14842       (clobber (reg:CC FLAGS_REG))])
14843    (parallel
14844      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14845       (clobber (reg:CC FLAGS_REG))])]
14846   ""
14847 {
14848   if (TARGET_ABM)
14849     {
14850       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14851       DONE;
14852     }
14853 })
14854
14855 (define_insn "clzsi2_abm"
14856   [(set (match_operand:SI 0 "register_operand" "=r")
14857         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14858    (clobber (reg:CC FLAGS_REG))]
14859   "TARGET_ABM"
14860   "lzcnt{l}\t{%1, %0|%0, %1}"
14861   [(set_attr "prefix_rep" "1")
14862    (set_attr "type" "bitmanip")
14863    (set_attr "mode" "SI")])
14864
14865 (define_insn "*bsr"
14866   [(set (match_operand:SI 0 "register_operand" "=r")
14867         (minus:SI (const_int 31)
14868                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14869    (clobber (reg:CC FLAGS_REG))]
14870   ""
14871   "bsr{l}\t{%1, %0|%0, %1}"
14872   [(set_attr "prefix_0f" "1")
14873    (set_attr "mode" "SI")])
14874
14875 (define_insn "popcountsi2"
14876   [(set (match_operand:SI 0 "register_operand" "=r")
14877         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14878    (clobber (reg:CC FLAGS_REG))]
14879   "TARGET_POPCNT"
14880   "popcnt{l}\t{%1, %0|%0, %1}"
14881   [(set_attr "prefix_rep" "1")
14882    (set_attr "type" "bitmanip")
14883    (set_attr "mode" "SI")])
14884
14885 (define_insn "*popcountsi2_cmp"
14886   [(set (reg FLAGS_REG)
14887         (compare
14888           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14889           (const_int 0)))
14890    (set (match_operand:SI 0 "register_operand" "=r")
14891         (popcount:SI (match_dup 1)))]
14892   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14893   "popcnt{l}\t{%1, %0|%0, %1}"
14894   [(set_attr "prefix_rep" "1")
14895    (set_attr "type" "bitmanip")
14896    (set_attr "mode" "SI")])
14897
14898 (define_insn "*popcountsi2_cmp_zext"
14899   [(set (reg FLAGS_REG)
14900         (compare
14901           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14902           (const_int 0)))
14903    (set (match_operand:DI 0 "register_operand" "=r")
14904         (zero_extend:DI(popcount:SI (match_dup 1))))]
14905   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14906   "popcnt{l}\t{%1, %0|%0, %1}"
14907   [(set_attr "prefix_rep" "1")
14908    (set_attr "type" "bitmanip")
14909    (set_attr "mode" "SI")])
14910
14911 (define_expand "bswapsi2"
14912   [(set (match_operand:SI 0 "register_operand" "")
14913         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
14914   ""
14915 {
14916   if (!TARGET_BSWAP)
14917     {
14918       rtx x = operands[0];
14919
14920       emit_move_insn (x, operands[1]);
14921       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14922       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14923       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14924       DONE;
14925     }
14926 })
14927
14928 (define_insn "*bswapsi_1"
14929   [(set (match_operand:SI 0 "register_operand" "=r")
14930         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
14931   "TARGET_BSWAP"
14932   "bswap\t%0"
14933   [(set_attr "prefix_0f" "1")
14934    (set_attr "length" "2")])
14935
14936 (define_insn "*bswaphi_lowpart_1"
14937   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14938         (bswap:HI (match_dup 0)))
14939    (clobber (reg:CC FLAGS_REG))]
14940   "TARGET_USE_XCHGB || optimize_size"
14941   "@
14942     xchg{b}\t{%h0, %b0|%b0, %h0}
14943     rol{w}\t{$8, %0|%0, 8}"
14944   [(set_attr "length" "2,4")
14945    (set_attr "mode" "QI,HI")])
14946
14947 (define_insn "bswaphi_lowpart"
14948   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
14949         (bswap:HI (match_dup 0)))
14950    (clobber (reg:CC FLAGS_REG))]
14951   ""
14952   "rol{w}\t{$8, %0|%0, 8}"
14953   [(set_attr "length" "4")
14954    (set_attr "mode" "HI")])
14955
14956 (define_insn "bswapdi2"
14957   [(set (match_operand:DI 0 "register_operand" "=r")
14958         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
14959   "TARGET_64BIT"
14960   "bswap\t%0"
14961   [(set_attr "prefix_0f" "1")
14962    (set_attr "length" "3")])
14963
14964 (define_expand "clzdi2"
14965   [(parallel
14966      [(set (match_operand:DI 0 "register_operand" "")
14967            (minus:DI (const_int 63)
14968                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14969       (clobber (reg:CC FLAGS_REG))])
14970    (parallel
14971      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14972       (clobber (reg:CC FLAGS_REG))])]
14973   "TARGET_64BIT"
14974 {
14975   if (TARGET_ABM)
14976     {
14977       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14978       DONE;
14979     }
14980 })
14981
14982 (define_insn "clzdi2_abm"
14983   [(set (match_operand:DI 0 "register_operand" "=r")
14984         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14985    (clobber (reg:CC FLAGS_REG))]
14986   "TARGET_64BIT && TARGET_ABM"
14987   "lzcnt{q}\t{%1, %0|%0, %1}"
14988   [(set_attr "prefix_rep" "1")
14989    (set_attr "type" "bitmanip")
14990    (set_attr "mode" "DI")])
14991
14992 (define_insn "*bsr_rex64"
14993   [(set (match_operand:DI 0 "register_operand" "=r")
14994         (minus:DI (const_int 63)
14995                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14996    (clobber (reg:CC FLAGS_REG))]
14997   "TARGET_64BIT"
14998   "bsr{q}\t{%1, %0|%0, %1}"
14999   [(set_attr "prefix_0f" "1")
15000    (set_attr "mode" "DI")])
15001
15002 (define_insn "popcountdi2"
15003   [(set (match_operand:DI 0 "register_operand" "=r")
15004         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15005    (clobber (reg:CC FLAGS_REG))]
15006   "TARGET_64BIT && TARGET_POPCNT"
15007   "popcnt{q}\t{%1, %0|%0, %1}"
15008   [(set_attr "prefix_rep" "1")
15009    (set_attr "type" "bitmanip")
15010    (set_attr "mode" "DI")])
15011
15012 (define_insn "*popcountdi2_cmp"
15013   [(set (reg FLAGS_REG)
15014         (compare
15015           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15016           (const_int 0)))
15017    (set (match_operand:DI 0 "register_operand" "=r")
15018         (popcount:DI (match_dup 1)))]
15019   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15020   "popcnt{q}\t{%1, %0|%0, %1}"
15021   [(set_attr "prefix_rep" "1")
15022    (set_attr "type" "bitmanip")
15023    (set_attr "mode" "DI")])
15024
15025 (define_expand "clzhi2"
15026   [(parallel
15027      [(set (match_operand:HI 0 "register_operand" "")
15028            (minus:HI (const_int 15)
15029                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15030       (clobber (reg:CC FLAGS_REG))])
15031    (parallel
15032      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15033       (clobber (reg:CC FLAGS_REG))])]
15034   ""
15035 {
15036   if (TARGET_ABM)
15037     {
15038       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15039       DONE;
15040     }
15041 })
15042
15043 (define_insn "clzhi2_abm"
15044   [(set (match_operand:HI 0 "register_operand" "=r")
15045         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15046    (clobber (reg:CC FLAGS_REG))]
15047   "TARGET_ABM"
15048   "lzcnt{w}\t{%1, %0|%0, %1}"
15049   [(set_attr "prefix_rep" "1")
15050    (set_attr "type" "bitmanip")
15051    (set_attr "mode" "HI")])
15052
15053 (define_insn "*bsrhi"
15054   [(set (match_operand:HI 0 "register_operand" "=r")
15055         (minus:HI (const_int 15)
15056                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15057    (clobber (reg:CC FLAGS_REG))]
15058   ""
15059   "bsr{w}\t{%1, %0|%0, %1}"
15060   [(set_attr "prefix_0f" "1")
15061    (set_attr "mode" "HI")])
15062
15063 (define_insn "popcounthi2"
15064   [(set (match_operand:HI 0 "register_operand" "=r")
15065         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15066    (clobber (reg:CC FLAGS_REG))]
15067   "TARGET_POPCNT"
15068   "popcnt{w}\t{%1, %0|%0, %1}"
15069   [(set_attr "prefix_rep" "1")
15070    (set_attr "type" "bitmanip")
15071    (set_attr "mode" "HI")])
15072
15073 (define_insn "*popcounthi2_cmp"
15074   [(set (reg FLAGS_REG)
15075         (compare
15076           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15077           (const_int 0)))
15078    (set (match_operand:HI 0 "register_operand" "=r")
15079         (popcount:HI (match_dup 1)))]
15080   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15081   "popcnt{w}\t{%1, %0|%0, %1}"
15082   [(set_attr "prefix_rep" "1")
15083    (set_attr "type" "bitmanip")
15084    (set_attr "mode" "HI")])
15085
15086 (define_expand "paritydi2"
15087   [(set (match_operand:DI 0 "register_operand" "")
15088         (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
15089   "! TARGET_POPCNT"
15090 {
15091   rtx scratch = gen_reg_rtx (QImode);
15092   rtx cond;
15093
15094   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15095                                 NULL_RTX, operands[1]));
15096
15097   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15098                          gen_rtx_REG (CCmode, FLAGS_REG),
15099                          const0_rtx);
15100   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15101
15102   if (TARGET_64BIT)
15103     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15104   else
15105     {
15106       rtx tmp = gen_reg_rtx (SImode);
15107
15108       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15109       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15110     }
15111   DONE;
15112 })
15113
15114 (define_insn_and_split "paritydi2_cmp"
15115   [(set (reg:CC FLAGS_REG)
15116         (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
15117    (clobber (match_scratch:DI 0 "=r,X"))
15118    (clobber (match_scratch:SI 1 "=r,r"))
15119    (clobber (match_scratch:HI 2 "=Q,Q"))]
15120   "! TARGET_POPCNT"
15121   "#"
15122   "&& reload_completed"
15123   [(parallel
15124      [(set (match_dup 1)
15125            (xor:SI (match_dup 1) (match_dup 4)))
15126       (clobber (reg:CC FLAGS_REG))])
15127    (parallel
15128      [(set (reg:CC FLAGS_REG)
15129            (parity:CC (match_dup 1)))
15130       (clobber (match_dup 1))
15131       (clobber (match_dup 2))])]
15132 {
15133   operands[4] = gen_lowpart (SImode, operands[3]);
15134
15135   if (MEM_P (operands[3]))
15136     emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
15137   else if (! TARGET_64BIT)
15138     operands[1] = gen_highpart (SImode, operands[3]);
15139   else
15140     {
15141       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15142       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15143     }
15144 })
15145
15146 (define_expand "paritysi2"
15147   [(set (match_operand:SI 0 "register_operand" "")
15148         (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
15149   "! TARGET_POPCNT"
15150 {
15151   rtx scratch = gen_reg_rtx (QImode);
15152   rtx cond;
15153
15154   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15155
15156   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15157                          gen_rtx_REG (CCmode, FLAGS_REG),
15158                          const0_rtx);
15159   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15160
15161   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15162   DONE;
15163 })
15164
15165 (define_insn_and_split "paritysi2_cmp"
15166   [(set (reg:CC FLAGS_REG)
15167         (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
15168    (clobber (match_scratch:SI 0 "=r,X"))
15169    (clobber (match_scratch:HI 1 "=Q,Q"))]
15170   "! TARGET_POPCNT"
15171   "#"
15172   "&& reload_completed"
15173   [(parallel
15174      [(set (match_dup 1)
15175            (xor:HI (match_dup 1) (match_dup 3)))
15176       (clobber (reg:CC FLAGS_REG))])
15177    (parallel
15178      [(set (reg:CC FLAGS_REG)
15179            (parity:CC (match_dup 1)))
15180       (clobber (match_dup 1))])]
15181 {
15182   operands[3] = gen_lowpart (HImode, operands[2]);
15183
15184   if (MEM_P (operands[2]))
15185     emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15186   else
15187     {
15188       emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15189       emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15190     }
15191 })
15192
15193 (define_insn "*parityhi2_cmp"
15194   [(set (reg:CC FLAGS_REG)
15195         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15196    (clobber (match_scratch:HI 0 "=Q"))]
15197   "! TARGET_POPCNT"
15198   "xor{b}\t{%h0, %b0|%b0, %h0}"
15199   [(set_attr "length" "2")
15200    (set_attr "mode" "HI")])
15201
15202 (define_insn "*parityqi2_cmp"
15203   [(set (reg:CC FLAGS_REG)
15204         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15205   "! TARGET_POPCNT"
15206   "test{b}\t%0, %0"
15207   [(set_attr "length" "2")
15208    (set_attr "mode" "QI")])
15209 \f
15210 ;; Thread-local storage patterns for ELF.
15211 ;;
15212 ;; Note that these code sequences must appear exactly as shown
15213 ;; in order to allow linker relaxation.
15214
15215 (define_insn "*tls_global_dynamic_32_gnu"
15216   [(set (match_operand:SI 0 "register_operand" "=a")
15217         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15218                     (match_operand:SI 2 "tls_symbolic_operand" "")
15219                     (match_operand:SI 3 "call_insn_operand" "")]
15220                     UNSPEC_TLS_GD))
15221    (clobber (match_scratch:SI 4 "=d"))
15222    (clobber (match_scratch:SI 5 "=c"))
15223    (clobber (reg:CC FLAGS_REG))]
15224   "!TARGET_64BIT && TARGET_GNU_TLS"
15225   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15226   [(set_attr "type" "multi")
15227    (set_attr "length" "12")])
15228
15229 (define_insn "*tls_global_dynamic_32_sun"
15230   [(set (match_operand:SI 0 "register_operand" "=a")
15231         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15232                     (match_operand:SI 2 "tls_symbolic_operand" "")
15233                     (match_operand:SI 3 "call_insn_operand" "")]
15234                     UNSPEC_TLS_GD))
15235    (clobber (match_scratch:SI 4 "=d"))
15236    (clobber (match_scratch:SI 5 "=c"))
15237    (clobber (reg:CC FLAGS_REG))]
15238   "!TARGET_64BIT && TARGET_SUN_TLS"
15239   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15240         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15241   [(set_attr "type" "multi")
15242    (set_attr "length" "14")])
15243
15244 (define_expand "tls_global_dynamic_32"
15245   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15246                    (unspec:SI
15247                     [(match_dup 2)
15248                      (match_operand:SI 1 "tls_symbolic_operand" "")
15249                      (match_dup 3)]
15250                     UNSPEC_TLS_GD))
15251               (clobber (match_scratch:SI 4 ""))
15252               (clobber (match_scratch:SI 5 ""))
15253               (clobber (reg:CC FLAGS_REG))])]
15254   ""
15255 {
15256   if (flag_pic)
15257     operands[2] = pic_offset_table_rtx;
15258   else
15259     {
15260       operands[2] = gen_reg_rtx (Pmode);
15261       emit_insn (gen_set_got (operands[2]));
15262     }
15263   if (TARGET_GNU2_TLS)
15264     {
15265        emit_insn (gen_tls_dynamic_gnu2_32
15266                   (operands[0], operands[1], operands[2]));
15267        DONE;
15268     }
15269   operands[3] = ix86_tls_get_addr ();
15270 })
15271
15272 (define_insn "*tls_global_dynamic_64"
15273   [(set (match_operand:DI 0 "register_operand" "=a")
15274         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15275                  (match_operand:DI 3 "" "")))
15276    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15277               UNSPEC_TLS_GD)]
15278   "TARGET_64BIT"
15279   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15280   [(set_attr "type" "multi")
15281    (set_attr "length" "16")])
15282
15283 (define_expand "tls_global_dynamic_64"
15284   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15285                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15286               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15287                          UNSPEC_TLS_GD)])]
15288   ""
15289 {
15290   if (TARGET_GNU2_TLS)
15291     {
15292        emit_insn (gen_tls_dynamic_gnu2_64
15293                   (operands[0], operands[1]));
15294        DONE;
15295     }
15296   operands[2] = ix86_tls_get_addr ();
15297 })
15298
15299 (define_insn "*tls_local_dynamic_base_32_gnu"
15300   [(set (match_operand:SI 0 "register_operand" "=a")
15301         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15302                     (match_operand:SI 2 "call_insn_operand" "")]
15303                    UNSPEC_TLS_LD_BASE))
15304    (clobber (match_scratch:SI 3 "=d"))
15305    (clobber (match_scratch:SI 4 "=c"))
15306    (clobber (reg:CC FLAGS_REG))]
15307   "!TARGET_64BIT && TARGET_GNU_TLS"
15308   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15309   [(set_attr "type" "multi")
15310    (set_attr "length" "11")])
15311
15312 (define_insn "*tls_local_dynamic_base_32_sun"
15313   [(set (match_operand:SI 0 "register_operand" "=a")
15314         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15315                     (match_operand:SI 2 "call_insn_operand" "")]
15316                    UNSPEC_TLS_LD_BASE))
15317    (clobber (match_scratch:SI 3 "=d"))
15318    (clobber (match_scratch:SI 4 "=c"))
15319    (clobber (reg:CC FLAGS_REG))]
15320   "!TARGET_64BIT && TARGET_SUN_TLS"
15321   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15322         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15323   [(set_attr "type" "multi")
15324    (set_attr "length" "13")])
15325
15326 (define_expand "tls_local_dynamic_base_32"
15327   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15328                    (unspec:SI [(match_dup 1) (match_dup 2)]
15329                               UNSPEC_TLS_LD_BASE))
15330               (clobber (match_scratch:SI 3 ""))
15331               (clobber (match_scratch:SI 4 ""))
15332               (clobber (reg:CC FLAGS_REG))])]
15333   ""
15334 {
15335   if (flag_pic)
15336     operands[1] = pic_offset_table_rtx;
15337   else
15338     {
15339       operands[1] = gen_reg_rtx (Pmode);
15340       emit_insn (gen_set_got (operands[1]));
15341     }
15342   if (TARGET_GNU2_TLS)
15343     {
15344        emit_insn (gen_tls_dynamic_gnu2_32
15345                   (operands[0], ix86_tls_module_base (), operands[1]));
15346        DONE;
15347     }
15348   operands[2] = ix86_tls_get_addr ();
15349 })
15350
15351 (define_insn "*tls_local_dynamic_base_64"
15352   [(set (match_operand:DI 0 "register_operand" "=a")
15353         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15354                  (match_operand:DI 2 "" "")))
15355    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15356   "TARGET_64BIT"
15357   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15358   [(set_attr "type" "multi")
15359    (set_attr "length" "12")])
15360
15361 (define_expand "tls_local_dynamic_base_64"
15362   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15363                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15364               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15365   ""
15366 {
15367   if (TARGET_GNU2_TLS)
15368     {
15369        emit_insn (gen_tls_dynamic_gnu2_64
15370                   (operands[0], ix86_tls_module_base ()));
15371        DONE;
15372     }
15373   operands[1] = ix86_tls_get_addr ();
15374 })
15375
15376 ;; Local dynamic of a single variable is a lose.  Show combine how
15377 ;; to convert that back to global dynamic.
15378
15379 (define_insn_and_split "*tls_local_dynamic_32_once"
15380   [(set (match_operand:SI 0 "register_operand" "=a")
15381         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15382                              (match_operand:SI 2 "call_insn_operand" "")]
15383                             UNSPEC_TLS_LD_BASE)
15384                  (const:SI (unspec:SI
15385                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15386                             UNSPEC_DTPOFF))))
15387    (clobber (match_scratch:SI 4 "=d"))
15388    (clobber (match_scratch:SI 5 "=c"))
15389    (clobber (reg:CC FLAGS_REG))]
15390   ""
15391   "#"
15392   ""
15393   [(parallel [(set (match_dup 0)
15394                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15395                               UNSPEC_TLS_GD))
15396               (clobber (match_dup 4))
15397               (clobber (match_dup 5))
15398               (clobber (reg:CC FLAGS_REG))])]
15399   "")
15400
15401 ;; Load and add the thread base pointer from %gs:0.
15402
15403 (define_insn "*load_tp_si"
15404   [(set (match_operand:SI 0 "register_operand" "=r")
15405         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15406   "!TARGET_64BIT"
15407   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15408   [(set_attr "type" "imov")
15409    (set_attr "modrm" "0")
15410    (set_attr "length" "7")
15411    (set_attr "memory" "load")
15412    (set_attr "imm_disp" "false")])
15413
15414 (define_insn "*add_tp_si"
15415   [(set (match_operand:SI 0 "register_operand" "=r")
15416         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15417                  (match_operand:SI 1 "register_operand" "0")))
15418    (clobber (reg:CC FLAGS_REG))]
15419   "!TARGET_64BIT"
15420   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15421   [(set_attr "type" "alu")
15422    (set_attr "modrm" "0")
15423    (set_attr "length" "7")
15424    (set_attr "memory" "load")
15425    (set_attr "imm_disp" "false")])
15426
15427 (define_insn "*load_tp_di"
15428   [(set (match_operand:DI 0 "register_operand" "=r")
15429         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15430   "TARGET_64BIT"
15431   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15432   [(set_attr "type" "imov")
15433    (set_attr "modrm" "0")
15434    (set_attr "length" "7")
15435    (set_attr "memory" "load")
15436    (set_attr "imm_disp" "false")])
15437
15438 (define_insn "*add_tp_di"
15439   [(set (match_operand:DI 0 "register_operand" "=r")
15440         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15441                  (match_operand:DI 1 "register_operand" "0")))
15442    (clobber (reg:CC FLAGS_REG))]
15443   "TARGET_64BIT"
15444   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15445   [(set_attr "type" "alu")
15446    (set_attr "modrm" "0")
15447    (set_attr "length" "7")
15448    (set_attr "memory" "load")
15449    (set_attr "imm_disp" "false")])
15450
15451 ;; GNU2 TLS patterns can be split.
15452
15453 (define_expand "tls_dynamic_gnu2_32"
15454   [(set (match_dup 3)
15455         (plus:SI (match_operand:SI 2 "register_operand" "")
15456                  (const:SI
15457                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15458                              UNSPEC_TLSDESC))))
15459    (parallel
15460     [(set (match_operand:SI 0 "register_operand" "")
15461           (unspec:SI [(match_dup 1) (match_dup 3)
15462                       (match_dup 2) (reg:SI SP_REG)]
15463                       UNSPEC_TLSDESC))
15464      (clobber (reg:CC FLAGS_REG))])]
15465   "!TARGET_64BIT && TARGET_GNU2_TLS"
15466 {
15467   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15468   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15469 })
15470
15471 (define_insn "*tls_dynamic_lea_32"
15472   [(set (match_operand:SI 0 "register_operand" "=r")
15473         (plus:SI (match_operand:SI 1 "register_operand" "b")
15474                  (const:SI
15475                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15476                               UNSPEC_TLSDESC))))]
15477   "!TARGET_64BIT && TARGET_GNU2_TLS"
15478   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15479   [(set_attr "type" "lea")
15480    (set_attr "mode" "SI")
15481    (set_attr "length" "6")
15482    (set_attr "length_address" "4")])
15483
15484 (define_insn "*tls_dynamic_call_32"
15485   [(set (match_operand:SI 0 "register_operand" "=a")
15486         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15487                     (match_operand:SI 2 "register_operand" "0")
15488                     ;; we have to make sure %ebx still points to the GOT
15489                     (match_operand:SI 3 "register_operand" "b")
15490                     (reg:SI SP_REG)]
15491                    UNSPEC_TLSDESC))
15492    (clobber (reg:CC FLAGS_REG))]
15493   "!TARGET_64BIT && TARGET_GNU2_TLS"
15494   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15495   [(set_attr "type" "call")
15496    (set_attr "length" "2")
15497    (set_attr "length_address" "0")])
15498
15499 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15500   [(set (match_operand:SI 0 "register_operand" "=&a")
15501         (plus:SI
15502          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15503                      (match_operand:SI 4 "" "")
15504                      (match_operand:SI 2 "register_operand" "b")
15505                      (reg:SI SP_REG)]
15506                     UNSPEC_TLSDESC)
15507          (const:SI (unspec:SI
15508                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15509                     UNSPEC_DTPOFF))))
15510    (clobber (reg:CC FLAGS_REG))]
15511   "!TARGET_64BIT && TARGET_GNU2_TLS"
15512   "#"
15513   ""
15514   [(set (match_dup 0) (match_dup 5))]
15515 {
15516   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15517   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15518 })
15519
15520 (define_expand "tls_dynamic_gnu2_64"
15521   [(set (match_dup 2)
15522         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15523                    UNSPEC_TLSDESC))
15524    (parallel
15525     [(set (match_operand:DI 0 "register_operand" "")
15526           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15527                      UNSPEC_TLSDESC))
15528      (clobber (reg:CC FLAGS_REG))])]
15529   "TARGET_64BIT && TARGET_GNU2_TLS"
15530 {
15531   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15532   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15533 })
15534
15535 (define_insn "*tls_dynamic_lea_64"
15536   [(set (match_operand:DI 0 "register_operand" "=r")
15537         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15538                    UNSPEC_TLSDESC))]
15539   "TARGET_64BIT && TARGET_GNU2_TLS"
15540   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15541   [(set_attr "type" "lea")
15542    (set_attr "mode" "DI")
15543    (set_attr "length" "7")
15544    (set_attr "length_address" "4")])
15545
15546 (define_insn "*tls_dynamic_call_64"
15547   [(set (match_operand:DI 0 "register_operand" "=a")
15548         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15549                     (match_operand:DI 2 "register_operand" "0")
15550                     (reg:DI SP_REG)]
15551                    UNSPEC_TLSDESC))
15552    (clobber (reg:CC FLAGS_REG))]
15553   "TARGET_64BIT && TARGET_GNU2_TLS"
15554   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15555   [(set_attr "type" "call")
15556    (set_attr "length" "2")
15557    (set_attr "length_address" "0")])
15558
15559 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15560   [(set (match_operand:DI 0 "register_operand" "=&a")
15561         (plus:DI
15562          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15563                      (match_operand:DI 3 "" "")
15564                      (reg:DI SP_REG)]
15565                     UNSPEC_TLSDESC)
15566          (const:DI (unspec:DI
15567                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15568                     UNSPEC_DTPOFF))))
15569    (clobber (reg:CC FLAGS_REG))]
15570   "TARGET_64BIT && TARGET_GNU2_TLS"
15571   "#"
15572   ""
15573   [(set (match_dup 0) (match_dup 4))]
15574 {
15575   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15576   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15577 })
15578
15579 ;;
15580 \f
15581 ;; These patterns match the binary 387 instructions for addM3, subM3,
15582 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15583 ;; SFmode.  The first is the normal insn, the second the same insn but
15584 ;; with one operand a conversion, and the third the same insn but with
15585 ;; the other operand a conversion.  The conversion may be SFmode or
15586 ;; SImode if the target mode DFmode, but only SImode if the target mode
15587 ;; is SFmode.
15588
15589 ;; Gcc is slightly more smart about handling normal two address instructions
15590 ;; so use special patterns for add and mull.
15591
15592 (define_insn "*fop_sf_comm_mixed"
15593   [(set (match_operand:SF 0 "register_operand" "=f,x")
15594         (match_operator:SF 3 "binary_fp_operator"
15595                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15596                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15597   "TARGET_MIX_SSE_I387
15598    && COMMUTATIVE_ARITH_P (operands[3])
15599    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15600   "* return output_387_binary_op (insn, operands);"
15601   [(set (attr "type")
15602         (if_then_else (eq_attr "alternative" "1")
15603            (if_then_else (match_operand:SF 3 "mult_operator" "")
15604               (const_string "ssemul")
15605               (const_string "sseadd"))
15606            (if_then_else (match_operand:SF 3 "mult_operator" "")
15607               (const_string "fmul")
15608               (const_string "fop"))))
15609    (set_attr "mode" "SF")])
15610
15611 (define_insn "*fop_sf_comm_sse"
15612   [(set (match_operand:SF 0 "register_operand" "=x")
15613         (match_operator:SF 3 "binary_fp_operator"
15614                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15615                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15616   "TARGET_SSE_MATH
15617    && COMMUTATIVE_ARITH_P (operands[3])
15618    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15619   "* return output_387_binary_op (insn, operands);"
15620   [(set (attr "type")
15621         (if_then_else (match_operand:SF 3 "mult_operator" "")
15622            (const_string "ssemul")
15623            (const_string "sseadd")))
15624    (set_attr "mode" "SF")])
15625
15626 (define_insn "*fop_sf_comm_i387"
15627   [(set (match_operand:SF 0 "register_operand" "=f")
15628         (match_operator:SF 3 "binary_fp_operator"
15629                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15630                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15631   "TARGET_80387
15632    && COMMUTATIVE_ARITH_P (operands[3])
15633    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15634   "* return output_387_binary_op (insn, operands);"
15635   [(set (attr "type")
15636         (if_then_else (match_operand:SF 3 "mult_operator" "")
15637            (const_string "fmul")
15638            (const_string "fop")))
15639    (set_attr "mode" "SF")])
15640
15641 (define_insn "*fop_sf_1_mixed"
15642   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15643         (match_operator:SF 3 "binary_fp_operator"
15644                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15645                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15646   "TARGET_MIX_SSE_I387
15647    && !COMMUTATIVE_ARITH_P (operands[3])
15648    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15649   "* return output_387_binary_op (insn, operands);"
15650   [(set (attr "type")
15651         (cond [(and (eq_attr "alternative" "2")
15652                     (match_operand:SF 3 "mult_operator" ""))
15653                  (const_string "ssemul")
15654                (and (eq_attr "alternative" "2")
15655                     (match_operand:SF 3 "div_operator" ""))
15656                  (const_string "ssediv")
15657                (eq_attr "alternative" "2")
15658                  (const_string "sseadd")
15659                (match_operand:SF 3 "mult_operator" "")
15660                  (const_string "fmul")
15661                (match_operand:SF 3 "div_operator" "")
15662                  (const_string "fdiv")
15663               ]
15664               (const_string "fop")))
15665    (set_attr "mode" "SF")])
15666
15667 (define_insn "*fop_sf_1_sse"
15668   [(set (match_operand:SF 0 "register_operand" "=x")
15669         (match_operator:SF 3 "binary_fp_operator"
15670                         [(match_operand:SF 1 "register_operand" "0")
15671                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15672   "TARGET_SSE_MATH
15673    && !COMMUTATIVE_ARITH_P (operands[3])"
15674   "* return output_387_binary_op (insn, operands);"
15675   [(set (attr "type")
15676         (cond [(match_operand:SF 3 "mult_operator" "")
15677                  (const_string "ssemul")
15678                (match_operand:SF 3 "div_operator" "")
15679                  (const_string "ssediv")
15680               ]
15681               (const_string "sseadd")))
15682    (set_attr "mode" "SF")])
15683
15684 ;; This pattern is not fully shadowed by the pattern above.
15685 (define_insn "*fop_sf_1_i387"
15686   [(set (match_operand:SF 0 "register_operand" "=f,f")
15687         (match_operator:SF 3 "binary_fp_operator"
15688                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15689                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15690   "TARGET_80387 && !TARGET_SSE_MATH
15691    && !COMMUTATIVE_ARITH_P (operands[3])
15692    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15693   "* return output_387_binary_op (insn, operands);"
15694   [(set (attr "type")
15695         (cond [(match_operand:SF 3 "mult_operator" "")
15696                  (const_string "fmul")
15697                (match_operand:SF 3 "div_operator" "")
15698                  (const_string "fdiv")
15699               ]
15700               (const_string "fop")))
15701    (set_attr "mode" "SF")])
15702
15703 ;; ??? Add SSE splitters for these!
15704 (define_insn "*fop_sf_2<mode>_i387"
15705   [(set (match_operand:SF 0 "register_operand" "=f,f")
15706         (match_operator:SF 3 "binary_fp_operator"
15707           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15708            (match_operand:SF 2 "register_operand" "0,0")]))]
15709   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15710   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15711   [(set (attr "type")
15712         (cond [(match_operand:SF 3 "mult_operator" "")
15713                  (const_string "fmul")
15714                (match_operand:SF 3 "div_operator" "")
15715                  (const_string "fdiv")
15716               ]
15717               (const_string "fop")))
15718    (set_attr "fp_int_src" "true")
15719    (set_attr "mode" "<MODE>")])
15720
15721 (define_insn "*fop_sf_3<mode>_i387"
15722   [(set (match_operand:SF 0 "register_operand" "=f,f")
15723         (match_operator:SF 3 "binary_fp_operator"
15724           [(match_operand:SF 1 "register_operand" "0,0")
15725            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15726   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15727   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15728   [(set (attr "type")
15729         (cond [(match_operand:SF 3 "mult_operator" "")
15730                  (const_string "fmul")
15731                (match_operand:SF 3 "div_operator" "")
15732                  (const_string "fdiv")
15733               ]
15734               (const_string "fop")))
15735    (set_attr "fp_int_src" "true")
15736    (set_attr "mode" "<MODE>")])
15737
15738 (define_insn "*fop_df_comm_mixed"
15739   [(set (match_operand:DF 0 "register_operand" "=f,x")
15740         (match_operator:DF 3 "binary_fp_operator"
15741           [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15742            (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15743   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15744    && COMMUTATIVE_ARITH_P (operands[3])
15745    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15746   "* return output_387_binary_op (insn, operands);"
15747   [(set (attr "type")
15748         (if_then_else (eq_attr "alternative" "1")
15749            (if_then_else (match_operand:DF 3 "mult_operator" "")
15750               (const_string "ssemul")
15751               (const_string "sseadd"))
15752            (if_then_else (match_operand:DF 3 "mult_operator" "")
15753               (const_string "fmul")
15754               (const_string "fop"))))
15755    (set_attr "mode" "DF")])
15756
15757 (define_insn "*fop_df_comm_sse"
15758   [(set (match_operand:DF 0 "register_operand" "=x")
15759         (match_operator:DF 3 "binary_fp_operator"
15760           [(match_operand:DF 1 "nonimmediate_operand" "%0")
15761            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15762   "TARGET_SSE2 && TARGET_SSE_MATH
15763    && COMMUTATIVE_ARITH_P (operands[3])
15764    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15765   "* return output_387_binary_op (insn, operands);"
15766   [(set (attr "type")
15767         (if_then_else (match_operand:DF 3 "mult_operator" "")
15768            (const_string "ssemul")
15769            (const_string "sseadd")))
15770    (set_attr "mode" "DF")])
15771
15772 (define_insn "*fop_df_comm_i387"
15773   [(set (match_operand:DF 0 "register_operand" "=f")
15774         (match_operator:DF 3 "binary_fp_operator"
15775                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15776                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15777   "TARGET_80387
15778    && COMMUTATIVE_ARITH_P (operands[3])
15779    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15780   "* return output_387_binary_op (insn, operands);"
15781   [(set (attr "type")
15782         (if_then_else (match_operand:DF 3 "mult_operator" "")
15783            (const_string "fmul")
15784            (const_string "fop")))
15785    (set_attr "mode" "DF")])
15786
15787 (define_insn "*fop_df_1_mixed"
15788   [(set (match_operand:DF 0 "register_operand" "=f,f,x")
15789         (match_operator:DF 3 "binary_fp_operator"
15790           [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15791            (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
15792   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15793    && !COMMUTATIVE_ARITH_P (operands[3])
15794    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15795   "* return output_387_binary_op (insn, operands);"
15796   [(set (attr "type")
15797         (cond [(and (eq_attr "alternative" "2")
15798                     (match_operand:DF 3 "mult_operator" ""))
15799                  (const_string "ssemul")
15800                (and (eq_attr "alternative" "2")
15801                     (match_operand:DF 3 "div_operator" ""))
15802                  (const_string "ssediv")
15803                (eq_attr "alternative" "2")
15804                  (const_string "sseadd")
15805                (match_operand:DF 3 "mult_operator" "")
15806                  (const_string "fmul")
15807                (match_operand:DF 3 "div_operator" "")
15808                  (const_string "fdiv")
15809               ]
15810               (const_string "fop")))
15811    (set_attr "mode" "DF")])
15812
15813 (define_insn "*fop_df_1_sse"
15814   [(set (match_operand:DF 0 "register_operand" "=x")
15815         (match_operator:DF 3 "binary_fp_operator"
15816           [(match_operand:DF 1 "register_operand" "0")
15817            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15818   "TARGET_SSE2 && TARGET_SSE_MATH
15819    && !COMMUTATIVE_ARITH_P (operands[3])"
15820   "* return output_387_binary_op (insn, operands);"
15821   [(set_attr "mode" "DF")
15822    (set (attr "type")
15823         (cond [(match_operand:DF 3 "mult_operator" "")
15824                  (const_string "ssemul")
15825                (match_operand:DF 3 "div_operator" "")
15826                  (const_string "ssediv")
15827               ]
15828               (const_string "sseadd")))])
15829
15830 ;; This pattern is not fully shadowed by the pattern above.
15831 (define_insn "*fop_df_1_i387"
15832   [(set (match_operand:DF 0 "register_operand" "=f,f")
15833         (match_operator:DF 3 "binary_fp_operator"
15834                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15835                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15836   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15837    && !COMMUTATIVE_ARITH_P (operands[3])
15838    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15839   "* return output_387_binary_op (insn, operands);"
15840   [(set (attr "type")
15841         (cond [(match_operand:DF 3 "mult_operator" "")
15842                  (const_string "fmul")
15843                (match_operand:DF 3 "div_operator" "")
15844                  (const_string "fdiv")
15845               ]
15846               (const_string "fop")))
15847    (set_attr "mode" "DF")])
15848
15849 ;; ??? Add SSE splitters for these!
15850 (define_insn "*fop_df_2<mode>_i387"
15851   [(set (match_operand:DF 0 "register_operand" "=f,f")
15852         (match_operator:DF 3 "binary_fp_operator"
15853            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15854             (match_operand:DF 2 "register_operand" "0,0")]))]
15855   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15856    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15857   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15858   [(set (attr "type")
15859         (cond [(match_operand:DF 3 "mult_operator" "")
15860                  (const_string "fmul")
15861                (match_operand:DF 3 "div_operator" "")
15862                  (const_string "fdiv")
15863               ]
15864               (const_string "fop")))
15865    (set_attr "fp_int_src" "true")
15866    (set_attr "mode" "<MODE>")])
15867
15868 (define_insn "*fop_df_3<mode>_i387"
15869   [(set (match_operand:DF 0 "register_operand" "=f,f")
15870         (match_operator:DF 3 "binary_fp_operator"
15871            [(match_operand:DF 1 "register_operand" "0,0")
15872             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15873   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15874    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15875   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15876   [(set (attr "type")
15877         (cond [(match_operand:DF 3 "mult_operator" "")
15878                  (const_string "fmul")
15879                (match_operand:DF 3 "div_operator" "")
15880                  (const_string "fdiv")
15881               ]
15882               (const_string "fop")))
15883    (set_attr "fp_int_src" "true")
15884    (set_attr "mode" "<MODE>")])
15885
15886 (define_insn "*fop_df_4_i387"
15887   [(set (match_operand:DF 0 "register_operand" "=f,f")
15888         (match_operator:DF 3 "binary_fp_operator"
15889            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15890             (match_operand:DF 2 "register_operand" "0,f")]))]
15891   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15892    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15893   "* return output_387_binary_op (insn, operands);"
15894   [(set (attr "type")
15895         (cond [(match_operand:DF 3 "mult_operator" "")
15896                  (const_string "fmul")
15897                (match_operand:DF 3 "div_operator" "")
15898                  (const_string "fdiv")
15899               ]
15900               (const_string "fop")))
15901    (set_attr "mode" "SF")])
15902
15903 (define_insn "*fop_df_5_i387"
15904   [(set (match_operand:DF 0 "register_operand" "=f,f")
15905         (match_operator:DF 3 "binary_fp_operator"
15906           [(match_operand:DF 1 "register_operand" "0,f")
15907            (float_extend:DF
15908             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15909   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15910   "* return output_387_binary_op (insn, operands);"
15911   [(set (attr "type")
15912         (cond [(match_operand:DF 3 "mult_operator" "")
15913                  (const_string "fmul")
15914                (match_operand:DF 3 "div_operator" "")
15915                  (const_string "fdiv")
15916               ]
15917               (const_string "fop")))
15918    (set_attr "mode" "SF")])
15919
15920 (define_insn "*fop_df_6_i387"
15921   [(set (match_operand:DF 0 "register_operand" "=f,f")
15922         (match_operator:DF 3 "binary_fp_operator"
15923           [(float_extend:DF
15924             (match_operand:SF 1 "register_operand" "0,f"))
15925            (float_extend:DF
15926             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15927   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15928   "* return output_387_binary_op (insn, operands);"
15929   [(set (attr "type")
15930         (cond [(match_operand:DF 3 "mult_operator" "")
15931                  (const_string "fmul")
15932                (match_operand:DF 3 "div_operator" "")
15933                  (const_string "fdiv")
15934               ]
15935               (const_string "fop")))
15936    (set_attr "mode" "SF")])
15937
15938 (define_insn "*fop_xf_comm_i387"
15939   [(set (match_operand:XF 0 "register_operand" "=f")
15940         (match_operator:XF 3 "binary_fp_operator"
15941                         [(match_operand:XF 1 "register_operand" "%0")
15942                          (match_operand:XF 2 "register_operand" "f")]))]
15943   "TARGET_80387
15944    && COMMUTATIVE_ARITH_P (operands[3])"
15945   "* return output_387_binary_op (insn, operands);"
15946   [(set (attr "type")
15947         (if_then_else (match_operand:XF 3 "mult_operator" "")
15948            (const_string "fmul")
15949            (const_string "fop")))
15950    (set_attr "mode" "XF")])
15951
15952 (define_insn "*fop_xf_1_i387"
15953   [(set (match_operand:XF 0 "register_operand" "=f,f")
15954         (match_operator:XF 3 "binary_fp_operator"
15955                         [(match_operand:XF 1 "register_operand" "0,f")
15956                          (match_operand:XF 2 "register_operand" "f,0")]))]
15957   "TARGET_80387
15958    && !COMMUTATIVE_ARITH_P (operands[3])"
15959   "* return output_387_binary_op (insn, operands);"
15960   [(set (attr "type")
15961         (cond [(match_operand:XF 3 "mult_operator" "")
15962                  (const_string "fmul")
15963                (match_operand:XF 3 "div_operator" "")
15964                  (const_string "fdiv")
15965               ]
15966               (const_string "fop")))
15967    (set_attr "mode" "XF")])
15968
15969 (define_insn "*fop_xf_2<mode>_i387"
15970   [(set (match_operand:XF 0 "register_operand" "=f,f")
15971         (match_operator:XF 3 "binary_fp_operator"
15972            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15973             (match_operand:XF 2 "register_operand" "0,0")]))]
15974   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15975   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15976   [(set (attr "type")
15977         (cond [(match_operand:XF 3 "mult_operator" "")
15978                  (const_string "fmul")
15979                (match_operand:XF 3 "div_operator" "")
15980                  (const_string "fdiv")
15981               ]
15982               (const_string "fop")))
15983    (set_attr "fp_int_src" "true")
15984    (set_attr "mode" "<MODE>")])
15985
15986 (define_insn "*fop_xf_3<mode>_i387"
15987   [(set (match_operand:XF 0 "register_operand" "=f,f")
15988         (match_operator:XF 3 "binary_fp_operator"
15989           [(match_operand:XF 1 "register_operand" "0,0")
15990            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15991   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15992   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15993   [(set (attr "type")
15994         (cond [(match_operand:XF 3 "mult_operator" "")
15995                  (const_string "fmul")
15996                (match_operand:XF 3 "div_operator" "")
15997                  (const_string "fdiv")
15998               ]
15999               (const_string "fop")))
16000    (set_attr "fp_int_src" "true")
16001    (set_attr "mode" "<MODE>")])
16002
16003 (define_insn "*fop_xf_4_i387"
16004   [(set (match_operand:XF 0 "register_operand" "=f,f")
16005         (match_operator:XF 3 "binary_fp_operator"
16006            [(float_extend:XF
16007               (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
16008             (match_operand:XF 2 "register_operand" "0,f")]))]
16009   "TARGET_80387"
16010   "* return output_387_binary_op (insn, operands);"
16011   [(set (attr "type")
16012         (cond [(match_operand:XF 3 "mult_operator" "")
16013                  (const_string "fmul")
16014                (match_operand:XF 3 "div_operator" "")
16015                  (const_string "fdiv")
16016               ]
16017               (const_string "fop")))
16018    (set_attr "mode" "SF")])
16019
16020 (define_insn "*fop_xf_5_i387"
16021   [(set (match_operand:XF 0 "register_operand" "=f,f")
16022         (match_operator:XF 3 "binary_fp_operator"
16023           [(match_operand:XF 1 "register_operand" "0,f")
16024            (float_extend:XF
16025              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
16026   "TARGET_80387"
16027   "* return output_387_binary_op (insn, operands);"
16028   [(set (attr "type")
16029         (cond [(match_operand:XF 3 "mult_operator" "")
16030                  (const_string "fmul")
16031                (match_operand:XF 3 "div_operator" "")
16032                  (const_string "fdiv")
16033               ]
16034               (const_string "fop")))
16035    (set_attr "mode" "SF")])
16036
16037 (define_insn "*fop_xf_6_i387"
16038   [(set (match_operand:XF 0 "register_operand" "=f,f")
16039         (match_operator:XF 3 "binary_fp_operator"
16040           [(float_extend:XF
16041              (match_operand:X87MODEF12 1 "register_operand" "0,f"))
16042            (float_extend:XF
16043              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
16044   "TARGET_80387"
16045   "* return output_387_binary_op (insn, operands);"
16046   [(set (attr "type")
16047         (cond [(match_operand:XF 3 "mult_operator" "")
16048                  (const_string "fmul")
16049                (match_operand:XF 3 "div_operator" "")
16050                  (const_string "fdiv")
16051               ]
16052               (const_string "fop")))
16053    (set_attr "mode" "SF")])
16054
16055 (define_split
16056   [(set (match_operand 0 "register_operand" "")
16057         (match_operator 3 "binary_fp_operator"
16058            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16059             (match_operand 2 "register_operand" "")]))]
16060   "TARGET_80387 && reload_completed
16061    && FLOAT_MODE_P (GET_MODE (operands[0]))"
16062   [(const_int 0)]
16063 {
16064   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16065   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16066   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16067                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16068                                           GET_MODE (operands[3]),
16069                                           operands[4],
16070                                           operands[2])));
16071   ix86_free_from_memory (GET_MODE (operands[1]));
16072   DONE;
16073 })
16074
16075 (define_split
16076   [(set (match_operand 0 "register_operand" "")
16077         (match_operator 3 "binary_fp_operator"
16078            [(match_operand 1 "register_operand" "")
16079             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16080   "TARGET_80387 && reload_completed
16081    && FLOAT_MODE_P (GET_MODE (operands[0]))"
16082   [(const_int 0)]
16083 {
16084   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16085   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16086   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16087                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16088                                           GET_MODE (operands[3]),
16089                                           operands[1],
16090                                           operands[4])));
16091   ix86_free_from_memory (GET_MODE (operands[2]));
16092   DONE;
16093 })
16094 \f
16095 ;; FPU special functions.
16096
16097 ;; This pattern implements a no-op XFmode truncation for
16098 ;; all fancy i386 XFmode math functions.
16099
16100 (define_insn "truncxf<mode>2_i387_noop_unspec"
16101   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16102         (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
16103         UNSPEC_TRUNC_NOOP))]
16104   "TARGET_USE_FANCY_MATH_387"
16105   "* return output_387_reg_move (insn, operands);"
16106   [(set_attr "type" "fmov")
16107    (set_attr "mode" "<MODE>")])
16108
16109 (define_insn "sqrtxf2"
16110   [(set (match_operand:XF 0 "register_operand" "=f")
16111         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16112   "TARGET_USE_FANCY_MATH_387"
16113   "fsqrt"
16114   [(set_attr "type" "fpspc")
16115    (set_attr "mode" "XF")
16116    (set_attr "athlon_decode" "direct")
16117    (set_attr "amdfam10_decode" "direct")])
16118
16119 (define_insn "sqrt_extend<mode>xf2_i387"
16120   [(set (match_operand:XF 0 "register_operand" "=f")
16121         (sqrt:XF
16122           (float_extend:XF
16123             (match_operand:X87MODEF12 1 "register_operand" "0"))))]
16124   "TARGET_USE_FANCY_MATH_387"
16125   "fsqrt"
16126   [(set_attr "type" "fpspc")
16127    (set_attr "mode" "XF")
16128    (set_attr "athlon_decode" "direct")   
16129    (set_attr "amdfam10_decode" "direct")])
16130
16131 (define_insn "*sqrt<mode>2_sse"
16132   [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
16133         (sqrt:SSEMODEF
16134           (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
16135   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16136   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16137   [(set_attr "type" "sse")
16138    (set_attr "mode" "<MODE>")
16139    (set_attr "athlon_decode" "*")
16140    (set_attr "amdfam10_decode" "*")])
16141
16142 (define_expand "sqrt<mode>2"
16143   [(set (match_operand:X87MODEF12 0 "register_operand" "")
16144         (sqrt:X87MODEF12
16145           (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
16146   "TARGET_USE_FANCY_MATH_387
16147    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16148 {
16149   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16150     {
16151       rtx op0 = gen_reg_rtx (XFmode);
16152       rtx op1 = force_reg (<MODE>mode, operands[1]);
16153
16154       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16155       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16156       DONE;
16157    }
16158 })
16159
16160 (define_insn "fpremxf4_i387"
16161   [(set (match_operand:XF 0 "register_operand" "=f")
16162         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16163                     (match_operand:XF 3 "register_operand" "1")]
16164                    UNSPEC_FPREM_F))
16165    (set (match_operand:XF 1 "register_operand" "=u")
16166         (unspec:XF [(match_dup 2) (match_dup 3)]
16167                    UNSPEC_FPREM_U))
16168    (set (reg:CCFP FPSR_REG)
16169         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16170                      UNSPEC_C2_FLAG))]
16171   "TARGET_USE_FANCY_MATH_387"
16172   "fprem"
16173   [(set_attr "type" "fpspc")
16174    (set_attr "mode" "XF")])
16175
16176 (define_expand "fmodxf3"
16177   [(use (match_operand:XF 0 "register_operand" ""))
16178    (use (match_operand:XF 1 "register_operand" ""))
16179    (use (match_operand:XF 2 "register_operand" ""))]
16180   "TARGET_USE_FANCY_MATH_387"
16181 {
16182   rtx label = gen_label_rtx ();
16183
16184   emit_label (label);
16185
16186   emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
16187                                 operands[1], operands[2]));
16188   ix86_emit_fp_unordered_jump (label);
16189   LABEL_NUSES (label) = 1;
16190
16191   emit_move_insn (operands[0], operands[1]);
16192   DONE;
16193 })
16194
16195 (define_expand "fmod<mode>3"
16196   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16197    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16198    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16199   "TARGET_USE_FANCY_MATH_387"
16200 {
16201   rtx label = gen_label_rtx ();
16202
16203   rtx op1 = gen_reg_rtx (XFmode);
16204   rtx op2 = gen_reg_rtx (XFmode);
16205
16206   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16207   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16208
16209   emit_label (label);
16210   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16211   ix86_emit_fp_unordered_jump (label);
16212   LABEL_NUSES (label) = 1;
16213
16214   /* Truncate the result properly for strict SSE math.  */
16215   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16216       && !TARGET_MIX_SSE_I387)
16217     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16218   else
16219     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16220
16221   DONE;
16222 })
16223
16224 (define_insn "fprem1xf4_i387"
16225   [(set (match_operand:XF 0 "register_operand" "=f")
16226         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16227                     (match_operand:XF 3 "register_operand" "1")]
16228                    UNSPEC_FPREM1_F))
16229    (set (match_operand:XF 1 "register_operand" "=u")
16230         (unspec:XF [(match_dup 2) (match_dup 3)]
16231                    UNSPEC_FPREM1_U))
16232    (set (reg:CCFP FPSR_REG)
16233         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16234                      UNSPEC_C2_FLAG))]
16235   "TARGET_USE_FANCY_MATH_387"
16236   "fprem1"
16237   [(set_attr "type" "fpspc")
16238    (set_attr "mode" "XF")])
16239
16240 (define_expand "remainderxf3"
16241   [(use (match_operand:XF 0 "register_operand" ""))
16242    (use (match_operand:XF 1 "register_operand" ""))
16243    (use (match_operand:XF 2 "register_operand" ""))]
16244   "TARGET_USE_FANCY_MATH_387"
16245 {
16246   rtx label = gen_label_rtx ();
16247
16248   emit_label (label);
16249
16250   emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
16251                                  operands[1], operands[2]));
16252   ix86_emit_fp_unordered_jump (label);
16253   LABEL_NUSES (label) = 1;
16254
16255   emit_move_insn (operands[0], operands[1]);
16256   DONE;
16257 })
16258
16259 (define_expand "remainder<mode>3"
16260   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16261    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16262    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16263   "TARGET_USE_FANCY_MATH_387"
16264 {
16265   rtx label = gen_label_rtx ();
16266
16267   rtx op1 = gen_reg_rtx (XFmode);
16268   rtx op2 = gen_reg_rtx (XFmode);
16269
16270   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16271   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16272
16273   emit_label (label);
16274
16275   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16276   ix86_emit_fp_unordered_jump (label);
16277   LABEL_NUSES (label) = 1;
16278
16279   /* Truncate the result properly for strict SSE math.  */
16280   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16281       && !TARGET_MIX_SSE_I387)
16282     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16283   else
16284     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16285
16286   DONE;
16287 })
16288
16289 (define_insn "*sinxf2_i387"
16290   [(set (match_operand:XF 0 "register_operand" "=f")
16291         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16292   "TARGET_USE_FANCY_MATH_387
16293    && flag_unsafe_math_optimizations"
16294   "fsin"
16295   [(set_attr "type" "fpspc")
16296    (set_attr "mode" "XF")])
16297
16298 (define_insn "*sin_extend<mode>xf2_i387"
16299   [(set (match_operand:XF 0 "register_operand" "=f")
16300         (unspec:XF [(float_extend:XF
16301                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
16302                    UNSPEC_SIN))]
16303   "TARGET_USE_FANCY_MATH_387
16304    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16305        || TARGET_MIX_SSE_I387)
16306    && flag_unsafe_math_optimizations"
16307   "fsin"
16308   [(set_attr "type" "fpspc")
16309    (set_attr "mode" "XF")])
16310
16311 (define_insn "*cosxf2_i387"
16312   [(set (match_operand:XF 0 "register_operand" "=f")
16313         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16314   "TARGET_USE_FANCY_MATH_387
16315    && flag_unsafe_math_optimizations"
16316   "fcos"
16317   [(set_attr "type" "fpspc")
16318    (set_attr "mode" "XF")])
16319
16320 (define_insn "*cos_extend<mode>xf2_i387"
16321   [(set (match_operand:XF 0 "register_operand" "=f")
16322         (unspec:XF [(float_extend:XF
16323                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
16324                    UNSPEC_COS))]
16325   "TARGET_USE_FANCY_MATH_387
16326    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16327        || TARGET_MIX_SSE_I387)
16328    && flag_unsafe_math_optimizations"
16329   "fcos"
16330   [(set_attr "type" "fpspc")
16331    (set_attr "mode" "XF")])
16332
16333 ;; When sincos pattern is defined, sin and cos builtin functions will be
16334 ;; expanded to sincos pattern with one of its outputs left unused.
16335 ;; CSE pass will figure out if two sincos patterns can be combined,
16336 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16337 ;; depending on the unused output.
16338
16339 (define_insn "sincosxf3"
16340   [(set (match_operand:XF 0 "register_operand" "=f")
16341         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16342                    UNSPEC_SINCOS_COS))
16343    (set (match_operand:XF 1 "register_operand" "=u")
16344         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16345   "TARGET_USE_FANCY_MATH_387
16346    && flag_unsafe_math_optimizations"
16347   "fsincos"
16348   [(set_attr "type" "fpspc")
16349    (set_attr "mode" "XF")])
16350
16351 (define_split
16352   [(set (match_operand:XF 0 "register_operand" "")
16353         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16354                    UNSPEC_SINCOS_COS))
16355    (set (match_operand:XF 1 "register_operand" "")
16356         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16357   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16358    && !reload_completed && !reload_in_progress"
16359   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16360   "")
16361
16362 (define_split
16363   [(set (match_operand:XF 0 "register_operand" "")
16364         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16365                    UNSPEC_SINCOS_COS))
16366    (set (match_operand:XF 1 "register_operand" "")
16367         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16368   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16369    && !reload_completed && !reload_in_progress"
16370   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16371   "")
16372
16373 (define_insn "sincos_extend<mode>xf3_i387"
16374   [(set (match_operand:XF 0 "register_operand" "=f")
16375         (unspec:XF [(float_extend:XF
16376                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16377                    UNSPEC_SINCOS_COS))
16378    (set (match_operand:XF 1 "register_operand" "=u")
16379         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16380   "TARGET_USE_FANCY_MATH_387
16381    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16382        || TARGET_MIX_SSE_I387)
16383    && flag_unsafe_math_optimizations"
16384   "fsincos"
16385   [(set_attr "type" "fpspc")
16386    (set_attr "mode" "XF")])
16387
16388 (define_split
16389   [(set (match_operand:XF 0 "register_operand" "")
16390         (unspec:XF [(float_extend:XF
16391                       (match_operand:X87MODEF12 2 "register_operand" ""))]
16392                    UNSPEC_SINCOS_COS))
16393    (set (match_operand:XF 1 "register_operand" "")
16394         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16395   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16396    && !reload_completed && !reload_in_progress"
16397   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16398   "")
16399
16400 (define_split
16401   [(set (match_operand:XF 0 "register_operand" "")
16402         (unspec:XF [(float_extend:XF
16403                       (match_operand:X87MODEF12 2 "register_operand" ""))]
16404                    UNSPEC_SINCOS_COS))
16405    (set (match_operand:XF 1 "register_operand" "")
16406         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16407   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16408    && !reload_completed && !reload_in_progress"
16409   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16410   "")
16411
16412 (define_expand "sincos<mode>3"
16413   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16414    (use (match_operand:X87MODEF12 1 "register_operand" ""))
16415    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16416   "TARGET_USE_FANCY_MATH_387
16417    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16418        || TARGET_MIX_SSE_I387)
16419    && flag_unsafe_math_optimizations"
16420 {
16421   rtx op0 = gen_reg_rtx (XFmode);
16422   rtx op1 = gen_reg_rtx (XFmode);
16423
16424   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16425   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16426   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16427   DONE;
16428 })
16429
16430 (define_insn "fptanxf4_i387"
16431   [(set (match_operand:XF 0 "register_operand" "=f")
16432         (match_operand:XF 3 "const_double_operand" "F"))
16433    (set (match_operand:XF 1 "register_operand" "=u")
16434         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16435                    UNSPEC_TAN))]
16436   "TARGET_USE_FANCY_MATH_387
16437    && flag_unsafe_math_optimizations
16438    && standard_80387_constant_p (operands[3]) == 2"
16439   "fptan"
16440   [(set_attr "type" "fpspc")
16441    (set_attr "mode" "XF")])
16442
16443 (define_insn "fptan_extend<mode>xf4_i387"
16444   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16445         (match_operand:X87MODEF12 3 "const_double_operand" "F"))
16446    (set (match_operand:XF 1 "register_operand" "=u")
16447         (unspec:XF [(float_extend:XF
16448                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16449                    UNSPEC_TAN))]
16450   "TARGET_USE_FANCY_MATH_387
16451    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16452        || TARGET_MIX_SSE_I387)
16453    && flag_unsafe_math_optimizations
16454    && standard_80387_constant_p (operands[3]) == 2"
16455   "fptan"
16456   [(set_attr "type" "fpspc")
16457    (set_attr "mode" "XF")])
16458
16459 (define_expand "tanxf2"
16460   [(use (match_operand:XF 0 "register_operand" ""))
16461    (use (match_operand:XF 1 "register_operand" ""))]
16462   "TARGET_USE_FANCY_MATH_387
16463    && flag_unsafe_math_optimizations"
16464 {
16465   rtx one = gen_reg_rtx (XFmode);
16466   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16467
16468   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16469   DONE;
16470 })
16471
16472 (define_expand "tan<mode>2"
16473   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16474    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16475   "TARGET_USE_FANCY_MATH_387
16476    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16477        || TARGET_MIX_SSE_I387)
16478    && flag_unsafe_math_optimizations"
16479 {
16480   rtx op0 = gen_reg_rtx (XFmode);
16481
16482   rtx one = gen_reg_rtx (<MODE>mode);
16483   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16484
16485   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16486                                              operands[1], op2));
16487   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16488   DONE;
16489 })
16490
16491 (define_insn "*fpatanxf3_i387"
16492   [(set (match_operand:XF 0 "register_operand" "=f")
16493         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16494                     (match_operand:XF 2 "register_operand" "u")]
16495                    UNSPEC_FPATAN))
16496    (clobber (match_scratch:XF 3 "=2"))]
16497   "TARGET_USE_FANCY_MATH_387
16498    && flag_unsafe_math_optimizations"
16499   "fpatan"
16500   [(set_attr "type" "fpspc")
16501    (set_attr "mode" "XF")])
16502
16503 (define_insn "fpatan_extend<mode>xf3_i387"
16504   [(set (match_operand:XF 0 "register_operand" "=f")
16505         (unspec:XF [(float_extend:XF
16506                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16507                     (float_extend:XF
16508                       (match_operand:X87MODEF12 2 "register_operand" "u"))]
16509                    UNSPEC_FPATAN))
16510    (clobber (match_scratch:XF 3 "=2"))]
16511   "TARGET_USE_FANCY_MATH_387
16512    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16513        || TARGET_MIX_SSE_I387)
16514    && flag_unsafe_math_optimizations"
16515   "fpatan"
16516   [(set_attr "type" "fpspc")
16517    (set_attr "mode" "XF")])
16518
16519 (define_expand "atan2xf3"
16520   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16521                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16522                                (match_operand:XF 1 "register_operand" "")]
16523                               UNSPEC_FPATAN))
16524               (clobber (match_scratch:XF 3 ""))])]
16525   "TARGET_USE_FANCY_MATH_387
16526    && flag_unsafe_math_optimizations"
16527   "")
16528
16529 (define_expand "atan2<mode>3"
16530   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16531    (use (match_operand:X87MODEF12 1 "register_operand" ""))
16532    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16533   "TARGET_USE_FANCY_MATH_387
16534    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16535        || TARGET_MIX_SSE_I387)
16536    && flag_unsafe_math_optimizations"
16537 {
16538   rtx op0 = gen_reg_rtx (XFmode);
16539
16540   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16541   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16542   DONE;
16543 })
16544
16545 (define_expand "atanxf2"
16546   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16547                    (unspec:XF [(match_dup 2)
16548                                (match_operand:XF 1 "register_operand" "")]
16549                               UNSPEC_FPATAN))
16550               (clobber (match_scratch:XF 3 ""))])]
16551   "TARGET_USE_FANCY_MATH_387
16552    && flag_unsafe_math_optimizations"
16553 {
16554   operands[2] = gen_reg_rtx (XFmode);
16555   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16556 })
16557
16558 (define_expand "atan<mode>2"
16559   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16560    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16561   "TARGET_USE_FANCY_MATH_387
16562    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16563        || TARGET_MIX_SSE_I387)
16564    && flag_unsafe_math_optimizations"
16565 {
16566   rtx op0 = gen_reg_rtx (XFmode);
16567
16568   rtx op2 = gen_reg_rtx (<MODE>mode);
16569   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16570
16571   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16572   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16573   DONE;
16574 })
16575
16576 (define_expand "asinxf2"
16577   [(set (match_dup 2)
16578         (mult:XF (match_operand:XF 1 "register_operand" "")
16579                  (match_dup 1)))
16580    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16581    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16582    (parallel [(set (match_operand:XF 0 "register_operand" "")
16583                    (unspec:XF [(match_dup 5) (match_dup 1)]
16584                               UNSPEC_FPATAN))
16585               (clobber (match_scratch:XF 6 ""))])]
16586   "TARGET_USE_FANCY_MATH_387
16587    && flag_unsafe_math_optimizations && !optimize_size"
16588 {
16589   int i;
16590
16591   for (i = 2; i < 6; i++)
16592     operands[i] = gen_reg_rtx (XFmode);
16593
16594   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16595 })
16596
16597 (define_expand "asin<mode>2"
16598   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16599    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16600  "TARGET_USE_FANCY_MATH_387
16601    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16602        || TARGET_MIX_SSE_I387)
16603    && flag_unsafe_math_optimizations && !optimize_size"
16604 {
16605   rtx op0 = gen_reg_rtx (XFmode);
16606   rtx op1 = gen_reg_rtx (XFmode);
16607
16608   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16609   emit_insn (gen_asinxf2 (op0, op1));
16610   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16611   DONE;
16612 })
16613
16614 (define_expand "acosxf2"
16615   [(set (match_dup 2)
16616         (mult:XF (match_operand:XF 1 "register_operand" "")
16617                  (match_dup 1)))
16618    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16619    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16620    (parallel [(set (match_operand:XF 0 "register_operand" "")
16621                    (unspec:XF [(match_dup 1) (match_dup 5)]
16622                               UNSPEC_FPATAN))
16623               (clobber (match_scratch:XF 6 ""))])]
16624   "TARGET_USE_FANCY_MATH_387
16625    && flag_unsafe_math_optimizations && !optimize_size"
16626 {
16627   int i;
16628
16629   for (i = 2; i < 6; i++)
16630     operands[i] = gen_reg_rtx (XFmode);
16631
16632   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16633 })
16634
16635 (define_expand "acos<mode>2"
16636   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16637    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16638  "TARGET_USE_FANCY_MATH_387
16639    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16640        || TARGET_MIX_SSE_I387)
16641    && flag_unsafe_math_optimizations && !optimize_size"
16642 {
16643   rtx op0 = gen_reg_rtx (XFmode);
16644   rtx op1 = gen_reg_rtx (XFmode);
16645
16646   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16647   emit_insn (gen_acosxf2 (op0, op1));
16648   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16649   DONE;
16650 })
16651
16652 (define_insn "fyl2xxf3_i387"
16653   [(set (match_operand:XF 0 "register_operand" "=f")
16654         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16655                     (match_operand:XF 2 "register_operand" "u")]
16656                    UNSPEC_FYL2X))
16657    (clobber (match_scratch:XF 3 "=2"))]
16658   "TARGET_USE_FANCY_MATH_387
16659    && flag_unsafe_math_optimizations"
16660   "fyl2x"
16661   [(set_attr "type" "fpspc")
16662    (set_attr "mode" "XF")])
16663
16664 (define_insn "fyl2x_extend<mode>xf3_i387"
16665   [(set (match_operand:XF 0 "register_operand" "=f")
16666         (unspec:XF [(float_extend:XF
16667                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16668                     (match_operand:XF 2 "register_operand" "u")]
16669                    UNSPEC_FYL2X))
16670    (clobber (match_scratch:XF 3 "=2"))]
16671   "TARGET_USE_FANCY_MATH_387
16672    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16673        || TARGET_MIX_SSE_I387)
16674    && flag_unsafe_math_optimizations"
16675   "fyl2x"
16676   [(set_attr "type" "fpspc")
16677    (set_attr "mode" "XF")])
16678
16679 (define_expand "logxf2"
16680   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16681                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16682                                (match_dup 2)] UNSPEC_FYL2X))
16683               (clobber (match_scratch:XF 3 ""))])]
16684   "TARGET_USE_FANCY_MATH_387
16685    && flag_unsafe_math_optimizations"
16686 {
16687   operands[2] = gen_reg_rtx (XFmode);
16688   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16689 })
16690
16691 (define_expand "log<mode>2"
16692   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16693    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16694   "TARGET_USE_FANCY_MATH_387
16695    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16696        || TARGET_MIX_SSE_I387)
16697    && flag_unsafe_math_optimizations"
16698 {
16699   rtx op0 = gen_reg_rtx (XFmode);
16700
16701   rtx op2 = gen_reg_rtx (XFmode);
16702   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16703
16704   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16705   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16706   DONE;
16707 })
16708
16709 (define_expand "log10xf2"
16710   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16711                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16712                                (match_dup 2)] UNSPEC_FYL2X))
16713               (clobber (match_scratch:XF 3 ""))])]
16714   "TARGET_USE_FANCY_MATH_387
16715    && flag_unsafe_math_optimizations"
16716 {
16717   operands[2] = gen_reg_rtx (XFmode);
16718   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16719 })
16720
16721 (define_expand "log10<mode>2"
16722   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16723    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16724   "TARGET_USE_FANCY_MATH_387
16725    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16726        || TARGET_MIX_SSE_I387)
16727    && flag_unsafe_math_optimizations"
16728 {
16729   rtx op0 = gen_reg_rtx (XFmode);
16730
16731   rtx op2 = gen_reg_rtx (XFmode);
16732   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16733
16734   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16735   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16736   DONE;
16737 })
16738
16739 (define_expand "log2xf2"
16740   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16741                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16742                                (match_dup 2)] UNSPEC_FYL2X))
16743               (clobber (match_scratch:XF 3 ""))])]
16744   "TARGET_USE_FANCY_MATH_387
16745    && flag_unsafe_math_optimizations"
16746 {
16747   operands[2] = gen_reg_rtx (XFmode);
16748   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16749 })
16750
16751 (define_expand "log2<mode>2"
16752   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16753    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16754   "TARGET_USE_FANCY_MATH_387
16755    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16756        || TARGET_MIX_SSE_I387)
16757    && flag_unsafe_math_optimizations"
16758 {
16759   rtx op0 = gen_reg_rtx (XFmode);
16760
16761   rtx op2 = gen_reg_rtx (XFmode);
16762   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16763
16764   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16765   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16766   DONE;
16767 })
16768
16769 (define_insn "fyl2xp1xf3_i387"
16770   [(set (match_operand:XF 0 "register_operand" "=f")
16771         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16772                     (match_operand:XF 2 "register_operand" "u")]
16773                    UNSPEC_FYL2XP1))
16774    (clobber (match_scratch:XF 3 "=2"))]
16775   "TARGET_USE_FANCY_MATH_387
16776    && flag_unsafe_math_optimizations"
16777   "fyl2xp1"
16778   [(set_attr "type" "fpspc")
16779    (set_attr "mode" "XF")])
16780
16781 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16782   [(set (match_operand:XF 0 "register_operand" "=f")
16783         (unspec:XF [(float_extend:XF
16784                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16785                     (match_operand:XF 2 "register_operand" "u")]
16786                    UNSPEC_FYL2XP1))
16787    (clobber (match_scratch:XF 3 "=2"))]
16788   "TARGET_USE_FANCY_MATH_387
16789    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16790        || TARGET_MIX_SSE_I387)
16791    && flag_unsafe_math_optimizations"
16792   "fyl2xp1"
16793   [(set_attr "type" "fpspc")
16794    (set_attr "mode" "XF")])
16795
16796 (define_expand "log1pxf2"
16797   [(use (match_operand:XF 0 "register_operand" ""))
16798    (use (match_operand:XF 1 "register_operand" ""))]
16799   "TARGET_USE_FANCY_MATH_387
16800    && flag_unsafe_math_optimizations && !optimize_size"
16801 {
16802   ix86_emit_i387_log1p (operands[0], operands[1]);
16803   DONE;
16804 })
16805
16806 (define_expand "log1p<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 && !optimize_size"
16813 {
16814   rtx op0 = gen_reg_rtx (XFmode);
16815
16816   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16817
16818   ix86_emit_i387_log1p (op0, operands[1]);
16819   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16820   DONE;
16821 })
16822
16823 (define_insn "fxtractxf3_i387"
16824   [(set (match_operand:XF 0 "register_operand" "=f")
16825         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16826                    UNSPEC_XTRACT_FRACT))
16827    (set (match_operand:XF 1 "register_operand" "=u")
16828         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16829   "TARGET_USE_FANCY_MATH_387
16830    && flag_unsafe_math_optimizations"
16831   "fxtract"
16832   [(set_attr "type" "fpspc")
16833    (set_attr "mode" "XF")])
16834
16835 (define_insn "fxtract_extend<mode>xf3_i387"
16836   [(set (match_operand:XF 0 "register_operand" "=f")
16837         (unspec:XF [(float_extend:XF
16838                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16839                    UNSPEC_XTRACT_FRACT))
16840    (set (match_operand:XF 1 "register_operand" "=u")
16841         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16842   "TARGET_USE_FANCY_MATH_387
16843    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16844        || TARGET_MIX_SSE_I387)
16845    && flag_unsafe_math_optimizations"
16846   "fxtract"
16847   [(set_attr "type" "fpspc")
16848    (set_attr "mode" "XF")])
16849
16850 (define_expand "logbxf2"
16851   [(parallel [(set (match_dup 2)
16852                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16853                               UNSPEC_XTRACT_FRACT))
16854               (set (match_operand:XF 0 "register_operand" "")
16855                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16856   "TARGET_USE_FANCY_MATH_387
16857    && flag_unsafe_math_optimizations"
16858 {
16859   operands[2] = gen_reg_rtx (XFmode);
16860 })
16861
16862 (define_expand "logb<mode>2"
16863   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16864    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16865   "TARGET_USE_FANCY_MATH_387
16866    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16867        || TARGET_MIX_SSE_I387)
16868    && flag_unsafe_math_optimizations"
16869 {
16870   rtx op0 = gen_reg_rtx (XFmode);
16871   rtx op1 = gen_reg_rtx (XFmode);
16872
16873   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16874   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16875   DONE;
16876 })
16877
16878 (define_expand "ilogbxf2"
16879   [(use (match_operand:SI 0 "register_operand" ""))
16880    (use (match_operand:XF 1 "register_operand" ""))]
16881   "TARGET_USE_FANCY_MATH_387
16882    && flag_unsafe_math_optimizations && !optimize_size"
16883 {
16884   rtx op0 = gen_reg_rtx (XFmode);
16885   rtx op1 = gen_reg_rtx (XFmode);
16886
16887   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16888   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16889   DONE;
16890 })
16891
16892 (define_expand "ilogb<mode>2"
16893   [(use (match_operand:SI 0 "register_operand" ""))
16894    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16895   "TARGET_USE_FANCY_MATH_387
16896    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16897        || TARGET_MIX_SSE_I387)
16898    && flag_unsafe_math_optimizations && !optimize_size"
16899 {
16900   rtx op0 = gen_reg_rtx (XFmode);
16901   rtx op1 = gen_reg_rtx (XFmode);
16902
16903   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16904   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16905   DONE;
16906 })
16907
16908 (define_insn "*f2xm1xf2_i387"
16909   [(set (match_operand:XF 0 "register_operand" "=f")
16910         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16911                    UNSPEC_F2XM1))]
16912   "TARGET_USE_FANCY_MATH_387
16913    && flag_unsafe_math_optimizations"
16914   "f2xm1"
16915   [(set_attr "type" "fpspc")
16916    (set_attr "mode" "XF")])
16917
16918 (define_insn "*fscalexf4_i387"
16919   [(set (match_operand:XF 0 "register_operand" "=f")
16920         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16921                     (match_operand:XF 3 "register_operand" "1")]
16922                    UNSPEC_FSCALE_FRACT))
16923    (set (match_operand:XF 1 "register_operand" "=u")
16924         (unspec:XF [(match_dup 2) (match_dup 3)]
16925                    UNSPEC_FSCALE_EXP))]
16926   "TARGET_USE_FANCY_MATH_387
16927    && flag_unsafe_math_optimizations"
16928   "fscale"
16929   [(set_attr "type" "fpspc")
16930    (set_attr "mode" "XF")])
16931
16932 (define_expand "expNcorexf3"
16933   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16934                                (match_operand:XF 2 "register_operand" "")))
16935    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16936    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16937    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16938    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16939    (parallel [(set (match_operand:XF 0 "register_operand" "")
16940                    (unspec:XF [(match_dup 8) (match_dup 4)]
16941                               UNSPEC_FSCALE_FRACT))
16942               (set (match_dup 9)
16943                    (unspec:XF [(match_dup 8) (match_dup 4)]
16944                               UNSPEC_FSCALE_EXP))])]
16945   "TARGET_USE_FANCY_MATH_387
16946    && flag_unsafe_math_optimizations && !optimize_size"
16947 {
16948   int i;
16949
16950   for (i = 3; i < 10; i++)
16951     operands[i] = gen_reg_rtx (XFmode);
16952
16953   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16954 })
16955
16956 (define_expand "expxf2"
16957   [(use (match_operand:XF 0 "register_operand" ""))
16958    (use (match_operand:XF 1 "register_operand" ""))]
16959   "TARGET_USE_FANCY_MATH_387
16960    && flag_unsafe_math_optimizations && !optimize_size"
16961 {
16962   rtx op2 = gen_reg_rtx (XFmode);
16963   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16964
16965   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16966   DONE;
16967 })
16968
16969 (define_expand "exp<mode>2"
16970   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16971    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16972  "TARGET_USE_FANCY_MATH_387
16973    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16974        || TARGET_MIX_SSE_I387)
16975    && flag_unsafe_math_optimizations && !optimize_size"
16976 {
16977   rtx op0 = gen_reg_rtx (XFmode);
16978   rtx op1 = gen_reg_rtx (XFmode);
16979
16980   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16981   emit_insn (gen_expxf2 (op0, op1));
16982   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16983   DONE;
16984 })
16985
16986 (define_expand "exp10xf2"
16987   [(use (match_operand:XF 0 "register_operand" ""))
16988    (use (match_operand:XF 1 "register_operand" ""))]
16989   "TARGET_USE_FANCY_MATH_387
16990    && flag_unsafe_math_optimizations && !optimize_size"
16991 {
16992   rtx op2 = gen_reg_rtx (XFmode);
16993   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16994
16995   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16996   DONE;
16997 })
16998
16999 (define_expand "exp10<mode>2"
17000   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17001    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17002  "TARGET_USE_FANCY_MATH_387
17003    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17004        || TARGET_MIX_SSE_I387)
17005    && flag_unsafe_math_optimizations && !optimize_size"
17006 {
17007   rtx op0 = gen_reg_rtx (XFmode);
17008   rtx op1 = gen_reg_rtx (XFmode);
17009
17010   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17011   emit_insn (gen_exp10xf2 (op0, op1));
17012   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17013   DONE;
17014 })
17015
17016 (define_expand "exp2xf2"
17017   [(use (match_operand:XF 0 "register_operand" ""))
17018    (use (match_operand:XF 1 "register_operand" ""))]
17019   "TARGET_USE_FANCY_MATH_387
17020    && flag_unsafe_math_optimizations && !optimize_size"
17021 {
17022   rtx op2 = gen_reg_rtx (XFmode);
17023   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17024
17025   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17026   DONE;
17027 })
17028
17029 (define_expand "exp2<mode>2"
17030   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17031    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17032  "TARGET_USE_FANCY_MATH_387
17033    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17034        || TARGET_MIX_SSE_I387)
17035    && flag_unsafe_math_optimizations && !optimize_size"
17036 {
17037   rtx op0 = gen_reg_rtx (XFmode);
17038   rtx op1 = gen_reg_rtx (XFmode);
17039
17040   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17041   emit_insn (gen_exp2xf2 (op0, op1));
17042   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17043   DONE;
17044 })
17045
17046 (define_expand "expm1xf2"
17047   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17048                                (match_dup 2)))
17049    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17050    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17051    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17052    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17053    (parallel [(set (match_dup 7)
17054                    (unspec:XF [(match_dup 6) (match_dup 4)]
17055                               UNSPEC_FSCALE_FRACT))
17056               (set (match_dup 8)
17057                    (unspec:XF [(match_dup 6) (match_dup 4)]
17058                               UNSPEC_FSCALE_EXP))])
17059    (parallel [(set (match_dup 10)
17060                    (unspec:XF [(match_dup 9) (match_dup 8)]
17061                               UNSPEC_FSCALE_FRACT))
17062               (set (match_dup 11)
17063                    (unspec:XF [(match_dup 9) (match_dup 8)]
17064                               UNSPEC_FSCALE_EXP))])
17065    (set (match_dup 12) (minus:XF (match_dup 10)
17066                                  (float_extend:XF (match_dup 13))))
17067    (set (match_operand:XF 0 "register_operand" "")
17068         (plus:XF (match_dup 12) (match_dup 7)))]
17069   "TARGET_USE_FANCY_MATH_387
17070    && flag_unsafe_math_optimizations && !optimize_size"
17071 {
17072   int i;
17073
17074   for (i = 2; i < 13; i++)
17075     operands[i] = gen_reg_rtx (XFmode);
17076
17077   operands[13]
17078     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17079
17080   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17081 })
17082
17083 (define_expand "expm1<mode>2"
17084   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17085    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17086  "TARGET_USE_FANCY_MATH_387
17087    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17088        || TARGET_MIX_SSE_I387)
17089    && flag_unsafe_math_optimizations && !optimize_size"
17090 {
17091   rtx op0 = gen_reg_rtx (XFmode);
17092   rtx op1 = gen_reg_rtx (XFmode);
17093
17094   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17095   emit_insn (gen_expm1xf2 (op0, op1));
17096   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17097   DONE;
17098 })
17099
17100 (define_expand "ldexpxf3"
17101   [(set (match_dup 3)
17102         (float:XF (match_operand:SI 2 "register_operand" "")))
17103    (parallel [(set (match_operand:XF 0 " register_operand" "")
17104                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17105                                (match_dup 3)]
17106                               UNSPEC_FSCALE_FRACT))
17107               (set (match_dup 4)
17108                    (unspec:XF [(match_dup 1) (match_dup 3)]
17109                               UNSPEC_FSCALE_EXP))])]
17110   "TARGET_USE_FANCY_MATH_387
17111    && flag_unsafe_math_optimizations && !optimize_size"
17112 {
17113   operands[3] = gen_reg_rtx (XFmode);
17114   operands[4] = gen_reg_rtx (XFmode);
17115 })
17116
17117 (define_expand "ldexp<mode>3"
17118   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17119    (use (match_operand:X87MODEF12 1 "general_operand" ""))
17120    (use (match_operand:SI 2 "register_operand" ""))]
17121  "TARGET_USE_FANCY_MATH_387
17122    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17123        || TARGET_MIX_SSE_I387)
17124    && flag_unsafe_math_optimizations && !optimize_size"
17125 {
17126   rtx op0 = gen_reg_rtx (XFmode);
17127   rtx op1 = gen_reg_rtx (XFmode);
17128
17129   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17130   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17131   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17132   DONE;
17133 })
17134
17135 (define_expand "scalbxf3"
17136   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17137                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17138                                (match_operand:XF 2 "register_operand" "")]
17139                               UNSPEC_FSCALE_FRACT))
17140               (set (match_dup 3)
17141                    (unspec:XF [(match_dup 1) (match_dup 2)]
17142                               UNSPEC_FSCALE_EXP))])]
17143   "TARGET_USE_FANCY_MATH_387
17144    && flag_unsafe_math_optimizations && !optimize_size"
17145 {
17146   operands[3] = gen_reg_rtx (XFmode);
17147 })
17148
17149 (define_expand "scalb<mode>3"
17150   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17151    (use (match_operand:X87MODEF12 1 "general_operand" ""))
17152    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
17153  "TARGET_USE_FANCY_MATH_387
17154    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17155        || TARGET_MIX_SSE_I387)
17156    && flag_unsafe_math_optimizations && !optimize_size"
17157 {
17158   rtx op0 = gen_reg_rtx (XFmode);
17159   rtx op1 = gen_reg_rtx (XFmode);
17160   rtx op2 = gen_reg_rtx (XFmode);
17161
17162   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17163   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17164   emit_insn (gen_scalbxf3 (op0, op1, op2));
17165   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17166   DONE;
17167 })
17168 \f
17169
17170 (define_insn "rintxf2"
17171   [(set (match_operand:XF 0 "register_operand" "=f")
17172         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17173                    UNSPEC_FRNDINT))]
17174   "TARGET_USE_FANCY_MATH_387
17175    && flag_unsafe_math_optimizations"
17176   "frndint"
17177   [(set_attr "type" "fpspc")
17178    (set_attr "mode" "XF")])
17179
17180 (define_expand "rint<mode>2"
17181   [(use (match_operand:SSEMODEF 0 "register_operand" ""))
17182    (use (match_operand:SSEMODEF 1 "register_operand" ""))]
17183   "(TARGET_USE_FANCY_MATH_387
17184     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17185         || TARGET_MIX_SSE_I387)
17186     && flag_unsafe_math_optimizations)
17187    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17188        && !flag_trapping_math
17189        && !optimize_size)"
17190 {
17191   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17192       && !flag_trapping_math
17193       && !optimize_size)
17194     ix86_expand_rint (operand0, operand1);
17195   else
17196     {
17197       rtx op0 = gen_reg_rtx (XFmode);
17198       rtx op1 = gen_reg_rtx (XFmode);
17199
17200       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17201       emit_insn (gen_rintxf2 (op0, op1));
17202
17203       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17204     }
17205   DONE;
17206 })
17207
17208 (define_expand "round<mode>2"
17209   [(match_operand:SSEMODEF 0 "register_operand" "")
17210    (match_operand:SSEMODEF 1 "nonimmediate_operand" "")]
17211   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17212    && !flag_trapping_math && !flag_rounding_math
17213    && !optimize_size"
17214 {
17215   if ((<MODE>mode != DFmode) || TARGET_64BIT)
17216     ix86_expand_round (operand0, operand1);
17217   else
17218     ix86_expand_rounddf_32 (operand0, operand1);
17219   DONE;
17220 })
17221
17222 (define_insn_and_split "*fistdi2_1"
17223   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17224         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17225                    UNSPEC_FIST))]
17226   "TARGET_USE_FANCY_MATH_387
17227    && !(reload_completed || reload_in_progress)"
17228   "#"
17229   "&& 1"
17230   [(const_int 0)]
17231 {
17232   if (memory_operand (operands[0], VOIDmode))
17233     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17234   else
17235     {
17236       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17237       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17238                                          operands[2]));
17239     }
17240   DONE;
17241 }
17242   [(set_attr "type" "fpspc")
17243    (set_attr "mode" "DI")])
17244
17245 (define_insn "fistdi2"
17246   [(set (match_operand:DI 0 "memory_operand" "=m")
17247         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17248                    UNSPEC_FIST))
17249    (clobber (match_scratch:XF 2 "=&1f"))]
17250   "TARGET_USE_FANCY_MATH_387"
17251   "* return output_fix_trunc (insn, operands, 0);"
17252   [(set_attr "type" "fpspc")
17253    (set_attr "mode" "DI")])
17254
17255 (define_insn "fistdi2_with_temp"
17256   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17257         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17258                    UNSPEC_FIST))
17259    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17260    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17261   "TARGET_USE_FANCY_MATH_387"
17262   "#"
17263   [(set_attr "type" "fpspc")
17264    (set_attr "mode" "DI")])
17265
17266 (define_split
17267   [(set (match_operand:DI 0 "register_operand" "")
17268         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17269                    UNSPEC_FIST))
17270    (clobber (match_operand:DI 2 "memory_operand" ""))
17271    (clobber (match_scratch 3 ""))]
17272   "reload_completed"
17273   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17274               (clobber (match_dup 3))])
17275    (set (match_dup 0) (match_dup 2))]
17276   "")
17277
17278 (define_split
17279   [(set (match_operand:DI 0 "memory_operand" "")
17280         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17281                    UNSPEC_FIST))
17282    (clobber (match_operand:DI 2 "memory_operand" ""))
17283    (clobber (match_scratch 3 ""))]
17284   "reload_completed"
17285   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17286               (clobber (match_dup 3))])]
17287   "")
17288
17289 (define_insn_and_split "*fist<mode>2_1"
17290   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17291         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17292                            UNSPEC_FIST))]
17293   "TARGET_USE_FANCY_MATH_387
17294    && !(reload_completed || reload_in_progress)"
17295   "#"
17296   "&& 1"
17297   [(const_int 0)]
17298 {
17299   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17300   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17301                                         operands[2]));
17302   DONE;
17303 }
17304   [(set_attr "type" "fpspc")
17305    (set_attr "mode" "<MODE>")])
17306
17307 (define_insn "fist<mode>2"
17308   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17309         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17310                            UNSPEC_FIST))]
17311   "TARGET_USE_FANCY_MATH_387"
17312   "* return output_fix_trunc (insn, operands, 0);"
17313   [(set_attr "type" "fpspc")
17314    (set_attr "mode" "<MODE>")])
17315
17316 (define_insn "fist<mode>2_with_temp"
17317   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17318         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17319                            UNSPEC_FIST))
17320    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17321   "TARGET_USE_FANCY_MATH_387"
17322   "#"
17323   [(set_attr "type" "fpspc")
17324    (set_attr "mode" "<MODE>")])
17325
17326 (define_split
17327   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17328         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17329                            UNSPEC_FIST))
17330    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17331   "reload_completed"
17332   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17333    (set (match_dup 0) (match_dup 2))]
17334   "")
17335
17336 (define_split
17337   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17338         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17339                            UNSPEC_FIST))
17340    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17341   "reload_completed"
17342   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17343   "")
17344
17345 (define_expand "lrintxf<mode>2"
17346   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17347      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17348                       UNSPEC_FIST))]
17349   "TARGET_USE_FANCY_MATH_387"
17350   "")
17351
17352 (define_expand "lrint<SSEMODEF:mode><SSEMODEI24:mode>2"
17353   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17354      (unspec:SSEMODEI24 [(match_operand:SSEMODEF 1 "register_operand" "")]
17355                         UNSPEC_FIX_NOTRUNC))]
17356   "SSE_FLOAT_MODE_P (<SSEMODEF:MODE>mode) && TARGET_SSE_MATH
17357    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17358   "")
17359
17360 (define_expand "lround<SSEMODEF:mode><SSEMODEI24:mode>2"
17361   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17362    (match_operand:SSEMODEF 1 "register_operand" "")]
17363   "SSE_FLOAT_MODE_P (<SSEMODEF:MODE>mode) && TARGET_SSE_MATH
17364    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17365    && !flag_trapping_math && !flag_rounding_math
17366    && !optimize_size"
17367 {
17368   ix86_expand_lround (operand0, operand1);
17369   DONE;
17370 })
17371
17372 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17373 (define_insn_and_split "frndintxf2_floor"
17374   [(set (match_operand:XF 0 "register_operand" "=f")
17375         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17376          UNSPEC_FRNDINT_FLOOR))
17377    (clobber (reg:CC FLAGS_REG))]
17378   "TARGET_USE_FANCY_MATH_387
17379    && flag_unsafe_math_optimizations
17380    && !(reload_completed || reload_in_progress)"
17381   "#"
17382   "&& 1"
17383   [(const_int 0)]
17384 {
17385   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17386
17387   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17388   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17389
17390   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17391                                         operands[2], operands[3]));
17392   DONE;
17393 }
17394   [(set_attr "type" "frndint")
17395    (set_attr "i387_cw" "floor")
17396    (set_attr "mode" "XF")])
17397
17398 (define_insn "frndintxf2_floor_i387"
17399   [(set (match_operand:XF 0 "register_operand" "=f")
17400         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17401          UNSPEC_FRNDINT_FLOOR))
17402    (use (match_operand:HI 2 "memory_operand" "m"))
17403    (use (match_operand:HI 3 "memory_operand" "m"))]
17404   "TARGET_USE_FANCY_MATH_387
17405    && flag_unsafe_math_optimizations"
17406   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17407   [(set_attr "type" "frndint")
17408    (set_attr "i387_cw" "floor")
17409    (set_attr "mode" "XF")])
17410
17411 (define_expand "floorxf2"
17412   [(use (match_operand:XF 0 "register_operand" ""))
17413    (use (match_operand:XF 1 "register_operand" ""))]
17414   "TARGET_USE_FANCY_MATH_387
17415    && flag_unsafe_math_optimizations && !optimize_size"
17416 {
17417   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17418   DONE;
17419 })
17420
17421 (define_expand "floordf2"
17422   [(use (match_operand:DF 0 "register_operand" ""))
17423    (use (match_operand:DF 1 "register_operand" ""))]
17424   "((TARGET_USE_FANCY_MATH_387
17425      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17426      && flag_unsafe_math_optimizations)
17427     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17428         && !flag_trapping_math))
17429    && !optimize_size"
17430 {
17431   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17432       && !flag_trapping_math)
17433     {
17434       if (TARGET_64BIT)
17435         ix86_expand_floorceil (operand0, operand1, true);
17436       else
17437         ix86_expand_floorceildf_32 (operand0, operand1, true);
17438     }
17439   else
17440     {
17441       rtx op0 = gen_reg_rtx (XFmode);
17442       rtx op1 = gen_reg_rtx (XFmode);
17443
17444       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17445       emit_insn (gen_frndintxf2_floor (op0, op1));
17446
17447       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17448     }
17449   DONE;
17450 })
17451
17452 (define_expand "floorsf2"
17453   [(use (match_operand:SF 0 "register_operand" ""))
17454    (use (match_operand:SF 1 "register_operand" ""))]
17455   "((TARGET_USE_FANCY_MATH_387
17456      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17457      && flag_unsafe_math_optimizations)
17458     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17459         && !flag_trapping_math))
17460    && !optimize_size"
17461 {
17462   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17463       && !flag_trapping_math)
17464     ix86_expand_floorceil (operand0, operand1, true);
17465   else
17466     {
17467       rtx op0 = gen_reg_rtx (XFmode);
17468       rtx op1 = gen_reg_rtx (XFmode);
17469
17470       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17471       emit_insn (gen_frndintxf2_floor (op0, op1));
17472
17473       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17474     }
17475   DONE;
17476 })
17477
17478 (define_insn_and_split "*fist<mode>2_floor_1"
17479   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17480         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17481          UNSPEC_FIST_FLOOR))
17482    (clobber (reg:CC FLAGS_REG))]
17483   "TARGET_USE_FANCY_MATH_387
17484    && flag_unsafe_math_optimizations
17485    && !(reload_completed || reload_in_progress)"
17486   "#"
17487   "&& 1"
17488   [(const_int 0)]
17489 {
17490   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17491
17492   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17493   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17494   if (memory_operand (operands[0], VOIDmode))
17495     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17496                                       operands[2], operands[3]));
17497   else
17498     {
17499       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17500       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17501                                                   operands[2], operands[3],
17502                                                   operands[4]));
17503     }
17504   DONE;
17505 }
17506   [(set_attr "type" "fistp")
17507    (set_attr "i387_cw" "floor")
17508    (set_attr "mode" "<MODE>")])
17509
17510 (define_insn "fistdi2_floor"
17511   [(set (match_operand:DI 0 "memory_operand" "=m")
17512         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17513          UNSPEC_FIST_FLOOR))
17514    (use (match_operand:HI 2 "memory_operand" "m"))
17515    (use (match_operand:HI 3 "memory_operand" "m"))
17516    (clobber (match_scratch:XF 4 "=&1f"))]
17517   "TARGET_USE_FANCY_MATH_387
17518    && flag_unsafe_math_optimizations"
17519   "* return output_fix_trunc (insn, operands, 0);"
17520   [(set_attr "type" "fistp")
17521    (set_attr "i387_cw" "floor")
17522    (set_attr "mode" "DI")])
17523
17524 (define_insn "fistdi2_floor_with_temp"
17525   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17526         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17527          UNSPEC_FIST_FLOOR))
17528    (use (match_operand:HI 2 "memory_operand" "m,m"))
17529    (use (match_operand:HI 3 "memory_operand" "m,m"))
17530    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17531    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17532   "TARGET_USE_FANCY_MATH_387
17533    && flag_unsafe_math_optimizations"
17534   "#"
17535   [(set_attr "type" "fistp")
17536    (set_attr "i387_cw" "floor")
17537    (set_attr "mode" "DI")])
17538
17539 (define_split
17540   [(set (match_operand:DI 0 "register_operand" "")
17541         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17542          UNSPEC_FIST_FLOOR))
17543    (use (match_operand:HI 2 "memory_operand" ""))
17544    (use (match_operand:HI 3 "memory_operand" ""))
17545    (clobber (match_operand:DI 4 "memory_operand" ""))
17546    (clobber (match_scratch 5 ""))]
17547   "reload_completed"
17548   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17549               (use (match_dup 2))
17550               (use (match_dup 3))
17551               (clobber (match_dup 5))])
17552    (set (match_dup 0) (match_dup 4))]
17553   "")
17554
17555 (define_split
17556   [(set (match_operand:DI 0 "memory_operand" "")
17557         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17558          UNSPEC_FIST_FLOOR))
17559    (use (match_operand:HI 2 "memory_operand" ""))
17560    (use (match_operand:HI 3 "memory_operand" ""))
17561    (clobber (match_operand:DI 4 "memory_operand" ""))
17562    (clobber (match_scratch 5 ""))]
17563   "reload_completed"
17564   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17565               (use (match_dup 2))
17566               (use (match_dup 3))
17567               (clobber (match_dup 5))])]
17568   "")
17569
17570 (define_insn "fist<mode>2_floor"
17571   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17572         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17573          UNSPEC_FIST_FLOOR))
17574    (use (match_operand:HI 2 "memory_operand" "m"))
17575    (use (match_operand:HI 3 "memory_operand" "m"))]
17576   "TARGET_USE_FANCY_MATH_387
17577    && flag_unsafe_math_optimizations"
17578   "* return output_fix_trunc (insn, operands, 0);"
17579   [(set_attr "type" "fistp")
17580    (set_attr "i387_cw" "floor")
17581    (set_attr "mode" "<MODE>")])
17582
17583 (define_insn "fist<mode>2_floor_with_temp"
17584   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17585         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17586          UNSPEC_FIST_FLOOR))
17587    (use (match_operand:HI 2 "memory_operand" "m,m"))
17588    (use (match_operand:HI 3 "memory_operand" "m,m"))
17589    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17590   "TARGET_USE_FANCY_MATH_387
17591    && flag_unsafe_math_optimizations"
17592   "#"
17593   [(set_attr "type" "fistp")
17594    (set_attr "i387_cw" "floor")
17595    (set_attr "mode" "<MODE>")])
17596
17597 (define_split
17598   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17599         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17600          UNSPEC_FIST_FLOOR))
17601    (use (match_operand:HI 2 "memory_operand" ""))
17602    (use (match_operand:HI 3 "memory_operand" ""))
17603    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17604   "reload_completed"
17605   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17606                                   UNSPEC_FIST_FLOOR))
17607               (use (match_dup 2))
17608               (use (match_dup 3))])
17609    (set (match_dup 0) (match_dup 4))]
17610   "")
17611
17612 (define_split
17613   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17614         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17615          UNSPEC_FIST_FLOOR))
17616    (use (match_operand:HI 2 "memory_operand" ""))
17617    (use (match_operand:HI 3 "memory_operand" ""))
17618    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17619   "reload_completed"
17620   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17621                                   UNSPEC_FIST_FLOOR))
17622               (use (match_dup 2))
17623               (use (match_dup 3))])]
17624   "")
17625
17626 (define_expand "lfloorxf<mode>2"
17627   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17628                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17629                     UNSPEC_FIST_FLOOR))
17630               (clobber (reg:CC FLAGS_REG))])]
17631   "TARGET_USE_FANCY_MATH_387
17632    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17633    && flag_unsafe_math_optimizations"
17634   "")
17635
17636 (define_expand "lfloor<mode>di2"
17637   [(match_operand:DI 0 "nonimmediate_operand" "")
17638    (match_operand:SSEMODEF 1 "register_operand" "")]
17639   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17640    && !flag_trapping_math
17641    && !optimize_size"
17642 {
17643   ix86_expand_lfloorceil (operand0, operand1, true);
17644   DONE;
17645 })
17646
17647 (define_expand "lfloor<mode>si2"
17648   [(match_operand:SI 0 "nonimmediate_operand" "")
17649    (match_operand:SSEMODEF 1 "register_operand" "")]
17650   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17651    && !flag_trapping_math
17652    && (!optimize_size || !TARGET_64BIT)"
17653 {
17654   ix86_expand_lfloorceil (operand0, operand1, true);
17655   DONE;
17656 })
17657
17658 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17659 (define_insn_and_split "frndintxf2_ceil"
17660   [(set (match_operand:XF 0 "register_operand" "=f")
17661         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17662          UNSPEC_FRNDINT_CEIL))
17663    (clobber (reg:CC FLAGS_REG))]
17664   "TARGET_USE_FANCY_MATH_387
17665    && flag_unsafe_math_optimizations
17666    && !(reload_completed || reload_in_progress)"
17667   "#"
17668   "&& 1"
17669   [(const_int 0)]
17670 {
17671   ix86_optimize_mode_switching[I387_CEIL] = 1;
17672
17673   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17674   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17675
17676   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17677                                        operands[2], operands[3]));
17678   DONE;
17679 }
17680   [(set_attr "type" "frndint")
17681    (set_attr "i387_cw" "ceil")
17682    (set_attr "mode" "XF")])
17683
17684 (define_insn "frndintxf2_ceil_i387"
17685   [(set (match_operand:XF 0 "register_operand" "=f")
17686         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17687          UNSPEC_FRNDINT_CEIL))
17688    (use (match_operand:HI 2 "memory_operand" "m"))
17689    (use (match_operand:HI 3 "memory_operand" "m"))]
17690   "TARGET_USE_FANCY_MATH_387
17691    && flag_unsafe_math_optimizations"
17692   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17693   [(set_attr "type" "frndint")
17694    (set_attr "i387_cw" "ceil")
17695    (set_attr "mode" "XF")])
17696
17697 (define_expand "ceilxf2"
17698   [(use (match_operand:XF 0 "register_operand" ""))
17699    (use (match_operand:XF 1 "register_operand" ""))]
17700   "TARGET_USE_FANCY_MATH_387
17701    && flag_unsafe_math_optimizations && !optimize_size"
17702 {
17703   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17704   DONE;
17705 })
17706
17707 (define_expand "ceildf2"
17708   [(use (match_operand:DF 0 "register_operand" ""))
17709    (use (match_operand:DF 1 "register_operand" ""))]
17710   "((TARGET_USE_FANCY_MATH_387
17711      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17712      && flag_unsafe_math_optimizations)
17713     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17714         && !flag_trapping_math))
17715    && !optimize_size"
17716 {
17717   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17718       && !flag_trapping_math)
17719     {
17720       if (TARGET_64BIT)
17721         ix86_expand_floorceil (operand0, operand1, false);
17722       else
17723         ix86_expand_floorceildf_32 (operand0, operand1, false);
17724     }
17725   else
17726     {
17727       rtx op0 = gen_reg_rtx (XFmode);
17728       rtx op1 = gen_reg_rtx (XFmode);
17729
17730       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17731       emit_insn (gen_frndintxf2_ceil (op0, op1));
17732
17733       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17734     }
17735   DONE;
17736 })
17737
17738 (define_expand "ceilsf2"
17739   [(use (match_operand:SF 0 "register_operand" ""))
17740    (use (match_operand:SF 1 "register_operand" ""))]
17741   "((TARGET_USE_FANCY_MATH_387
17742      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17743      && flag_unsafe_math_optimizations)
17744     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17745         && !flag_trapping_math))
17746    && !optimize_size"
17747 {
17748   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17749       && !flag_trapping_math)
17750     ix86_expand_floorceil (operand0, operand1, false);
17751   else
17752     {
17753       rtx op0 = gen_reg_rtx (XFmode);
17754       rtx op1 = gen_reg_rtx (XFmode);
17755
17756       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17757       emit_insn (gen_frndintxf2_ceil (op0, op1));
17758
17759       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17760     }
17761   DONE;
17762 })
17763
17764 (define_insn_and_split "*fist<mode>2_ceil_1"
17765   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17766         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17767          UNSPEC_FIST_CEIL))
17768    (clobber (reg:CC FLAGS_REG))]
17769   "TARGET_USE_FANCY_MATH_387
17770    && flag_unsafe_math_optimizations
17771    && !(reload_completed || reload_in_progress)"
17772   "#"
17773   "&& 1"
17774   [(const_int 0)]
17775 {
17776   ix86_optimize_mode_switching[I387_CEIL] = 1;
17777
17778   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17779   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17780   if (memory_operand (operands[0], VOIDmode))
17781     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17782                                      operands[2], operands[3]));
17783   else
17784     {
17785       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17786       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17787                                                  operands[2], operands[3],
17788                                                  operands[4]));
17789     }
17790   DONE;
17791 }
17792   [(set_attr "type" "fistp")
17793    (set_attr "i387_cw" "ceil")
17794    (set_attr "mode" "<MODE>")])
17795
17796 (define_insn "fistdi2_ceil"
17797   [(set (match_operand:DI 0 "memory_operand" "=m")
17798         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17799          UNSPEC_FIST_CEIL))
17800    (use (match_operand:HI 2 "memory_operand" "m"))
17801    (use (match_operand:HI 3 "memory_operand" "m"))
17802    (clobber (match_scratch:XF 4 "=&1f"))]
17803   "TARGET_USE_FANCY_MATH_387
17804    && flag_unsafe_math_optimizations"
17805   "* return output_fix_trunc (insn, operands, 0);"
17806   [(set_attr "type" "fistp")
17807    (set_attr "i387_cw" "ceil")
17808    (set_attr "mode" "DI")])
17809
17810 (define_insn "fistdi2_ceil_with_temp"
17811   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17812         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17813          UNSPEC_FIST_CEIL))
17814    (use (match_operand:HI 2 "memory_operand" "m,m"))
17815    (use (match_operand:HI 3 "memory_operand" "m,m"))
17816    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17817    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17818   "TARGET_USE_FANCY_MATH_387
17819    && flag_unsafe_math_optimizations"
17820   "#"
17821   [(set_attr "type" "fistp")
17822    (set_attr "i387_cw" "ceil")
17823    (set_attr "mode" "DI")])
17824
17825 (define_split
17826   [(set (match_operand:DI 0 "register_operand" "")
17827         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17828          UNSPEC_FIST_CEIL))
17829    (use (match_operand:HI 2 "memory_operand" ""))
17830    (use (match_operand:HI 3 "memory_operand" ""))
17831    (clobber (match_operand:DI 4 "memory_operand" ""))
17832    (clobber (match_scratch 5 ""))]
17833   "reload_completed"
17834   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17835               (use (match_dup 2))
17836               (use (match_dup 3))
17837               (clobber (match_dup 5))])
17838    (set (match_dup 0) (match_dup 4))]
17839   "")
17840
17841 (define_split
17842   [(set (match_operand:DI 0 "memory_operand" "")
17843         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17844          UNSPEC_FIST_CEIL))
17845    (use (match_operand:HI 2 "memory_operand" ""))
17846    (use (match_operand:HI 3 "memory_operand" ""))
17847    (clobber (match_operand:DI 4 "memory_operand" ""))
17848    (clobber (match_scratch 5 ""))]
17849   "reload_completed"
17850   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17851               (use (match_dup 2))
17852               (use (match_dup 3))
17853               (clobber (match_dup 5))])]
17854   "")
17855
17856 (define_insn "fist<mode>2_ceil"
17857   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17858         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17859          UNSPEC_FIST_CEIL))
17860    (use (match_operand:HI 2 "memory_operand" "m"))
17861    (use (match_operand:HI 3 "memory_operand" "m"))]
17862   "TARGET_USE_FANCY_MATH_387
17863    && flag_unsafe_math_optimizations"
17864   "* return output_fix_trunc (insn, operands, 0);"
17865   [(set_attr "type" "fistp")
17866    (set_attr "i387_cw" "ceil")
17867    (set_attr "mode" "<MODE>")])
17868
17869 (define_insn "fist<mode>2_ceil_with_temp"
17870   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17871         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17872          UNSPEC_FIST_CEIL))
17873    (use (match_operand:HI 2 "memory_operand" "m,m"))
17874    (use (match_operand:HI 3 "memory_operand" "m,m"))
17875    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17876   "TARGET_USE_FANCY_MATH_387
17877    && flag_unsafe_math_optimizations"
17878   "#"
17879   [(set_attr "type" "fistp")
17880    (set_attr "i387_cw" "ceil")
17881    (set_attr "mode" "<MODE>")])
17882
17883 (define_split
17884   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17885         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17886          UNSPEC_FIST_CEIL))
17887    (use (match_operand:HI 2 "memory_operand" ""))
17888    (use (match_operand:HI 3 "memory_operand" ""))
17889    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17890   "reload_completed"
17891   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17892                                   UNSPEC_FIST_CEIL))
17893               (use (match_dup 2))
17894               (use (match_dup 3))])
17895    (set (match_dup 0) (match_dup 4))]
17896   "")
17897
17898 (define_split
17899   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17900         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17901          UNSPEC_FIST_CEIL))
17902    (use (match_operand:HI 2 "memory_operand" ""))
17903    (use (match_operand:HI 3 "memory_operand" ""))
17904    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17905   "reload_completed"
17906   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17907                                   UNSPEC_FIST_CEIL))
17908               (use (match_dup 2))
17909               (use (match_dup 3))])]
17910   "")
17911
17912 (define_expand "lceilxf<mode>2"
17913   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17914                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17915                     UNSPEC_FIST_CEIL))
17916               (clobber (reg:CC FLAGS_REG))])]
17917   "TARGET_USE_FANCY_MATH_387
17918    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17919    && flag_unsafe_math_optimizations"
17920   "")
17921
17922 (define_expand "lceil<mode>di2"
17923   [(match_operand:DI 0 "nonimmediate_operand" "")
17924    (match_operand:SSEMODEF 1 "register_operand" "")]
17925   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17926    && !flag_trapping_math"
17927 {
17928   ix86_expand_lfloorceil (operand0, operand1, false);
17929   DONE;
17930 })
17931
17932 (define_expand "lceil<mode>si2"
17933   [(match_operand:SI 0 "nonimmediate_operand" "")
17934    (match_operand:SSEMODEF 1 "register_operand" "")]
17935   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17936    && !flag_trapping_math"
17937 {
17938   ix86_expand_lfloorceil (operand0, operand1, false);
17939   DONE;
17940 })
17941
17942 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17943 (define_insn_and_split "frndintxf2_trunc"
17944   [(set (match_operand:XF 0 "register_operand" "=f")
17945         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17946          UNSPEC_FRNDINT_TRUNC))
17947    (clobber (reg:CC FLAGS_REG))]
17948   "TARGET_USE_FANCY_MATH_387
17949    && flag_unsafe_math_optimizations
17950    && !(reload_completed || reload_in_progress)"
17951   "#"
17952   "&& 1"
17953   [(const_int 0)]
17954 {
17955   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17956
17957   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17958   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17959
17960   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17961                                         operands[2], operands[3]));
17962   DONE;
17963 }
17964   [(set_attr "type" "frndint")
17965    (set_attr "i387_cw" "trunc")
17966    (set_attr "mode" "XF")])
17967
17968 (define_insn "frndintxf2_trunc_i387"
17969   [(set (match_operand:XF 0 "register_operand" "=f")
17970         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17971          UNSPEC_FRNDINT_TRUNC))
17972    (use (match_operand:HI 2 "memory_operand" "m"))
17973    (use (match_operand:HI 3 "memory_operand" "m"))]
17974   "TARGET_USE_FANCY_MATH_387
17975    && flag_unsafe_math_optimizations"
17976   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17977   [(set_attr "type" "frndint")
17978    (set_attr "i387_cw" "trunc")
17979    (set_attr "mode" "XF")])
17980
17981 (define_expand "btruncxf2"
17982   [(use (match_operand:XF 0 "register_operand" ""))
17983    (use (match_operand:XF 1 "register_operand" ""))]
17984   "TARGET_USE_FANCY_MATH_387
17985    && flag_unsafe_math_optimizations && !optimize_size"
17986 {
17987   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17988   DONE;
17989 })
17990
17991 (define_expand "btruncdf2"
17992   [(use (match_operand:DF 0 "register_operand" ""))
17993    (use (match_operand:DF 1 "register_operand" ""))]
17994   "((TARGET_USE_FANCY_MATH_387
17995      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17996      && flag_unsafe_math_optimizations)
17997     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17998         && !flag_trapping_math))
17999    && !optimize_size"
18000 {
18001   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18002       && !flag_trapping_math)
18003     {
18004       if (TARGET_64BIT)
18005         ix86_expand_trunc (operand0, operand1);
18006       else
18007         ix86_expand_truncdf_32 (operand0, operand1);
18008     }
18009   else
18010     {
18011       rtx op0 = gen_reg_rtx (XFmode);
18012       rtx op1 = gen_reg_rtx (XFmode);
18013
18014       emit_insn (gen_extenddfxf2 (op1, operands[1]));
18015       emit_insn (gen_frndintxf2_trunc (op0, op1));
18016
18017       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18018     }
18019   DONE;
18020 })
18021
18022 (define_expand "btruncsf2"
18023   [(use (match_operand:SF 0 "register_operand" ""))
18024    (use (match_operand:SF 1 "register_operand" ""))]
18025   "((TARGET_USE_FANCY_MATH_387
18026      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18027      && flag_unsafe_math_optimizations)
18028     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18029         && !flag_trapping_math))
18030    && !optimize_size"
18031 {
18032   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18033       && !flag_trapping_math)
18034     ix86_expand_trunc (operand0, operand1);
18035   else
18036     {
18037       rtx op0 = gen_reg_rtx (XFmode);
18038       rtx op1 = gen_reg_rtx (XFmode);
18039
18040       emit_insn (gen_extendsfxf2 (op1, operands[1]));
18041       emit_insn (gen_frndintxf2_trunc (op0, op1));
18042
18043       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18044     }
18045   DONE;
18046 })
18047
18048 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18049 (define_insn_and_split "frndintxf2_mask_pm"
18050   [(set (match_operand:XF 0 "register_operand" "=f")
18051         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18052          UNSPEC_FRNDINT_MASK_PM))
18053    (clobber (reg:CC FLAGS_REG))]
18054   "TARGET_USE_FANCY_MATH_387
18055    && flag_unsafe_math_optimizations
18056    && !(reload_completed || reload_in_progress)"
18057   "#"
18058   "&& 1"
18059   [(const_int 0)]
18060 {
18061   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18062
18063   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18064   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18065
18066   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18067                                           operands[2], operands[3]));
18068   DONE;
18069 }
18070   [(set_attr "type" "frndint")
18071    (set_attr "i387_cw" "mask_pm")
18072    (set_attr "mode" "XF")])
18073
18074 (define_insn "frndintxf2_mask_pm_i387"
18075   [(set (match_operand:XF 0 "register_operand" "=f")
18076         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18077          UNSPEC_FRNDINT_MASK_PM))
18078    (use (match_operand:HI 2 "memory_operand" "m"))
18079    (use (match_operand:HI 3 "memory_operand" "m"))]
18080   "TARGET_USE_FANCY_MATH_387
18081    && flag_unsafe_math_optimizations"
18082   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18083   [(set_attr "type" "frndint")
18084    (set_attr "i387_cw" "mask_pm")
18085    (set_attr "mode" "XF")])
18086
18087 (define_expand "nearbyintxf2"
18088   [(use (match_operand:XF 0 "register_operand" ""))
18089    (use (match_operand:XF 1 "register_operand" ""))]
18090   "TARGET_USE_FANCY_MATH_387
18091    && flag_unsafe_math_optimizations"
18092 {
18093   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18094
18095   DONE;
18096 })
18097
18098 (define_expand "nearbyintdf2"
18099   [(use (match_operand:DF 0 "register_operand" ""))
18100    (use (match_operand:DF 1 "register_operand" ""))]
18101   "TARGET_USE_FANCY_MATH_387
18102    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18103    && flag_unsafe_math_optimizations"
18104 {
18105   rtx op0 = gen_reg_rtx (XFmode);
18106   rtx op1 = gen_reg_rtx (XFmode);
18107
18108   emit_insn (gen_extenddfxf2 (op1, operands[1]));
18109   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18110
18111   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18112   DONE;
18113 })
18114
18115 (define_expand "nearbyintsf2"
18116   [(use (match_operand:SF 0 "register_operand" ""))
18117    (use (match_operand:SF 1 "register_operand" ""))]
18118   "TARGET_USE_FANCY_MATH_387
18119    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18120    && flag_unsafe_math_optimizations"
18121 {
18122   rtx op0 = gen_reg_rtx (XFmode);
18123   rtx op1 = gen_reg_rtx (XFmode);
18124
18125   emit_insn (gen_extendsfxf2 (op1, operands[1]));
18126   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18127
18128   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18129   DONE;
18130 })
18131
18132 (define_insn "fxam<mode>2_i387"
18133   [(set (match_operand:HI 0 "register_operand" "=a")
18134         (unspec:HI
18135           [(match_operand:X87MODEF 1 "register_operand" "f")]
18136           UNSPEC_FXAM))]
18137   "TARGET_USE_FANCY_MATH_387"
18138   "fxam\n\tfnstsw\t%0"
18139   [(set_attr "type" "multi")
18140    (set_attr "unit" "i387")
18141    (set_attr "mode" "<MODE>")])
18142
18143 (define_expand "isinf<mode>2"
18144   [(use (match_operand:SI 0 "register_operand" ""))
18145    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18146   "TARGET_USE_FANCY_MATH_387
18147    && TARGET_C99_FUNCTIONS
18148    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18149        || TARGET_MIX_SSE_I387)"
18150 {
18151   rtx mask = GEN_INT (0x45);
18152   rtx val = GEN_INT (0x05);
18153
18154   rtx cond;
18155
18156   rtx scratch = gen_reg_rtx (HImode);
18157   rtx res = gen_reg_rtx (QImode);
18158
18159   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18160   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18161   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18162   cond = gen_rtx_fmt_ee (EQ, QImode,
18163                          gen_rtx_REG (CCmode, FLAGS_REG),
18164                          const0_rtx);
18165   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18166   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18167   DONE;
18168 })
18169
18170 \f
18171 ;; Block operation instructions
18172
18173 (define_expand "movmemsi"
18174   [(use (match_operand:BLK 0 "memory_operand" ""))
18175    (use (match_operand:BLK 1 "memory_operand" ""))
18176    (use (match_operand:SI 2 "nonmemory_operand" ""))
18177    (use (match_operand:SI 3 "const_int_operand" ""))
18178    (use (match_operand:SI 4 "const_int_operand" ""))
18179    (use (match_operand:SI 5 "const_int_operand" ""))]
18180   ""
18181 {
18182  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18183                          operands[4], operands[5]))
18184    DONE;
18185  else
18186    FAIL;
18187 })
18188
18189 (define_expand "movmemdi"
18190   [(use (match_operand:BLK 0 "memory_operand" ""))
18191    (use (match_operand:BLK 1 "memory_operand" ""))
18192    (use (match_operand:DI 2 "nonmemory_operand" ""))
18193    (use (match_operand:DI 3 "const_int_operand" ""))
18194    (use (match_operand:SI 4 "const_int_operand" ""))
18195    (use (match_operand:SI 5 "const_int_operand" ""))]
18196   "TARGET_64BIT"
18197 {
18198  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18199                          operands[4], operands[5]))
18200    DONE;
18201  else
18202    FAIL;
18203 })
18204
18205 ;; Most CPUs don't like single string operations
18206 ;; Handle this case here to simplify previous expander.
18207
18208 (define_expand "strmov"
18209   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18210    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18211    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18212               (clobber (reg:CC FLAGS_REG))])
18213    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18214               (clobber (reg:CC FLAGS_REG))])]
18215   ""
18216 {
18217   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18218
18219   /* If .md ever supports :P for Pmode, these can be directly
18220      in the pattern above.  */
18221   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18222   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18223
18224   if (TARGET_SINGLE_STRINGOP || optimize_size)
18225     {
18226       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18227                                       operands[2], operands[3],
18228                                       operands[5], operands[6]));
18229       DONE;
18230     }
18231
18232   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18233 })
18234
18235 (define_expand "strmov_singleop"
18236   [(parallel [(set (match_operand 1 "memory_operand" "")
18237                    (match_operand 3 "memory_operand" ""))
18238               (set (match_operand 0 "register_operand" "")
18239                    (match_operand 4 "" ""))
18240               (set (match_operand 2 "register_operand" "")
18241                    (match_operand 5 "" ""))])]
18242   "TARGET_SINGLE_STRINGOP || optimize_size"
18243   "")
18244
18245 (define_insn "*strmovdi_rex_1"
18246   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18247         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18248    (set (match_operand:DI 0 "register_operand" "=D")
18249         (plus:DI (match_dup 2)
18250                  (const_int 8)))
18251    (set (match_operand:DI 1 "register_operand" "=S")
18252         (plus:DI (match_dup 3)
18253                  (const_int 8)))]
18254   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18255   "movsq"
18256   [(set_attr "type" "str")
18257    (set_attr "mode" "DI")
18258    (set_attr "memory" "both")])
18259
18260 (define_insn "*strmovsi_1"
18261   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18262         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18263    (set (match_operand:SI 0 "register_operand" "=D")
18264         (plus:SI (match_dup 2)
18265                  (const_int 4)))
18266    (set (match_operand:SI 1 "register_operand" "=S")
18267         (plus:SI (match_dup 3)
18268                  (const_int 4)))]
18269   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18270   "{movsl|movsd}"
18271   [(set_attr "type" "str")
18272    (set_attr "mode" "SI")
18273    (set_attr "memory" "both")])
18274
18275 (define_insn "*strmovsi_rex_1"
18276   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18277         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18278    (set (match_operand:DI 0 "register_operand" "=D")
18279         (plus:DI (match_dup 2)
18280                  (const_int 4)))
18281    (set (match_operand:DI 1 "register_operand" "=S")
18282         (plus:DI (match_dup 3)
18283                  (const_int 4)))]
18284   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18285   "{movsl|movsd}"
18286   [(set_attr "type" "str")
18287    (set_attr "mode" "SI")
18288    (set_attr "memory" "both")])
18289
18290 (define_insn "*strmovhi_1"
18291   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18292         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18293    (set (match_operand:SI 0 "register_operand" "=D")
18294         (plus:SI (match_dup 2)
18295                  (const_int 2)))
18296    (set (match_operand:SI 1 "register_operand" "=S")
18297         (plus:SI (match_dup 3)
18298                  (const_int 2)))]
18299   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18300   "movsw"
18301   [(set_attr "type" "str")
18302    (set_attr "memory" "both")
18303    (set_attr "mode" "HI")])
18304
18305 (define_insn "*strmovhi_rex_1"
18306   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18307         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18308    (set (match_operand:DI 0 "register_operand" "=D")
18309         (plus:DI (match_dup 2)
18310                  (const_int 2)))
18311    (set (match_operand:DI 1 "register_operand" "=S")
18312         (plus:DI (match_dup 3)
18313                  (const_int 2)))]
18314   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18315   "movsw"
18316   [(set_attr "type" "str")
18317    (set_attr "memory" "both")
18318    (set_attr "mode" "HI")])
18319
18320 (define_insn "*strmovqi_1"
18321   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18322         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18323    (set (match_operand:SI 0 "register_operand" "=D")
18324         (plus:SI (match_dup 2)
18325                  (const_int 1)))
18326    (set (match_operand:SI 1 "register_operand" "=S")
18327         (plus:SI (match_dup 3)
18328                  (const_int 1)))]
18329   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18330   "movsb"
18331   [(set_attr "type" "str")
18332    (set_attr "memory" "both")
18333    (set_attr "mode" "QI")])
18334
18335 (define_insn "*strmovqi_rex_1"
18336   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18337         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18338    (set (match_operand:DI 0 "register_operand" "=D")
18339         (plus:DI (match_dup 2)
18340                  (const_int 1)))
18341    (set (match_operand:DI 1 "register_operand" "=S")
18342         (plus:DI (match_dup 3)
18343                  (const_int 1)))]
18344   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18345   "movsb"
18346   [(set_attr "type" "str")
18347    (set_attr "memory" "both")
18348    (set_attr "mode" "QI")])
18349
18350 (define_expand "rep_mov"
18351   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18352               (set (match_operand 0 "register_operand" "")
18353                    (match_operand 5 "" ""))
18354               (set (match_operand 2 "register_operand" "")
18355                    (match_operand 6 "" ""))
18356               (set (match_operand 1 "memory_operand" "")
18357                    (match_operand 3 "memory_operand" ""))
18358               (use (match_dup 4))])]
18359   ""
18360   "")
18361
18362 (define_insn "*rep_movdi_rex64"
18363   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18364    (set (match_operand:DI 0 "register_operand" "=D")
18365         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18366                             (const_int 3))
18367                  (match_operand:DI 3 "register_operand" "0")))
18368    (set (match_operand:DI 1 "register_operand" "=S")
18369         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18370                  (match_operand:DI 4 "register_operand" "1")))
18371    (set (mem:BLK (match_dup 3))
18372         (mem:BLK (match_dup 4)))
18373    (use (match_dup 5))]
18374   "TARGET_64BIT"
18375   "{rep\;movsq|rep movsq}"
18376   [(set_attr "type" "str")
18377    (set_attr "prefix_rep" "1")
18378    (set_attr "memory" "both")
18379    (set_attr "mode" "DI")])
18380
18381 (define_insn "*rep_movsi"
18382   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18383    (set (match_operand:SI 0 "register_operand" "=D")
18384         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18385                             (const_int 2))
18386                  (match_operand:SI 3 "register_operand" "0")))
18387    (set (match_operand:SI 1 "register_operand" "=S")
18388         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18389                  (match_operand:SI 4 "register_operand" "1")))
18390    (set (mem:BLK (match_dup 3))
18391         (mem:BLK (match_dup 4)))
18392    (use (match_dup 5))]
18393   "!TARGET_64BIT"
18394   "{rep\;movsl|rep movsd}"
18395   [(set_attr "type" "str")
18396    (set_attr "prefix_rep" "1")
18397    (set_attr "memory" "both")
18398    (set_attr "mode" "SI")])
18399
18400 (define_insn "*rep_movsi_rex64"
18401   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18402    (set (match_operand:DI 0 "register_operand" "=D")
18403         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18404                             (const_int 2))
18405                  (match_operand:DI 3 "register_operand" "0")))
18406    (set (match_operand:DI 1 "register_operand" "=S")
18407         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18408                  (match_operand:DI 4 "register_operand" "1")))
18409    (set (mem:BLK (match_dup 3))
18410         (mem:BLK (match_dup 4)))
18411    (use (match_dup 5))]
18412   "TARGET_64BIT"
18413   "{rep\;movsl|rep movsd}"
18414   [(set_attr "type" "str")
18415    (set_attr "prefix_rep" "1")
18416    (set_attr "memory" "both")
18417    (set_attr "mode" "SI")])
18418
18419 (define_insn "*rep_movqi"
18420   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18421    (set (match_operand:SI 0 "register_operand" "=D")
18422         (plus:SI (match_operand:SI 3 "register_operand" "0")
18423                  (match_operand:SI 5 "register_operand" "2")))
18424    (set (match_operand:SI 1 "register_operand" "=S")
18425         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18426    (set (mem:BLK (match_dup 3))
18427         (mem:BLK (match_dup 4)))
18428    (use (match_dup 5))]
18429   "!TARGET_64BIT"
18430   "{rep\;movsb|rep movsb}"
18431   [(set_attr "type" "str")
18432    (set_attr "prefix_rep" "1")
18433    (set_attr "memory" "both")
18434    (set_attr "mode" "SI")])
18435
18436 (define_insn "*rep_movqi_rex64"
18437   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18438    (set (match_operand:DI 0 "register_operand" "=D")
18439         (plus:DI (match_operand:DI 3 "register_operand" "0")
18440                  (match_operand:DI 5 "register_operand" "2")))
18441    (set (match_operand:DI 1 "register_operand" "=S")
18442         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18443    (set (mem:BLK (match_dup 3))
18444         (mem:BLK (match_dup 4)))
18445    (use (match_dup 5))]
18446   "TARGET_64BIT"
18447   "{rep\;movsb|rep movsb}"
18448   [(set_attr "type" "str")
18449    (set_attr "prefix_rep" "1")
18450    (set_attr "memory" "both")
18451    (set_attr "mode" "SI")])
18452
18453 (define_expand "setmemsi"
18454    [(use (match_operand:BLK 0 "memory_operand" ""))
18455     (use (match_operand:SI 1 "nonmemory_operand" ""))
18456     (use (match_operand 2 "const_int_operand" ""))
18457     (use (match_operand 3 "const_int_operand" ""))
18458     (use (match_operand:SI 4 "const_int_operand" ""))
18459     (use (match_operand:SI 5 "const_int_operand" ""))]
18460   ""
18461 {
18462  if (ix86_expand_setmem (operands[0], operands[1],
18463                          operands[2], operands[3],
18464                          operands[4], operands[5]))
18465    DONE;
18466  else
18467    FAIL;
18468 })
18469
18470 (define_expand "setmemdi"
18471    [(use (match_operand:BLK 0 "memory_operand" ""))
18472     (use (match_operand:DI 1 "nonmemory_operand" ""))
18473     (use (match_operand 2 "const_int_operand" ""))
18474     (use (match_operand 3 "const_int_operand" ""))
18475     (use (match_operand 4 "const_int_operand" ""))
18476     (use (match_operand 5 "const_int_operand" ""))]
18477   "TARGET_64BIT"
18478 {
18479  if (ix86_expand_setmem (operands[0], operands[1],
18480                          operands[2], operands[3],
18481                          operands[4], operands[5]))
18482    DONE;
18483  else
18484    FAIL;
18485 })
18486
18487 ;; Most CPUs don't like single string operations
18488 ;; Handle this case here to simplify previous expander.
18489
18490 (define_expand "strset"
18491   [(set (match_operand 1 "memory_operand" "")
18492         (match_operand 2 "register_operand" ""))
18493    (parallel [(set (match_operand 0 "register_operand" "")
18494                    (match_dup 3))
18495               (clobber (reg:CC FLAGS_REG))])]
18496   ""
18497 {
18498   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18499     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18500
18501   /* If .md ever supports :P for Pmode, this can be directly
18502      in the pattern above.  */
18503   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18504                               GEN_INT (GET_MODE_SIZE (GET_MODE
18505                                                       (operands[2]))));
18506   if (TARGET_SINGLE_STRINGOP || optimize_size)
18507     {
18508       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18509                                       operands[3]));
18510       DONE;
18511     }
18512 })
18513
18514 (define_expand "strset_singleop"
18515   [(parallel [(set (match_operand 1 "memory_operand" "")
18516                    (match_operand 2 "register_operand" ""))
18517               (set (match_operand 0 "register_operand" "")
18518                    (match_operand 3 "" ""))])]
18519   "TARGET_SINGLE_STRINGOP || optimize_size"
18520   "")
18521
18522 (define_insn "*strsetdi_rex_1"
18523   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18524         (match_operand:DI 2 "register_operand" "a"))
18525    (set (match_operand:DI 0 "register_operand" "=D")
18526         (plus:DI (match_dup 1)
18527                  (const_int 8)))]
18528   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18529   "stosq"
18530   [(set_attr "type" "str")
18531    (set_attr "memory" "store")
18532    (set_attr "mode" "DI")])
18533
18534 (define_insn "*strsetsi_1"
18535   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18536         (match_operand:SI 2 "register_operand" "a"))
18537    (set (match_operand:SI 0 "register_operand" "=D")
18538         (plus:SI (match_dup 1)
18539                  (const_int 4)))]
18540   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18541   "{stosl|stosd}"
18542   [(set_attr "type" "str")
18543    (set_attr "memory" "store")
18544    (set_attr "mode" "SI")])
18545
18546 (define_insn "*strsetsi_rex_1"
18547   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18548         (match_operand:SI 2 "register_operand" "a"))
18549    (set (match_operand:DI 0 "register_operand" "=D")
18550         (plus:DI (match_dup 1)
18551                  (const_int 4)))]
18552   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18553   "{stosl|stosd}"
18554   [(set_attr "type" "str")
18555    (set_attr "memory" "store")
18556    (set_attr "mode" "SI")])
18557
18558 (define_insn "*strsethi_1"
18559   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18560         (match_operand:HI 2 "register_operand" "a"))
18561    (set (match_operand:SI 0 "register_operand" "=D")
18562         (plus:SI (match_dup 1)
18563                  (const_int 2)))]
18564   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18565   "stosw"
18566   [(set_attr "type" "str")
18567    (set_attr "memory" "store")
18568    (set_attr "mode" "HI")])
18569
18570 (define_insn "*strsethi_rex_1"
18571   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18572         (match_operand:HI 2 "register_operand" "a"))
18573    (set (match_operand:DI 0 "register_operand" "=D")
18574         (plus:DI (match_dup 1)
18575                  (const_int 2)))]
18576   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18577   "stosw"
18578   [(set_attr "type" "str")
18579    (set_attr "memory" "store")
18580    (set_attr "mode" "HI")])
18581
18582 (define_insn "*strsetqi_1"
18583   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18584         (match_operand:QI 2 "register_operand" "a"))
18585    (set (match_operand:SI 0 "register_operand" "=D")
18586         (plus:SI (match_dup 1)
18587                  (const_int 1)))]
18588   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18589   "stosb"
18590   [(set_attr "type" "str")
18591    (set_attr "memory" "store")
18592    (set_attr "mode" "QI")])
18593
18594 (define_insn "*strsetqi_rex_1"
18595   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18596         (match_operand:QI 2 "register_operand" "a"))
18597    (set (match_operand:DI 0 "register_operand" "=D")
18598         (plus:DI (match_dup 1)
18599                  (const_int 1)))]
18600   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18601   "stosb"
18602   [(set_attr "type" "str")
18603    (set_attr "memory" "store")
18604    (set_attr "mode" "QI")])
18605
18606 (define_expand "rep_stos"
18607   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18608               (set (match_operand 0 "register_operand" "")
18609                    (match_operand 4 "" ""))
18610               (set (match_operand 2 "memory_operand" "") (const_int 0))
18611               (use (match_operand 3 "register_operand" ""))
18612               (use (match_dup 1))])]
18613   ""
18614   "")
18615
18616 (define_insn "*rep_stosdi_rex64"
18617   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18618    (set (match_operand:DI 0 "register_operand" "=D")
18619         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18620                             (const_int 3))
18621                  (match_operand:DI 3 "register_operand" "0")))
18622    (set (mem:BLK (match_dup 3))
18623         (const_int 0))
18624    (use (match_operand:DI 2 "register_operand" "a"))
18625    (use (match_dup 4))]
18626   "TARGET_64BIT"
18627   "{rep\;stosq|rep stosq}"
18628   [(set_attr "type" "str")
18629    (set_attr "prefix_rep" "1")
18630    (set_attr "memory" "store")
18631    (set_attr "mode" "DI")])
18632
18633 (define_insn "*rep_stossi"
18634   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18635    (set (match_operand:SI 0 "register_operand" "=D")
18636         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18637                             (const_int 2))
18638                  (match_operand:SI 3 "register_operand" "0")))
18639    (set (mem:BLK (match_dup 3))
18640         (const_int 0))
18641    (use (match_operand:SI 2 "register_operand" "a"))
18642    (use (match_dup 4))]
18643   "!TARGET_64BIT"
18644   "{rep\;stosl|rep stosd}"
18645   [(set_attr "type" "str")
18646    (set_attr "prefix_rep" "1")
18647    (set_attr "memory" "store")
18648    (set_attr "mode" "SI")])
18649
18650 (define_insn "*rep_stossi_rex64"
18651   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18652    (set (match_operand:DI 0 "register_operand" "=D")
18653         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18654                             (const_int 2))
18655                  (match_operand:DI 3 "register_operand" "0")))
18656    (set (mem:BLK (match_dup 3))
18657         (const_int 0))
18658    (use (match_operand:SI 2 "register_operand" "a"))
18659    (use (match_dup 4))]
18660   "TARGET_64BIT"
18661   "{rep\;stosl|rep stosd}"
18662   [(set_attr "type" "str")
18663    (set_attr "prefix_rep" "1")
18664    (set_attr "memory" "store")
18665    (set_attr "mode" "SI")])
18666
18667 (define_insn "*rep_stosqi"
18668   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18669    (set (match_operand:SI 0 "register_operand" "=D")
18670         (plus:SI (match_operand:SI 3 "register_operand" "0")
18671                  (match_operand:SI 4 "register_operand" "1")))
18672    (set (mem:BLK (match_dup 3))
18673         (const_int 0))
18674    (use (match_operand:QI 2 "register_operand" "a"))
18675    (use (match_dup 4))]
18676   "!TARGET_64BIT"
18677   "{rep\;stosb|rep stosb}"
18678   [(set_attr "type" "str")
18679    (set_attr "prefix_rep" "1")
18680    (set_attr "memory" "store")
18681    (set_attr "mode" "QI")])
18682
18683 (define_insn "*rep_stosqi_rex64"
18684   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18685    (set (match_operand:DI 0 "register_operand" "=D")
18686         (plus:DI (match_operand:DI 3 "register_operand" "0")
18687                  (match_operand:DI 4 "register_operand" "1")))
18688    (set (mem:BLK (match_dup 3))
18689         (const_int 0))
18690    (use (match_operand:QI 2 "register_operand" "a"))
18691    (use (match_dup 4))]
18692   "TARGET_64BIT"
18693   "{rep\;stosb|rep stosb}"
18694   [(set_attr "type" "str")
18695    (set_attr "prefix_rep" "1")
18696    (set_attr "memory" "store")
18697    (set_attr "mode" "QI")])
18698
18699 (define_expand "cmpstrnsi"
18700   [(set (match_operand:SI 0 "register_operand" "")
18701         (compare:SI (match_operand:BLK 1 "general_operand" "")
18702                     (match_operand:BLK 2 "general_operand" "")))
18703    (use (match_operand 3 "general_operand" ""))
18704    (use (match_operand 4 "immediate_operand" ""))]
18705   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18706 {
18707   rtx addr1, addr2, out, outlow, count, countreg, align;
18708
18709   /* Can't use this if the user has appropriated esi or edi.  */
18710   if (global_regs[4] || global_regs[5])
18711     FAIL;
18712
18713   out = operands[0];
18714   if (!REG_P (out))
18715     out = gen_reg_rtx (SImode);
18716
18717   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18718   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18719   if (addr1 != XEXP (operands[1], 0))
18720     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18721   if (addr2 != XEXP (operands[2], 0))
18722     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18723
18724   count = operands[3];
18725   countreg = ix86_zero_extend_to_Pmode (count);
18726
18727   /* %%% Iff we are testing strict equality, we can use known alignment
18728      to good advantage.  This may be possible with combine, particularly
18729      once cc0 is dead.  */
18730   align = operands[4];
18731
18732   if (CONST_INT_P (count))
18733     {
18734       if (INTVAL (count) == 0)
18735         {
18736           emit_move_insn (operands[0], const0_rtx);
18737           DONE;
18738         }
18739       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18740                                      operands[1], operands[2]));
18741     }
18742   else
18743     {
18744       if (TARGET_64BIT)
18745         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18746       else
18747         emit_insn (gen_cmpsi_1 (countreg, countreg));
18748       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18749                                   operands[1], operands[2]));
18750     }
18751
18752   outlow = gen_lowpart (QImode, out);
18753   emit_insn (gen_cmpintqi (outlow));
18754   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18755
18756   if (operands[0] != out)
18757     emit_move_insn (operands[0], out);
18758
18759   DONE;
18760 })
18761
18762 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18763
18764 (define_expand "cmpintqi"
18765   [(set (match_dup 1)
18766         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18767    (set (match_dup 2)
18768         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18769    (parallel [(set (match_operand:QI 0 "register_operand" "")
18770                    (minus:QI (match_dup 1)
18771                              (match_dup 2)))
18772               (clobber (reg:CC FLAGS_REG))])]
18773   ""
18774   "operands[1] = gen_reg_rtx (QImode);
18775    operands[2] = gen_reg_rtx (QImode);")
18776
18777 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18778 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18779
18780 (define_expand "cmpstrnqi_nz_1"
18781   [(parallel [(set (reg:CC FLAGS_REG)
18782                    (compare:CC (match_operand 4 "memory_operand" "")
18783                                (match_operand 5 "memory_operand" "")))
18784               (use (match_operand 2 "register_operand" ""))
18785               (use (match_operand:SI 3 "immediate_operand" ""))
18786               (clobber (match_operand 0 "register_operand" ""))
18787               (clobber (match_operand 1 "register_operand" ""))
18788               (clobber (match_dup 2))])]
18789   ""
18790   "")
18791
18792 (define_insn "*cmpstrnqi_nz_1"
18793   [(set (reg:CC FLAGS_REG)
18794         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18795                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18796    (use (match_operand:SI 6 "register_operand" "2"))
18797    (use (match_operand:SI 3 "immediate_operand" "i"))
18798    (clobber (match_operand:SI 0 "register_operand" "=S"))
18799    (clobber (match_operand:SI 1 "register_operand" "=D"))
18800    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18801   "!TARGET_64BIT"
18802   "repz{\;| }cmpsb"
18803   [(set_attr "type" "str")
18804    (set_attr "mode" "QI")
18805    (set_attr "prefix_rep" "1")])
18806
18807 (define_insn "*cmpstrnqi_nz_rex_1"
18808   [(set (reg:CC FLAGS_REG)
18809         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18810                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18811    (use (match_operand:DI 6 "register_operand" "2"))
18812    (use (match_operand:SI 3 "immediate_operand" "i"))
18813    (clobber (match_operand:DI 0 "register_operand" "=S"))
18814    (clobber (match_operand:DI 1 "register_operand" "=D"))
18815    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18816   "TARGET_64BIT"
18817   "repz{\;| }cmpsb"
18818   [(set_attr "type" "str")
18819    (set_attr "mode" "QI")
18820    (set_attr "prefix_rep" "1")])
18821
18822 ;; The same, but the count is not known to not be zero.
18823
18824 (define_expand "cmpstrnqi_1"
18825   [(parallel [(set (reg:CC FLAGS_REG)
18826                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18827                                      (const_int 0))
18828                   (compare:CC (match_operand 4 "memory_operand" "")
18829                               (match_operand 5 "memory_operand" ""))
18830                   (const_int 0)))
18831               (use (match_operand:SI 3 "immediate_operand" ""))
18832               (use (reg:CC FLAGS_REG))
18833               (clobber (match_operand 0 "register_operand" ""))
18834               (clobber (match_operand 1 "register_operand" ""))
18835               (clobber (match_dup 2))])]
18836   ""
18837   "")
18838
18839 (define_insn "*cmpstrnqi_1"
18840   [(set (reg:CC FLAGS_REG)
18841         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18842                              (const_int 0))
18843           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18844                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18845           (const_int 0)))
18846    (use (match_operand:SI 3 "immediate_operand" "i"))
18847    (use (reg:CC FLAGS_REG))
18848    (clobber (match_operand:SI 0 "register_operand" "=S"))
18849    (clobber (match_operand:SI 1 "register_operand" "=D"))
18850    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18851   "!TARGET_64BIT"
18852   "repz{\;| }cmpsb"
18853   [(set_attr "type" "str")
18854    (set_attr "mode" "QI")
18855    (set_attr "prefix_rep" "1")])
18856
18857 (define_insn "*cmpstrnqi_rex_1"
18858   [(set (reg:CC FLAGS_REG)
18859         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18860                              (const_int 0))
18861           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18862                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18863           (const_int 0)))
18864    (use (match_operand:SI 3 "immediate_operand" "i"))
18865    (use (reg:CC FLAGS_REG))
18866    (clobber (match_operand:DI 0 "register_operand" "=S"))
18867    (clobber (match_operand:DI 1 "register_operand" "=D"))
18868    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18869   "TARGET_64BIT"
18870   "repz{\;| }cmpsb"
18871   [(set_attr "type" "str")
18872    (set_attr "mode" "QI")
18873    (set_attr "prefix_rep" "1")])
18874
18875 (define_expand "strlensi"
18876   [(set (match_operand:SI 0 "register_operand" "")
18877         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18878                     (match_operand:QI 2 "immediate_operand" "")
18879                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18880   ""
18881 {
18882  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18883    DONE;
18884  else
18885    FAIL;
18886 })
18887
18888 (define_expand "strlendi"
18889   [(set (match_operand:DI 0 "register_operand" "")
18890         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18891                     (match_operand:QI 2 "immediate_operand" "")
18892                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18893   ""
18894 {
18895  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18896    DONE;
18897  else
18898    FAIL;
18899 })
18900
18901 (define_expand "strlenqi_1"
18902   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18903               (clobber (match_operand 1 "register_operand" ""))
18904               (clobber (reg:CC FLAGS_REG))])]
18905   ""
18906   "")
18907
18908 (define_insn "*strlenqi_1"
18909   [(set (match_operand:SI 0 "register_operand" "=&c")
18910         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18911                     (match_operand:QI 2 "register_operand" "a")
18912                     (match_operand:SI 3 "immediate_operand" "i")
18913                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18914    (clobber (match_operand:SI 1 "register_operand" "=D"))
18915    (clobber (reg:CC FLAGS_REG))]
18916   "!TARGET_64BIT"
18917   "repnz{\;| }scasb"
18918   [(set_attr "type" "str")
18919    (set_attr "mode" "QI")
18920    (set_attr "prefix_rep" "1")])
18921
18922 (define_insn "*strlenqi_rex_1"
18923   [(set (match_operand:DI 0 "register_operand" "=&c")
18924         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18925                     (match_operand:QI 2 "register_operand" "a")
18926                     (match_operand:DI 3 "immediate_operand" "i")
18927                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18928    (clobber (match_operand:DI 1 "register_operand" "=D"))
18929    (clobber (reg:CC FLAGS_REG))]
18930   "TARGET_64BIT"
18931   "repnz{\;| }scasb"
18932   [(set_attr "type" "str")
18933    (set_attr "mode" "QI")
18934    (set_attr "prefix_rep" "1")])
18935
18936 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18937 ;; handled in combine, but it is not currently up to the task.
18938 ;; When used for their truth value, the cmpstrn* expanders generate
18939 ;; code like this:
18940 ;;
18941 ;;   repz cmpsb
18942 ;;   seta       %al
18943 ;;   setb       %dl
18944 ;;   cmpb       %al, %dl
18945 ;;   jcc        label
18946 ;;
18947 ;; The intermediate three instructions are unnecessary.
18948
18949 ;; This one handles cmpstrn*_nz_1...
18950 (define_peephole2
18951   [(parallel[
18952      (set (reg:CC FLAGS_REG)
18953           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18954                       (mem:BLK (match_operand 5 "register_operand" ""))))
18955      (use (match_operand 6 "register_operand" ""))
18956      (use (match_operand:SI 3 "immediate_operand" ""))
18957      (clobber (match_operand 0 "register_operand" ""))
18958      (clobber (match_operand 1 "register_operand" ""))
18959      (clobber (match_operand 2 "register_operand" ""))])
18960    (set (match_operand:QI 7 "register_operand" "")
18961         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18962    (set (match_operand:QI 8 "register_operand" "")
18963         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18964    (set (reg FLAGS_REG)
18965         (compare (match_dup 7) (match_dup 8)))
18966   ]
18967   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18968   [(parallel[
18969      (set (reg:CC FLAGS_REG)
18970           (compare:CC (mem:BLK (match_dup 4))
18971                       (mem:BLK (match_dup 5))))
18972      (use (match_dup 6))
18973      (use (match_dup 3))
18974      (clobber (match_dup 0))
18975      (clobber (match_dup 1))
18976      (clobber (match_dup 2))])]
18977   "")
18978
18979 ;; ...and this one handles cmpstrn*_1.
18980 (define_peephole2
18981   [(parallel[
18982      (set (reg:CC FLAGS_REG)
18983           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18984                                (const_int 0))
18985             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18986                         (mem:BLK (match_operand 5 "register_operand" "")))
18987             (const_int 0)))
18988      (use (match_operand:SI 3 "immediate_operand" ""))
18989      (use (reg:CC FLAGS_REG))
18990      (clobber (match_operand 0 "register_operand" ""))
18991      (clobber (match_operand 1 "register_operand" ""))
18992      (clobber (match_operand 2 "register_operand" ""))])
18993    (set (match_operand:QI 7 "register_operand" "")
18994         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18995    (set (match_operand:QI 8 "register_operand" "")
18996         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18997    (set (reg FLAGS_REG)
18998         (compare (match_dup 7) (match_dup 8)))
18999   ]
19000   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19001   [(parallel[
19002      (set (reg:CC FLAGS_REG)
19003           (if_then_else:CC (ne (match_dup 6)
19004                                (const_int 0))
19005             (compare:CC (mem:BLK (match_dup 4))
19006                         (mem:BLK (match_dup 5)))
19007             (const_int 0)))
19008      (use (match_dup 3))
19009      (use (reg:CC FLAGS_REG))
19010      (clobber (match_dup 0))
19011      (clobber (match_dup 1))
19012      (clobber (match_dup 2))])]
19013   "")
19014
19015
19016 \f
19017 ;; Conditional move instructions.
19018
19019 (define_expand "movdicc"
19020   [(set (match_operand:DI 0 "register_operand" "")
19021         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19022                          (match_operand:DI 2 "general_operand" "")
19023                          (match_operand:DI 3 "general_operand" "")))]
19024   "TARGET_64BIT"
19025   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19026
19027 (define_insn "x86_movdicc_0_m1_rex64"
19028   [(set (match_operand:DI 0 "register_operand" "=r")
19029         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19030           (const_int -1)
19031           (const_int 0)))
19032    (clobber (reg:CC FLAGS_REG))]
19033   "TARGET_64BIT"
19034   "sbb{q}\t%0, %0"
19035   ; Since we don't have the proper number of operands for an alu insn,
19036   ; fill in all the blanks.
19037   [(set_attr "type" "alu")
19038    (set_attr "pent_pair" "pu")
19039    (set_attr "memory" "none")
19040    (set_attr "imm_disp" "false")
19041    (set_attr "mode" "DI")
19042    (set_attr "length_immediate" "0")])
19043
19044 (define_insn "*movdicc_c_rex64"
19045   [(set (match_operand:DI 0 "register_operand" "=r,r")
19046         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19047                                 [(reg FLAGS_REG) (const_int 0)])
19048                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19049                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19050   "TARGET_64BIT && TARGET_CMOVE
19051    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19052   "@
19053    cmov%O2%C1\t{%2, %0|%0, %2}
19054    cmov%O2%c1\t{%3, %0|%0, %3}"
19055   [(set_attr "type" "icmov")
19056    (set_attr "mode" "DI")])
19057
19058 (define_expand "movsicc"
19059   [(set (match_operand:SI 0 "register_operand" "")
19060         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19061                          (match_operand:SI 2 "general_operand" "")
19062                          (match_operand:SI 3 "general_operand" "")))]
19063   ""
19064   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19065
19066 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19067 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19068 ;; So just document what we're doing explicitly.
19069
19070 (define_insn "x86_movsicc_0_m1"
19071   [(set (match_operand:SI 0 "register_operand" "=r")
19072         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19073           (const_int -1)
19074           (const_int 0)))
19075    (clobber (reg:CC FLAGS_REG))]
19076   ""
19077   "sbb{l}\t%0, %0"
19078   ; Since we don't have the proper number of operands for an alu insn,
19079   ; fill in all the blanks.
19080   [(set_attr "type" "alu")
19081    (set_attr "pent_pair" "pu")
19082    (set_attr "memory" "none")
19083    (set_attr "imm_disp" "false")
19084    (set_attr "mode" "SI")
19085    (set_attr "length_immediate" "0")])
19086
19087 (define_insn "*movsicc_noc"
19088   [(set (match_operand:SI 0 "register_operand" "=r,r")
19089         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19090                                 [(reg FLAGS_REG) (const_int 0)])
19091                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19092                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19093   "TARGET_CMOVE
19094    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19095   "@
19096    cmov%O2%C1\t{%2, %0|%0, %2}
19097    cmov%O2%c1\t{%3, %0|%0, %3}"
19098   [(set_attr "type" "icmov")
19099    (set_attr "mode" "SI")])
19100
19101 (define_expand "movhicc"
19102   [(set (match_operand:HI 0 "register_operand" "")
19103         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19104                          (match_operand:HI 2 "general_operand" "")
19105                          (match_operand:HI 3 "general_operand" "")))]
19106   "TARGET_HIMODE_MATH"
19107   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19108
19109 (define_insn "*movhicc_noc"
19110   [(set (match_operand:HI 0 "register_operand" "=r,r")
19111         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19112                                 [(reg FLAGS_REG) (const_int 0)])
19113                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19114                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19115   "TARGET_CMOVE
19116    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19117   "@
19118    cmov%O2%C1\t{%2, %0|%0, %2}
19119    cmov%O2%c1\t{%3, %0|%0, %3}"
19120   [(set_attr "type" "icmov")
19121    (set_attr "mode" "HI")])
19122
19123 (define_expand "movqicc"
19124   [(set (match_operand:QI 0 "register_operand" "")
19125         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19126                          (match_operand:QI 2 "general_operand" "")
19127                          (match_operand:QI 3 "general_operand" "")))]
19128   "TARGET_QIMODE_MATH"
19129   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19130
19131 (define_insn_and_split "*movqicc_noc"
19132   [(set (match_operand:QI 0 "register_operand" "=r,r")
19133         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19134                                 [(match_operand 4 "flags_reg_operand" "")
19135                                  (const_int 0)])
19136                       (match_operand:QI 2 "register_operand" "r,0")
19137                       (match_operand:QI 3 "register_operand" "0,r")))]
19138   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19139   "#"
19140   "&& reload_completed"
19141   [(set (match_dup 0)
19142         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19143                       (match_dup 2)
19144                       (match_dup 3)))]
19145   "operands[0] = gen_lowpart (SImode, operands[0]);
19146    operands[2] = gen_lowpart (SImode, operands[2]);
19147    operands[3] = gen_lowpart (SImode, operands[3]);"
19148   [(set_attr "type" "icmov")
19149    (set_attr "mode" "SI")])
19150
19151 (define_expand "movsfcc"
19152   [(set (match_operand:SF 0 "register_operand" "")
19153         (if_then_else:SF (match_operand 1 "comparison_operator" "")
19154                          (match_operand:SF 2 "register_operand" "")
19155                          (match_operand:SF 3 "register_operand" "")))]
19156   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19157   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19158
19159 (define_insn "*movsfcc_1_387"
19160   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19161         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19162                                 [(reg FLAGS_REG) (const_int 0)])
19163                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19164                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19165   "TARGET_80387 && TARGET_CMOVE
19166    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19167   "@
19168    fcmov%F1\t{%2, %0|%0, %2}
19169    fcmov%f1\t{%3, %0|%0, %3}
19170    cmov%O2%C1\t{%2, %0|%0, %2}
19171    cmov%O2%c1\t{%3, %0|%0, %3}"
19172   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19173    (set_attr "mode" "SF,SF,SI,SI")])
19174
19175 (define_expand "movdfcc"
19176   [(set (match_operand:DF 0 "register_operand" "")
19177         (if_then_else:DF (match_operand 1 "comparison_operator" "")
19178                          (match_operand:DF 2 "register_operand" "")
19179                          (match_operand:DF 3 "register_operand" "")))]
19180   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19181   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19182
19183 (define_insn "*movdfcc_1"
19184   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19185         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19186                                 [(reg FLAGS_REG) (const_int 0)])
19187                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19188                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19189   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19190    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19191   "@
19192    fcmov%F1\t{%2, %0|%0, %2}
19193    fcmov%f1\t{%3, %0|%0, %3}
19194    #
19195    #"
19196   [(set_attr "type" "fcmov,fcmov,multi,multi")
19197    (set_attr "mode" "DF")])
19198
19199 (define_insn "*movdfcc_1_rex64"
19200   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19201         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19202                                 [(reg FLAGS_REG) (const_int 0)])
19203                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19204                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19205   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19206    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19207   "@
19208    fcmov%F1\t{%2, %0|%0, %2}
19209    fcmov%f1\t{%3, %0|%0, %3}
19210    cmov%O2%C1\t{%2, %0|%0, %2}
19211    cmov%O2%c1\t{%3, %0|%0, %3}"
19212   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19213    (set_attr "mode" "DF")])
19214
19215 (define_split
19216   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19217         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19218                                 [(match_operand 4 "flags_reg_operand" "")
19219                                  (const_int 0)])
19220                       (match_operand:DF 2 "nonimmediate_operand" "")
19221                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19222   "!TARGET_64BIT && reload_completed"
19223   [(set (match_dup 2)
19224         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19225                       (match_dup 5)
19226                       (match_dup 7)))
19227    (set (match_dup 3)
19228         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19229                       (match_dup 6)
19230                       (match_dup 8)))]
19231   "split_di (operands+2, 1, operands+5, operands+6);
19232    split_di (operands+3, 1, operands+7, operands+8);
19233    split_di (operands, 1, operands+2, operands+3);")
19234
19235 (define_expand "movxfcc"
19236   [(set (match_operand:XF 0 "register_operand" "")
19237         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19238                          (match_operand:XF 2 "register_operand" "")
19239                          (match_operand:XF 3 "register_operand" "")))]
19240   "TARGET_80387 && TARGET_CMOVE"
19241   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19242
19243 (define_insn "*movxfcc_1"
19244   [(set (match_operand:XF 0 "register_operand" "=f,f")
19245         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19246                                 [(reg FLAGS_REG) (const_int 0)])
19247                       (match_operand:XF 2 "register_operand" "f,0")
19248                       (match_operand:XF 3 "register_operand" "0,f")))]
19249   "TARGET_80387 && TARGET_CMOVE"
19250   "@
19251    fcmov%F1\t{%2, %0|%0, %2}
19252    fcmov%f1\t{%3, %0|%0, %3}"
19253   [(set_attr "type" "fcmov")
19254    (set_attr "mode" "XF")])
19255
19256 ;; These versions of the min/max patterns are intentionally ignorant of
19257 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19258 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19259 ;; are undefined in this condition, we're certain this is correct.
19260
19261 (define_insn "sminsf3"
19262   [(set (match_operand:SF 0 "register_operand" "=x")
19263         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19264                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19265   "TARGET_SSE_MATH"
19266   "minss\t{%2, %0|%0, %2}"
19267   [(set_attr "type" "sseadd")
19268    (set_attr "mode" "SF")])
19269
19270 (define_insn "smaxsf3"
19271   [(set (match_operand:SF 0 "register_operand" "=x")
19272         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19273                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19274   "TARGET_SSE_MATH"
19275   "maxss\t{%2, %0|%0, %2}"
19276   [(set_attr "type" "sseadd")
19277    (set_attr "mode" "SF")])
19278
19279 (define_insn "smindf3"
19280   [(set (match_operand:DF 0 "register_operand" "=x")
19281         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19282                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19283   "TARGET_SSE2 && TARGET_SSE_MATH"
19284   "minsd\t{%2, %0|%0, %2}"
19285   [(set_attr "type" "sseadd")
19286    (set_attr "mode" "DF")])
19287
19288 (define_insn "smaxdf3"
19289   [(set (match_operand:DF 0 "register_operand" "=x")
19290         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19291                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19292   "TARGET_SSE2 && TARGET_SSE_MATH"
19293   "maxsd\t{%2, %0|%0, %2}"
19294   [(set_attr "type" "sseadd")
19295    (set_attr "mode" "DF")])
19296
19297 ;; These versions of the min/max patterns implement exactly the operations
19298 ;;   min = (op1 < op2 ? op1 : op2)
19299 ;;   max = (!(op1 < op2) ? op1 : op2)
19300 ;; Their operands are not commutative, and thus they may be used in the
19301 ;; presence of -0.0 and NaN.
19302
19303 (define_insn "*ieee_sminsf3"
19304   [(set (match_operand:SF 0 "register_operand" "=x")
19305         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19306                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19307                    UNSPEC_IEEE_MIN))]
19308   "TARGET_SSE_MATH"
19309   "minss\t{%2, %0|%0, %2}"
19310   [(set_attr "type" "sseadd")
19311    (set_attr "mode" "SF")])
19312
19313 (define_insn "*ieee_smaxsf3"
19314   [(set (match_operand:SF 0 "register_operand" "=x")
19315         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19316                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19317                    UNSPEC_IEEE_MAX))]
19318   "TARGET_SSE_MATH"
19319   "maxss\t{%2, %0|%0, %2}"
19320   [(set_attr "type" "sseadd")
19321    (set_attr "mode" "SF")])
19322
19323 (define_insn "*ieee_smindf3"
19324   [(set (match_operand:DF 0 "register_operand" "=x")
19325         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19326                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19327                    UNSPEC_IEEE_MIN))]
19328   "TARGET_SSE2 && TARGET_SSE_MATH"
19329   "minsd\t{%2, %0|%0, %2}"
19330   [(set_attr "type" "sseadd")
19331    (set_attr "mode" "DF")])
19332
19333 (define_insn "*ieee_smaxdf3"
19334   [(set (match_operand:DF 0 "register_operand" "=x")
19335         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19336                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19337                    UNSPEC_IEEE_MAX))]
19338   "TARGET_SSE2 && TARGET_SSE_MATH"
19339   "maxsd\t{%2, %0|%0, %2}"
19340   [(set_attr "type" "sseadd")
19341    (set_attr "mode" "DF")])
19342
19343 ;; Make two stack loads independent:
19344 ;;   fld aa              fld aa
19345 ;;   fld %st(0)     ->   fld bb
19346 ;;   fmul bb             fmul %st(1), %st
19347 ;;
19348 ;; Actually we only match the last two instructions for simplicity.
19349 (define_peephole2
19350   [(set (match_operand 0 "fp_register_operand" "")
19351         (match_operand 1 "fp_register_operand" ""))
19352    (set (match_dup 0)
19353         (match_operator 2 "binary_fp_operator"
19354            [(match_dup 0)
19355             (match_operand 3 "memory_operand" "")]))]
19356   "REGNO (operands[0]) != REGNO (operands[1])"
19357   [(set (match_dup 0) (match_dup 3))
19358    (set (match_dup 0) (match_dup 4))]
19359
19360   ;; The % modifier is not operational anymore in peephole2's, so we have to
19361   ;; swap the operands manually in the case of addition and multiplication.
19362   "if (COMMUTATIVE_ARITH_P (operands[2]))
19363      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19364                                  operands[0], operands[1]);
19365    else
19366      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19367                                  operands[1], operands[0]);")
19368
19369 ;; Conditional addition patterns
19370 (define_expand "addqicc"
19371   [(match_operand:QI 0 "register_operand" "")
19372    (match_operand 1 "comparison_operator" "")
19373    (match_operand:QI 2 "register_operand" "")
19374    (match_operand:QI 3 "const_int_operand" "")]
19375   ""
19376   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19377
19378 (define_expand "addhicc"
19379   [(match_operand:HI 0 "register_operand" "")
19380    (match_operand 1 "comparison_operator" "")
19381    (match_operand:HI 2 "register_operand" "")
19382    (match_operand:HI 3 "const_int_operand" "")]
19383   ""
19384   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19385
19386 (define_expand "addsicc"
19387   [(match_operand:SI 0 "register_operand" "")
19388    (match_operand 1 "comparison_operator" "")
19389    (match_operand:SI 2 "register_operand" "")
19390    (match_operand:SI 3 "const_int_operand" "")]
19391   ""
19392   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19393
19394 (define_expand "adddicc"
19395   [(match_operand:DI 0 "register_operand" "")
19396    (match_operand 1 "comparison_operator" "")
19397    (match_operand:DI 2 "register_operand" "")
19398    (match_operand:DI 3 "const_int_operand" "")]
19399   "TARGET_64BIT"
19400   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19401
19402 \f
19403 ;; Misc patterns (?)
19404
19405 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19406 ;; Otherwise there will be nothing to keep
19407 ;;
19408 ;; [(set (reg ebp) (reg esp))]
19409 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19410 ;;  (clobber (eflags)]
19411 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19412 ;;
19413 ;; in proper program order.
19414 (define_insn "pro_epilogue_adjust_stack_1"
19415   [(set (match_operand:SI 0 "register_operand" "=r,r")
19416         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19417                  (match_operand:SI 2 "immediate_operand" "i,i")))
19418    (clobber (reg:CC FLAGS_REG))
19419    (clobber (mem:BLK (scratch)))]
19420   "!TARGET_64BIT"
19421 {
19422   switch (get_attr_type (insn))
19423     {
19424     case TYPE_IMOV:
19425       return "mov{l}\t{%1, %0|%0, %1}";
19426
19427     case TYPE_ALU:
19428       if (CONST_INT_P (operands[2])
19429           && (INTVAL (operands[2]) == 128
19430               || (INTVAL (operands[2]) < 0
19431                   && INTVAL (operands[2]) != -128)))
19432         {
19433           operands[2] = GEN_INT (-INTVAL (operands[2]));
19434           return "sub{l}\t{%2, %0|%0, %2}";
19435         }
19436       return "add{l}\t{%2, %0|%0, %2}";
19437
19438     case TYPE_LEA:
19439       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19440       return "lea{l}\t{%a2, %0|%0, %a2}";
19441
19442     default:
19443       gcc_unreachable ();
19444     }
19445 }
19446   [(set (attr "type")
19447         (cond [(eq_attr "alternative" "0")
19448                  (const_string "alu")
19449                (match_operand:SI 2 "const0_operand" "")
19450                  (const_string "imov")
19451               ]
19452               (const_string "lea")))
19453    (set_attr "mode" "SI")])
19454
19455 (define_insn "pro_epilogue_adjust_stack_rex64"
19456   [(set (match_operand:DI 0 "register_operand" "=r,r")
19457         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19458                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19459    (clobber (reg:CC FLAGS_REG))
19460    (clobber (mem:BLK (scratch)))]
19461   "TARGET_64BIT"
19462 {
19463   switch (get_attr_type (insn))
19464     {
19465     case TYPE_IMOV:
19466       return "mov{q}\t{%1, %0|%0, %1}";
19467
19468     case TYPE_ALU:
19469       if (CONST_INT_P (operands[2])
19470           /* Avoid overflows.  */
19471           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19472           && (INTVAL (operands[2]) == 128
19473               || (INTVAL (operands[2]) < 0
19474                   && INTVAL (operands[2]) != -128)))
19475         {
19476           operands[2] = GEN_INT (-INTVAL (operands[2]));
19477           return "sub{q}\t{%2, %0|%0, %2}";
19478         }
19479       return "add{q}\t{%2, %0|%0, %2}";
19480
19481     case TYPE_LEA:
19482       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19483       return "lea{q}\t{%a2, %0|%0, %a2}";
19484
19485     default:
19486       gcc_unreachable ();
19487     }
19488 }
19489   [(set (attr "type")
19490         (cond [(eq_attr "alternative" "0")
19491                  (const_string "alu")
19492                (match_operand:DI 2 "const0_operand" "")
19493                  (const_string "imov")
19494               ]
19495               (const_string "lea")))
19496    (set_attr "mode" "DI")])
19497
19498 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19499   [(set (match_operand:DI 0 "register_operand" "=r,r")
19500         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19501                  (match_operand:DI 3 "immediate_operand" "i,i")))
19502    (use (match_operand:DI 2 "register_operand" "r,r"))
19503    (clobber (reg:CC FLAGS_REG))
19504    (clobber (mem:BLK (scratch)))]
19505   "TARGET_64BIT"
19506 {
19507   switch (get_attr_type (insn))
19508     {
19509     case TYPE_ALU:
19510       return "add{q}\t{%2, %0|%0, %2}";
19511
19512     case TYPE_LEA:
19513       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19514       return "lea{q}\t{%a2, %0|%0, %a2}";
19515
19516     default:
19517       gcc_unreachable ();
19518     }
19519 }
19520   [(set_attr "type" "alu,lea")
19521    (set_attr "mode" "DI")])
19522
19523 (define_insn "allocate_stack_worker_32"
19524   [(set (match_operand:SI 0 "register_operand" "+a")
19525         (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19526    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19527    (clobber (reg:CC FLAGS_REG))]
19528   "!TARGET_64BIT && TARGET_STACK_PROBE"
19529   "call\t__alloca"
19530   [(set_attr "type" "multi")
19531    (set_attr "length" "5")])
19532
19533 (define_insn "allocate_stack_worker_64"
19534   [(set (match_operand:DI 0 "register_operand" "=a")
19535         (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19536    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19537    (clobber (reg:DI R10_REG))
19538    (clobber (reg:DI R11_REG))
19539    (clobber (reg:CC FLAGS_REG))]
19540   "TARGET_64BIT && TARGET_STACK_PROBE"
19541   "call\t___chkstk"
19542   [(set_attr "type" "multi")
19543    (set_attr "length" "5")])
19544
19545 (define_expand "allocate_stack"
19546   [(match_operand 0 "register_operand" "")
19547    (match_operand 1 "general_operand" "")]
19548   "TARGET_STACK_PROBE"
19549 {
19550   rtx x;
19551
19552 #ifndef CHECK_STACK_LIMIT
19553 #define CHECK_STACK_LIMIT 0
19554 #endif
19555
19556   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19557       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19558     {
19559       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19560                                stack_pointer_rtx, 0, OPTAB_DIRECT);
19561       if (x != stack_pointer_rtx)
19562         emit_move_insn (stack_pointer_rtx, x);
19563     }
19564   else
19565     {
19566       x = copy_to_mode_reg (Pmode, operands[1]);
19567       if (TARGET_64BIT)
19568         x = gen_allocate_stack_worker_64 (x);
19569       else
19570         x = gen_allocate_stack_worker_32 (x);
19571       emit_insn (x);
19572     }
19573
19574   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19575   DONE;
19576 })
19577
19578 (define_expand "builtin_setjmp_receiver"
19579   [(label_ref (match_operand 0 "" ""))]
19580   "!TARGET_64BIT && flag_pic"
19581 {
19582   if (TARGET_MACHO)
19583     {
19584       rtx xops[3];
19585       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19586       rtx label_rtx = gen_label_rtx ();
19587       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19588       xops[0] = xops[1] = picreg;
19589       xops[2] = gen_rtx_CONST (SImode,
19590                   gen_rtx_MINUS (SImode,
19591                     gen_rtx_LABEL_REF (SImode, label_rtx),
19592                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19593       ix86_expand_binary_operator (MINUS, SImode, xops);
19594     }
19595   else
19596     emit_insn (gen_set_got (pic_offset_table_rtx));
19597   DONE;
19598 })
19599 \f
19600 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19601
19602 (define_split
19603   [(set (match_operand 0 "register_operand" "")
19604         (match_operator 3 "promotable_binary_operator"
19605            [(match_operand 1 "register_operand" "")
19606             (match_operand 2 "aligned_operand" "")]))
19607    (clobber (reg:CC FLAGS_REG))]
19608   "! TARGET_PARTIAL_REG_STALL && reload_completed
19609    && ((GET_MODE (operands[0]) == HImode
19610         && ((!optimize_size && !TARGET_FAST_PREFIX)
19611             /* ??? next two lines just !satisfies_constraint_K (...) */
19612             || !CONST_INT_P (operands[2])
19613             || satisfies_constraint_K (operands[2])))
19614        || (GET_MODE (operands[0]) == QImode
19615            && (TARGET_PROMOTE_QImode || optimize_size)))"
19616   [(parallel [(set (match_dup 0)
19617                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19618               (clobber (reg:CC FLAGS_REG))])]
19619   "operands[0] = gen_lowpart (SImode, operands[0]);
19620    operands[1] = gen_lowpart (SImode, operands[1]);
19621    if (GET_CODE (operands[3]) != ASHIFT)
19622      operands[2] = gen_lowpart (SImode, operands[2]);
19623    PUT_MODE (operands[3], SImode);")
19624
19625 ; Promote the QImode tests, as i386 has encoding of the AND
19626 ; instruction with 32-bit sign-extended immediate and thus the
19627 ; instruction size is unchanged, except in the %eax case for
19628 ; which it is increased by one byte, hence the ! optimize_size.
19629 (define_split
19630   [(set (match_operand 0 "flags_reg_operand" "")
19631         (match_operator 2 "compare_operator"
19632           [(and (match_operand 3 "aligned_operand" "")
19633                 (match_operand 4 "const_int_operand" ""))
19634            (const_int 0)]))
19635    (set (match_operand 1 "register_operand" "")
19636         (and (match_dup 3) (match_dup 4)))]
19637   "! TARGET_PARTIAL_REG_STALL && reload_completed
19638    /* Ensure that the operand will remain sign-extended immediate.  */
19639    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19640    && ! optimize_size
19641    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19642        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19643   [(parallel [(set (match_dup 0)
19644                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19645                                     (const_int 0)]))
19646               (set (match_dup 1)
19647                    (and:SI (match_dup 3) (match_dup 4)))])]
19648 {
19649   operands[4]
19650     = gen_int_mode (INTVAL (operands[4])
19651                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19652   operands[1] = gen_lowpart (SImode, operands[1]);
19653   operands[3] = gen_lowpart (SImode, operands[3]);
19654 })
19655
19656 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19657 ; the TEST instruction with 32-bit sign-extended immediate and thus
19658 ; the instruction size would at least double, which is not what we
19659 ; want even with ! optimize_size.
19660 (define_split
19661   [(set (match_operand 0 "flags_reg_operand" "")
19662         (match_operator 1 "compare_operator"
19663           [(and (match_operand:HI 2 "aligned_operand" "")
19664                 (match_operand:HI 3 "const_int_operand" ""))
19665            (const_int 0)]))]
19666   "! TARGET_PARTIAL_REG_STALL && reload_completed
19667    /* Ensure that the operand will remain sign-extended immediate.  */
19668    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19669    && ! TARGET_FAST_PREFIX
19670    && ! optimize_size"
19671   [(set (match_dup 0)
19672         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19673                          (const_int 0)]))]
19674 {
19675   operands[3]
19676     = gen_int_mode (INTVAL (operands[3])
19677                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19678   operands[2] = gen_lowpart (SImode, operands[2]);
19679 })
19680
19681 (define_split
19682   [(set (match_operand 0 "register_operand" "")
19683         (neg (match_operand 1 "register_operand" "")))
19684    (clobber (reg:CC FLAGS_REG))]
19685   "! TARGET_PARTIAL_REG_STALL && reload_completed
19686    && (GET_MODE (operands[0]) == HImode
19687        || (GET_MODE (operands[0]) == QImode
19688            && (TARGET_PROMOTE_QImode || optimize_size)))"
19689   [(parallel [(set (match_dup 0)
19690                    (neg:SI (match_dup 1)))
19691               (clobber (reg:CC FLAGS_REG))])]
19692   "operands[0] = gen_lowpart (SImode, operands[0]);
19693    operands[1] = gen_lowpart (SImode, operands[1]);")
19694
19695 (define_split
19696   [(set (match_operand 0 "register_operand" "")
19697         (not (match_operand 1 "register_operand" "")))]
19698   "! TARGET_PARTIAL_REG_STALL && reload_completed
19699    && (GET_MODE (operands[0]) == HImode
19700        || (GET_MODE (operands[0]) == QImode
19701            && (TARGET_PROMOTE_QImode || optimize_size)))"
19702   [(set (match_dup 0)
19703         (not:SI (match_dup 1)))]
19704   "operands[0] = gen_lowpart (SImode, operands[0]);
19705    operands[1] = gen_lowpart (SImode, operands[1]);")
19706
19707 (define_split
19708   [(set (match_operand 0 "register_operand" "")
19709         (if_then_else (match_operator 1 "comparison_operator"
19710                                 [(reg FLAGS_REG) (const_int 0)])
19711                       (match_operand 2 "register_operand" "")
19712                       (match_operand 3 "register_operand" "")))]
19713   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19714    && (GET_MODE (operands[0]) == HImode
19715        || (GET_MODE (operands[0]) == QImode
19716            && (TARGET_PROMOTE_QImode || optimize_size)))"
19717   [(set (match_dup 0)
19718         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19719   "operands[0] = gen_lowpart (SImode, operands[0]);
19720    operands[2] = gen_lowpart (SImode, operands[2]);
19721    operands[3] = gen_lowpart (SImode, operands[3]);")
19722
19723 \f
19724 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19725 ;; transform a complex memory operation into two memory to register operations.
19726
19727 ;; Don't push memory operands
19728 (define_peephole2
19729   [(set (match_operand:SI 0 "push_operand" "")
19730         (match_operand:SI 1 "memory_operand" ""))
19731    (match_scratch:SI 2 "r")]
19732   "!optimize_size && !TARGET_PUSH_MEMORY
19733    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19734   [(set (match_dup 2) (match_dup 1))
19735    (set (match_dup 0) (match_dup 2))]
19736   "")
19737
19738 (define_peephole2
19739   [(set (match_operand:DI 0 "push_operand" "")
19740         (match_operand:DI 1 "memory_operand" ""))
19741    (match_scratch:DI 2 "r")]
19742   "!optimize_size && !TARGET_PUSH_MEMORY
19743    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19744   [(set (match_dup 2) (match_dup 1))
19745    (set (match_dup 0) (match_dup 2))]
19746   "")
19747
19748 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19749 ;; SImode pushes.
19750 (define_peephole2
19751   [(set (match_operand:SF 0 "push_operand" "")
19752         (match_operand:SF 1 "memory_operand" ""))
19753    (match_scratch:SF 2 "r")]
19754   "!optimize_size && !TARGET_PUSH_MEMORY
19755    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19756   [(set (match_dup 2) (match_dup 1))
19757    (set (match_dup 0) (match_dup 2))]
19758   "")
19759
19760 (define_peephole2
19761   [(set (match_operand:HI 0 "push_operand" "")
19762         (match_operand:HI 1 "memory_operand" ""))
19763    (match_scratch:HI 2 "r")]
19764   "!optimize_size && !TARGET_PUSH_MEMORY
19765    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19766   [(set (match_dup 2) (match_dup 1))
19767    (set (match_dup 0) (match_dup 2))]
19768   "")
19769
19770 (define_peephole2
19771   [(set (match_operand:QI 0 "push_operand" "")
19772         (match_operand:QI 1 "memory_operand" ""))
19773    (match_scratch:QI 2 "q")]
19774   "!optimize_size && !TARGET_PUSH_MEMORY
19775    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19776   [(set (match_dup 2) (match_dup 1))
19777    (set (match_dup 0) (match_dup 2))]
19778   "")
19779
19780 ;; Don't move an immediate directly to memory when the instruction
19781 ;; gets too big.
19782 (define_peephole2
19783   [(match_scratch:SI 1 "r")
19784    (set (match_operand:SI 0 "memory_operand" "")
19785         (const_int 0))]
19786   "! optimize_size
19787    && ! TARGET_USE_MOV0
19788    && TARGET_SPLIT_LONG_MOVES
19789    && get_attr_length (insn) >= ix86_cost->large_insn
19790    && peep2_regno_dead_p (0, FLAGS_REG)"
19791   [(parallel [(set (match_dup 1) (const_int 0))
19792               (clobber (reg:CC FLAGS_REG))])
19793    (set (match_dup 0) (match_dup 1))]
19794   "")
19795
19796 (define_peephole2
19797   [(match_scratch:HI 1 "r")
19798    (set (match_operand:HI 0 "memory_operand" "")
19799         (const_int 0))]
19800   "! optimize_size
19801    && ! TARGET_USE_MOV0
19802    && TARGET_SPLIT_LONG_MOVES
19803    && get_attr_length (insn) >= ix86_cost->large_insn
19804    && peep2_regno_dead_p (0, FLAGS_REG)"
19805   [(parallel [(set (match_dup 2) (const_int 0))
19806               (clobber (reg:CC FLAGS_REG))])
19807    (set (match_dup 0) (match_dup 1))]
19808   "operands[2] = gen_lowpart (SImode, operands[1]);")
19809
19810 (define_peephole2
19811   [(match_scratch:QI 1 "q")
19812    (set (match_operand:QI 0 "memory_operand" "")
19813         (const_int 0))]
19814   "! optimize_size
19815    && ! TARGET_USE_MOV0
19816    && TARGET_SPLIT_LONG_MOVES
19817    && get_attr_length (insn) >= ix86_cost->large_insn
19818    && peep2_regno_dead_p (0, FLAGS_REG)"
19819   [(parallel [(set (match_dup 2) (const_int 0))
19820               (clobber (reg:CC FLAGS_REG))])
19821    (set (match_dup 0) (match_dup 1))]
19822   "operands[2] = gen_lowpart (SImode, operands[1]);")
19823
19824 (define_peephole2
19825   [(match_scratch:SI 2 "r")
19826    (set (match_operand:SI 0 "memory_operand" "")
19827         (match_operand:SI 1 "immediate_operand" ""))]
19828   "! optimize_size
19829    && get_attr_length (insn) >= ix86_cost->large_insn
19830    && TARGET_SPLIT_LONG_MOVES"
19831   [(set (match_dup 2) (match_dup 1))
19832    (set (match_dup 0) (match_dup 2))]
19833   "")
19834
19835 (define_peephole2
19836   [(match_scratch:HI 2 "r")
19837    (set (match_operand:HI 0 "memory_operand" "")
19838         (match_operand:HI 1 "immediate_operand" ""))]
19839   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19840   && TARGET_SPLIT_LONG_MOVES"
19841   [(set (match_dup 2) (match_dup 1))
19842    (set (match_dup 0) (match_dup 2))]
19843   "")
19844
19845 (define_peephole2
19846   [(match_scratch:QI 2 "q")
19847    (set (match_operand:QI 0 "memory_operand" "")
19848         (match_operand:QI 1 "immediate_operand" ""))]
19849   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19850   && TARGET_SPLIT_LONG_MOVES"
19851   [(set (match_dup 2) (match_dup 1))
19852    (set (match_dup 0) (match_dup 2))]
19853   "")
19854
19855 ;; Don't compare memory with zero, load and use a test instead.
19856 (define_peephole2
19857   [(set (match_operand 0 "flags_reg_operand" "")
19858         (match_operator 1 "compare_operator"
19859           [(match_operand:SI 2 "memory_operand" "")
19860            (const_int 0)]))
19861    (match_scratch:SI 3 "r")]
19862   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19863   [(set (match_dup 3) (match_dup 2))
19864    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19865   "")
19866
19867 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19868 ;; Don't split NOTs with a displacement operand, because resulting XOR
19869 ;; will not be pairable anyway.
19870 ;;
19871 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19872 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19873 ;; so this split helps here as well.
19874 ;;
19875 ;; Note: Can't do this as a regular split because we can't get proper
19876 ;; lifetime information then.
19877
19878 (define_peephole2
19879   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19880         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19881   "!optimize_size
19882    && peep2_regno_dead_p (0, FLAGS_REG)
19883    && ((TARGET_NOT_UNPAIRABLE
19884         && (!MEM_P (operands[0])
19885             || !memory_displacement_operand (operands[0], SImode)))
19886        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))"
19887   [(parallel [(set (match_dup 0)
19888                    (xor:SI (match_dup 1) (const_int -1)))
19889               (clobber (reg:CC FLAGS_REG))])]
19890   "")
19891
19892 (define_peephole2
19893   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19894         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19895   "!optimize_size
19896    && peep2_regno_dead_p (0, FLAGS_REG)
19897    && ((TARGET_NOT_UNPAIRABLE
19898         && (!MEM_P (operands[0])
19899             || !memory_displacement_operand (operands[0], HImode)))
19900        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))"
19901   [(parallel [(set (match_dup 0)
19902                    (xor:HI (match_dup 1) (const_int -1)))
19903               (clobber (reg:CC FLAGS_REG))])]
19904   "")
19905
19906 (define_peephole2
19907   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19908         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19909   "!optimize_size
19910    && peep2_regno_dead_p (0, FLAGS_REG)
19911    && ((TARGET_NOT_UNPAIRABLE
19912         && (!MEM_P (operands[0])
19913             || !memory_displacement_operand (operands[0], QImode)))
19914        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))"
19915   [(parallel [(set (match_dup 0)
19916                    (xor:QI (match_dup 1) (const_int -1)))
19917               (clobber (reg:CC FLAGS_REG))])]
19918   "")
19919
19920 ;; Non pairable "test imm, reg" instructions can be translated to
19921 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19922 ;; byte opcode instead of two, have a short form for byte operands),
19923 ;; so do it for other CPUs as well.  Given that the value was dead,
19924 ;; this should not create any new dependencies.  Pass on the sub-word
19925 ;; versions if we're concerned about partial register stalls.
19926
19927 (define_peephole2
19928   [(set (match_operand 0 "flags_reg_operand" "")
19929         (match_operator 1 "compare_operator"
19930           [(and:SI (match_operand:SI 2 "register_operand" "")
19931                    (match_operand:SI 3 "immediate_operand" ""))
19932            (const_int 0)]))]
19933   "ix86_match_ccmode (insn, CCNOmode)
19934    && (true_regnum (operands[2]) != 0
19935        || satisfies_constraint_K (operands[3]))
19936    && peep2_reg_dead_p (1, operands[2])"
19937   [(parallel
19938      [(set (match_dup 0)
19939            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19940                             (const_int 0)]))
19941       (set (match_dup 2)
19942            (and:SI (match_dup 2) (match_dup 3)))])]
19943   "")
19944
19945 ;; We don't need to handle HImode case, because it will be promoted to SImode
19946 ;; on ! TARGET_PARTIAL_REG_STALL
19947
19948 (define_peephole2
19949   [(set (match_operand 0 "flags_reg_operand" "")
19950         (match_operator 1 "compare_operator"
19951           [(and:QI (match_operand:QI 2 "register_operand" "")
19952                    (match_operand:QI 3 "immediate_operand" ""))
19953            (const_int 0)]))]
19954   "! TARGET_PARTIAL_REG_STALL
19955    && ix86_match_ccmode (insn, CCNOmode)
19956    && true_regnum (operands[2]) != 0
19957    && peep2_reg_dead_p (1, operands[2])"
19958   [(parallel
19959      [(set (match_dup 0)
19960            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19961                             (const_int 0)]))
19962       (set (match_dup 2)
19963            (and:QI (match_dup 2) (match_dup 3)))])]
19964   "")
19965
19966 (define_peephole2
19967   [(set (match_operand 0 "flags_reg_operand" "")
19968         (match_operator 1 "compare_operator"
19969           [(and:SI
19970              (zero_extract:SI
19971                (match_operand 2 "ext_register_operand" "")
19972                (const_int 8)
19973                (const_int 8))
19974              (match_operand 3 "const_int_operand" ""))
19975            (const_int 0)]))]
19976   "! TARGET_PARTIAL_REG_STALL
19977    && ix86_match_ccmode (insn, CCNOmode)
19978    && true_regnum (operands[2]) != 0
19979    && peep2_reg_dead_p (1, operands[2])"
19980   [(parallel [(set (match_dup 0)
19981                    (match_op_dup 1
19982                      [(and:SI
19983                         (zero_extract:SI
19984                           (match_dup 2)
19985                           (const_int 8)
19986                           (const_int 8))
19987                         (match_dup 3))
19988                       (const_int 0)]))
19989               (set (zero_extract:SI (match_dup 2)
19990                                     (const_int 8)
19991                                     (const_int 8))
19992                    (and:SI
19993                      (zero_extract:SI
19994                        (match_dup 2)
19995                        (const_int 8)
19996                        (const_int 8))
19997                      (match_dup 3)))])]
19998   "")
19999
20000 ;; Don't do logical operations with memory inputs.
20001 (define_peephole2
20002   [(match_scratch:SI 2 "r")
20003    (parallel [(set (match_operand:SI 0 "register_operand" "")
20004                    (match_operator:SI 3 "arith_or_logical_operator"
20005                      [(match_dup 0)
20006                       (match_operand:SI 1 "memory_operand" "")]))
20007               (clobber (reg:CC FLAGS_REG))])]
20008   "! optimize_size && ! TARGET_READ_MODIFY"
20009   [(set (match_dup 2) (match_dup 1))
20010    (parallel [(set (match_dup 0)
20011                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20012               (clobber (reg:CC FLAGS_REG))])]
20013   "")
20014
20015 (define_peephole2
20016   [(match_scratch:SI 2 "r")
20017    (parallel [(set (match_operand:SI 0 "register_operand" "")
20018                    (match_operator:SI 3 "arith_or_logical_operator"
20019                      [(match_operand:SI 1 "memory_operand" "")
20020                       (match_dup 0)]))
20021               (clobber (reg:CC FLAGS_REG))])]
20022   "! optimize_size && ! TARGET_READ_MODIFY"
20023   [(set (match_dup 2) (match_dup 1))
20024    (parallel [(set (match_dup 0)
20025                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20026               (clobber (reg:CC FLAGS_REG))])]
20027   "")
20028
20029 ; Don't do logical operations with memory outputs
20030 ;
20031 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20032 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20033 ; the same decoder scheduling characteristics as the original.
20034
20035 (define_peephole2
20036   [(match_scratch:SI 2 "r")
20037    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20038                    (match_operator:SI 3 "arith_or_logical_operator"
20039                      [(match_dup 0)
20040                       (match_operand:SI 1 "nonmemory_operand" "")]))
20041               (clobber (reg:CC FLAGS_REG))])]
20042   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20043   [(set (match_dup 2) (match_dup 0))
20044    (parallel [(set (match_dup 2)
20045                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20046               (clobber (reg:CC FLAGS_REG))])
20047    (set (match_dup 0) (match_dup 2))]
20048   "")
20049
20050 (define_peephole2
20051   [(match_scratch:SI 2 "r")
20052    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20053                    (match_operator:SI 3 "arith_or_logical_operator"
20054                      [(match_operand:SI 1 "nonmemory_operand" "")
20055                       (match_dup 0)]))
20056               (clobber (reg:CC FLAGS_REG))])]
20057   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20058   [(set (match_dup 2) (match_dup 0))
20059    (parallel [(set (match_dup 2)
20060                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20061               (clobber (reg:CC FLAGS_REG))])
20062    (set (match_dup 0) (match_dup 2))]
20063   "")
20064
20065 ;; Attempt to always use XOR for zeroing registers.
20066 (define_peephole2
20067   [(set (match_operand 0 "register_operand" "")
20068         (match_operand 1 "const0_operand" ""))]
20069   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20070    && (! TARGET_USE_MOV0 || optimize_size)
20071    && GENERAL_REG_P (operands[0])
20072    && peep2_regno_dead_p (0, FLAGS_REG)"
20073   [(parallel [(set (match_dup 0) (const_int 0))
20074               (clobber (reg:CC FLAGS_REG))])]
20075 {
20076   operands[0] = gen_lowpart (word_mode, operands[0]);
20077 })
20078
20079 (define_peephole2
20080   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20081         (const_int 0))]
20082   "(GET_MODE (operands[0]) == QImode
20083     || GET_MODE (operands[0]) == HImode)
20084    && (! TARGET_USE_MOV0 || optimize_size)
20085    && peep2_regno_dead_p (0, FLAGS_REG)"
20086   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20087               (clobber (reg:CC FLAGS_REG))])])
20088
20089 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20090 (define_peephole2
20091   [(set (match_operand 0 "register_operand" "")
20092         (const_int -1))]
20093   "(GET_MODE (operands[0]) == HImode
20094     || GET_MODE (operands[0]) == SImode
20095     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20096    && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20097    && peep2_regno_dead_p (0, FLAGS_REG)"
20098   [(parallel [(set (match_dup 0) (const_int -1))
20099               (clobber (reg:CC FLAGS_REG))])]
20100   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20101                               operands[0]);")
20102
20103 ;; Attempt to convert simple leas to adds. These can be created by
20104 ;; move expanders.
20105 (define_peephole2
20106   [(set (match_operand:SI 0 "register_operand" "")
20107         (plus:SI (match_dup 0)
20108                  (match_operand:SI 1 "nonmemory_operand" "")))]
20109   "peep2_regno_dead_p (0, FLAGS_REG)"
20110   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20111               (clobber (reg:CC FLAGS_REG))])]
20112   "")
20113
20114 (define_peephole2
20115   [(set (match_operand:SI 0 "register_operand" "")
20116         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20117                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20118   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20119   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20120               (clobber (reg:CC FLAGS_REG))])]
20121   "operands[2] = gen_lowpart (SImode, operands[2]);")
20122
20123 (define_peephole2
20124   [(set (match_operand:DI 0 "register_operand" "")
20125         (plus:DI (match_dup 0)
20126                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20127   "peep2_regno_dead_p (0, FLAGS_REG)"
20128   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20129               (clobber (reg:CC FLAGS_REG))])]
20130   "")
20131
20132 (define_peephole2
20133   [(set (match_operand:SI 0 "register_operand" "")
20134         (mult:SI (match_dup 0)
20135                  (match_operand:SI 1 "const_int_operand" "")))]
20136   "exact_log2 (INTVAL (operands[1])) >= 0
20137    && peep2_regno_dead_p (0, FLAGS_REG)"
20138   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20139               (clobber (reg:CC FLAGS_REG))])]
20140   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20141
20142 (define_peephole2
20143   [(set (match_operand:DI 0 "register_operand" "")
20144         (mult:DI (match_dup 0)
20145                  (match_operand:DI 1 "const_int_operand" "")))]
20146   "exact_log2 (INTVAL (operands[1])) >= 0
20147    && peep2_regno_dead_p (0, FLAGS_REG)"
20148   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20149               (clobber (reg:CC FLAGS_REG))])]
20150   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20151
20152 (define_peephole2
20153   [(set (match_operand:SI 0 "register_operand" "")
20154         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20155                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20156   "exact_log2 (INTVAL (operands[2])) >= 0
20157    && REGNO (operands[0]) == REGNO (operands[1])
20158    && peep2_regno_dead_p (0, FLAGS_REG)"
20159   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20160               (clobber (reg:CC FLAGS_REG))])]
20161   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20162
20163 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20164 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20165 ;; many CPUs it is also faster, since special hardware to avoid esp
20166 ;; dependencies is present.
20167
20168 ;; While some of these conversions may be done using splitters, we use peepholes
20169 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20170
20171 ;; Convert prologue esp subtractions to push.
20172 ;; We need register to push.  In order to keep verify_flow_info happy we have
20173 ;; two choices
20174 ;; - use scratch and clobber it in order to avoid dependencies
20175 ;; - use already live register
20176 ;; We can't use the second way right now, since there is no reliable way how to
20177 ;; verify that given register is live.  First choice will also most likely in
20178 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20179 ;; call clobbered registers are dead.  We may want to use base pointer as an
20180 ;; alternative when no register is available later.
20181
20182 (define_peephole2
20183   [(match_scratch:SI 0 "r")
20184    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20185               (clobber (reg:CC FLAGS_REG))
20186               (clobber (mem:BLK (scratch)))])]
20187   "optimize_size || !TARGET_SUB_ESP_4"
20188   [(clobber (match_dup 0))
20189    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20190               (clobber (mem:BLK (scratch)))])])
20191
20192 (define_peephole2
20193   [(match_scratch:SI 0 "r")
20194    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20195               (clobber (reg:CC FLAGS_REG))
20196               (clobber (mem:BLK (scratch)))])]
20197   "optimize_size || !TARGET_SUB_ESP_8"
20198   [(clobber (match_dup 0))
20199    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20200    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20201               (clobber (mem:BLK (scratch)))])])
20202
20203 ;; Convert esp subtractions to push.
20204 (define_peephole2
20205   [(match_scratch:SI 0 "r")
20206    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20207               (clobber (reg:CC FLAGS_REG))])]
20208   "optimize_size || !TARGET_SUB_ESP_4"
20209   [(clobber (match_dup 0))
20210    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20211
20212 (define_peephole2
20213   [(match_scratch:SI 0 "r")
20214    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20215               (clobber (reg:CC FLAGS_REG))])]
20216   "optimize_size || !TARGET_SUB_ESP_8"
20217   [(clobber (match_dup 0))
20218    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20219    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20220
20221 ;; Convert epilogue deallocator to pop.
20222 (define_peephole2
20223   [(match_scratch:SI 0 "r")
20224    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20225               (clobber (reg:CC FLAGS_REG))
20226               (clobber (mem:BLK (scratch)))])]
20227   "optimize_size || !TARGET_ADD_ESP_4"
20228   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20229               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20230               (clobber (mem:BLK (scratch)))])]
20231   "")
20232
20233 ;; Two pops case is tricky, since pop causes dependency on destination register.
20234 ;; We use two registers if available.
20235 (define_peephole2
20236   [(match_scratch:SI 0 "r")
20237    (match_scratch:SI 1 "r")
20238    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20239               (clobber (reg:CC FLAGS_REG))
20240               (clobber (mem:BLK (scratch)))])]
20241   "optimize_size || !TARGET_ADD_ESP_8"
20242   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20243               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20244               (clobber (mem:BLK (scratch)))])
20245    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20246               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20247   "")
20248
20249 (define_peephole2
20250   [(match_scratch:SI 0 "r")
20251    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20252               (clobber (reg:CC FLAGS_REG))
20253               (clobber (mem:BLK (scratch)))])]
20254   "optimize_size"
20255   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20256               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20257               (clobber (mem:BLK (scratch)))])
20258    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20259               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20260   "")
20261
20262 ;; Convert esp additions to pop.
20263 (define_peephole2
20264   [(match_scratch:SI 0 "r")
20265    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20266               (clobber (reg:CC FLAGS_REG))])]
20267   ""
20268   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20269               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20270   "")
20271
20272 ;; Two pops case is tricky, since pop causes dependency on destination register.
20273 ;; We use two registers if available.
20274 (define_peephole2
20275   [(match_scratch:SI 0 "r")
20276    (match_scratch:SI 1 "r")
20277    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20278               (clobber (reg:CC FLAGS_REG))])]
20279   ""
20280   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20281               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20282    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20283               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20284   "")
20285
20286 (define_peephole2
20287   [(match_scratch:SI 0 "r")
20288    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20289               (clobber (reg:CC FLAGS_REG))])]
20290   "optimize_size"
20291   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20292               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20293    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20294               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20295   "")
20296 \f
20297 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20298 ;; required and register dies.  Similarly for 128 to plus -128.
20299 (define_peephole2
20300   [(set (match_operand 0 "flags_reg_operand" "")
20301         (match_operator 1 "compare_operator"
20302           [(match_operand 2 "register_operand" "")
20303            (match_operand 3 "const_int_operand" "")]))]
20304   "(INTVAL (operands[3]) == -1
20305     || INTVAL (operands[3]) == 1
20306     || INTVAL (operands[3]) == 128)
20307    && ix86_match_ccmode (insn, CCGCmode)
20308    && peep2_reg_dead_p (1, operands[2])"
20309   [(parallel [(set (match_dup 0)
20310                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20311               (clobber (match_dup 2))])]
20312   "")
20313 \f
20314 (define_peephole2
20315   [(match_scratch:DI 0 "r")
20316    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20317               (clobber (reg:CC FLAGS_REG))
20318               (clobber (mem:BLK (scratch)))])]
20319   "optimize_size || !TARGET_SUB_ESP_4"
20320   [(clobber (match_dup 0))
20321    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20322               (clobber (mem:BLK (scratch)))])])
20323
20324 (define_peephole2
20325   [(match_scratch:DI 0 "r")
20326    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20327               (clobber (reg:CC FLAGS_REG))
20328               (clobber (mem:BLK (scratch)))])]
20329   "optimize_size || !TARGET_SUB_ESP_8"
20330   [(clobber (match_dup 0))
20331    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20332    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20333               (clobber (mem:BLK (scratch)))])])
20334
20335 ;; Convert esp subtractions to push.
20336 (define_peephole2
20337   [(match_scratch:DI 0 "r")
20338    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20339               (clobber (reg:CC FLAGS_REG))])]
20340   "optimize_size || !TARGET_SUB_ESP_4"
20341   [(clobber (match_dup 0))
20342    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20343
20344 (define_peephole2
20345   [(match_scratch:DI 0 "r")
20346    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20347               (clobber (reg:CC FLAGS_REG))])]
20348   "optimize_size || !TARGET_SUB_ESP_8"
20349   [(clobber (match_dup 0))
20350    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20351    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20352
20353 ;; Convert epilogue deallocator to pop.
20354 (define_peephole2
20355   [(match_scratch:DI 0 "r")
20356    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20357               (clobber (reg:CC FLAGS_REG))
20358               (clobber (mem:BLK (scratch)))])]
20359   "optimize_size || !TARGET_ADD_ESP_4"
20360   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20361               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20362               (clobber (mem:BLK (scratch)))])]
20363   "")
20364
20365 ;; Two pops case is tricky, since pop causes dependency on destination register.
20366 ;; We use two registers if available.
20367 (define_peephole2
20368   [(match_scratch:DI 0 "r")
20369    (match_scratch:DI 1 "r")
20370    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20371               (clobber (reg:CC FLAGS_REG))
20372               (clobber (mem:BLK (scratch)))])]
20373   "optimize_size || !TARGET_ADD_ESP_8"
20374   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20375               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20376               (clobber (mem:BLK (scratch)))])
20377    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20378               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20379   "")
20380
20381 (define_peephole2
20382   [(match_scratch:DI 0 "r")
20383    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20384               (clobber (reg:CC FLAGS_REG))
20385               (clobber (mem:BLK (scratch)))])]
20386   "optimize_size"
20387   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20388               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20389               (clobber (mem:BLK (scratch)))])
20390    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20391               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20392   "")
20393
20394 ;; Convert esp additions to pop.
20395 (define_peephole2
20396   [(match_scratch:DI 0 "r")
20397    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20398               (clobber (reg:CC FLAGS_REG))])]
20399   ""
20400   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20401               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20402   "")
20403
20404 ;; Two pops case is tricky, since pop causes dependency on destination register.
20405 ;; We use two registers if available.
20406 (define_peephole2
20407   [(match_scratch:DI 0 "r")
20408    (match_scratch:DI 1 "r")
20409    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20410               (clobber (reg:CC FLAGS_REG))])]
20411   ""
20412   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20413               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20414    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20415               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20416   "")
20417
20418 (define_peephole2
20419   [(match_scratch:DI 0 "r")
20420    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20421               (clobber (reg:CC FLAGS_REG))])]
20422   "optimize_size"
20423   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20424               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20425    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20426               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20427   "")
20428 \f
20429 ;; Convert imul by three, five and nine into lea
20430 (define_peephole2
20431   [(parallel
20432     [(set (match_operand:SI 0 "register_operand" "")
20433           (mult:SI (match_operand:SI 1 "register_operand" "")
20434                    (match_operand:SI 2 "const_int_operand" "")))
20435      (clobber (reg:CC FLAGS_REG))])]
20436   "INTVAL (operands[2]) == 3
20437    || INTVAL (operands[2]) == 5
20438    || INTVAL (operands[2]) == 9"
20439   [(set (match_dup 0)
20440         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20441                  (match_dup 1)))]
20442   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20443
20444 (define_peephole2
20445   [(parallel
20446     [(set (match_operand:SI 0 "register_operand" "")
20447           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20448                    (match_operand:SI 2 "const_int_operand" "")))
20449      (clobber (reg:CC FLAGS_REG))])]
20450   "!optimize_size
20451    && (INTVAL (operands[2]) == 3
20452        || INTVAL (operands[2]) == 5
20453        || INTVAL (operands[2]) == 9)"
20454   [(set (match_dup 0) (match_dup 1))
20455    (set (match_dup 0)
20456         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20457                  (match_dup 0)))]
20458   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20459
20460 (define_peephole2
20461   [(parallel
20462     [(set (match_operand:DI 0 "register_operand" "")
20463           (mult:DI (match_operand:DI 1 "register_operand" "")
20464                    (match_operand:DI 2 "const_int_operand" "")))
20465      (clobber (reg:CC FLAGS_REG))])]
20466   "TARGET_64BIT
20467    && (INTVAL (operands[2]) == 3
20468        || INTVAL (operands[2]) == 5
20469        || INTVAL (operands[2]) == 9)"
20470   [(set (match_dup 0)
20471         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20472                  (match_dup 1)))]
20473   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20474
20475 (define_peephole2
20476   [(parallel
20477     [(set (match_operand:DI 0 "register_operand" "")
20478           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20479                    (match_operand:DI 2 "const_int_operand" "")))
20480      (clobber (reg:CC FLAGS_REG))])]
20481   "TARGET_64BIT
20482    && !optimize_size
20483    && (INTVAL (operands[2]) == 3
20484        || INTVAL (operands[2]) == 5
20485        || INTVAL (operands[2]) == 9)"
20486   [(set (match_dup 0) (match_dup 1))
20487    (set (match_dup 0)
20488         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20489                  (match_dup 0)))]
20490   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20491
20492 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20493 ;; imul $32bit_imm, reg, reg is direct decoded.
20494 (define_peephole2
20495   [(match_scratch:DI 3 "r")
20496    (parallel [(set (match_operand:DI 0 "register_operand" "")
20497                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20498                             (match_operand:DI 2 "immediate_operand" "")))
20499               (clobber (reg:CC FLAGS_REG))])]
20500   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20501    && !satisfies_constraint_K (operands[2])"
20502   [(set (match_dup 3) (match_dup 1))
20503    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20504               (clobber (reg:CC FLAGS_REG))])]
20505 "")
20506
20507 (define_peephole2
20508   [(match_scratch:SI 3 "r")
20509    (parallel [(set (match_operand:SI 0 "register_operand" "")
20510                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20511                             (match_operand:SI 2 "immediate_operand" "")))
20512               (clobber (reg:CC FLAGS_REG))])]
20513   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20514    && !satisfies_constraint_K (operands[2])"
20515   [(set (match_dup 3) (match_dup 1))
20516    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20517               (clobber (reg:CC FLAGS_REG))])]
20518 "")
20519
20520 (define_peephole2
20521   [(match_scratch:SI 3 "r")
20522    (parallel [(set (match_operand:DI 0 "register_operand" "")
20523                    (zero_extend:DI
20524                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20525                               (match_operand:SI 2 "immediate_operand" ""))))
20526               (clobber (reg:CC FLAGS_REG))])]
20527   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20528    && !satisfies_constraint_K (operands[2])"
20529   [(set (match_dup 3) (match_dup 1))
20530    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20531               (clobber (reg:CC FLAGS_REG))])]
20532 "")
20533
20534 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20535 ;; Convert it into imul reg, reg
20536 ;; It would be better to force assembler to encode instruction using long
20537 ;; immediate, but there is apparently no way to do so.
20538 (define_peephole2
20539   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20540                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20541                             (match_operand:DI 2 "const_int_operand" "")))
20542               (clobber (reg:CC FLAGS_REG))])
20543    (match_scratch:DI 3 "r")]
20544   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20545    && satisfies_constraint_K (operands[2])"
20546   [(set (match_dup 3) (match_dup 2))
20547    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20548               (clobber (reg:CC FLAGS_REG))])]
20549 {
20550   if (!rtx_equal_p (operands[0], operands[1]))
20551     emit_move_insn (operands[0], operands[1]);
20552 })
20553
20554 (define_peephole2
20555   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20556                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20557                             (match_operand:SI 2 "const_int_operand" "")))
20558               (clobber (reg:CC FLAGS_REG))])
20559    (match_scratch:SI 3 "r")]
20560   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20561    && satisfies_constraint_K (operands[2])"
20562   [(set (match_dup 3) (match_dup 2))
20563    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20564               (clobber (reg:CC FLAGS_REG))])]
20565 {
20566   if (!rtx_equal_p (operands[0], operands[1]))
20567     emit_move_insn (operands[0], operands[1]);
20568 })
20569
20570 (define_peephole2
20571   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20572                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20573                             (match_operand:HI 2 "immediate_operand" "")))
20574               (clobber (reg:CC FLAGS_REG))])
20575    (match_scratch:HI 3 "r")]
20576   "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20577   [(set (match_dup 3) (match_dup 2))
20578    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20579               (clobber (reg:CC FLAGS_REG))])]
20580 {
20581   if (!rtx_equal_p (operands[0], operands[1]))
20582     emit_move_insn (operands[0], operands[1]);
20583 })
20584
20585 ;; After splitting up read-modify operations, array accesses with memory
20586 ;; operands might end up in form:
20587 ;;  sall    $2, %eax
20588 ;;  movl    4(%esp), %edx
20589 ;;  addl    %edx, %eax
20590 ;; instead of pre-splitting:
20591 ;;  sall    $2, %eax
20592 ;;  addl    4(%esp), %eax
20593 ;; Turn it into:
20594 ;;  movl    4(%esp), %edx
20595 ;;  leal    (%edx,%eax,4), %eax
20596
20597 (define_peephole2
20598   [(parallel [(set (match_operand 0 "register_operand" "")
20599                    (ashift (match_operand 1 "register_operand" "")
20600                            (match_operand 2 "const_int_operand" "")))
20601                (clobber (reg:CC FLAGS_REG))])
20602    (set (match_operand 3 "register_operand")
20603         (match_operand 4 "x86_64_general_operand" ""))
20604    (parallel [(set (match_operand 5 "register_operand" "")
20605                    (plus (match_operand 6 "register_operand" "")
20606                          (match_operand 7 "register_operand" "")))
20607                    (clobber (reg:CC FLAGS_REG))])]
20608   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20609    /* Validate MODE for lea.  */
20610    && ((!TARGET_PARTIAL_REG_STALL
20611         && (GET_MODE (operands[0]) == QImode
20612             || GET_MODE (operands[0]) == HImode))
20613        || GET_MODE (operands[0]) == SImode
20614        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20615    /* We reorder load and the shift.  */
20616    && !rtx_equal_p (operands[1], operands[3])
20617    && !reg_overlap_mentioned_p (operands[0], operands[4])
20618    /* Last PLUS must consist of operand 0 and 3.  */
20619    && !rtx_equal_p (operands[0], operands[3])
20620    && (rtx_equal_p (operands[3], operands[6])
20621        || rtx_equal_p (operands[3], operands[7]))
20622    && (rtx_equal_p (operands[0], operands[6])
20623        || rtx_equal_p (operands[0], operands[7]))
20624    /* The intermediate operand 0 must die or be same as output.  */
20625    && (rtx_equal_p (operands[0], operands[5])
20626        || peep2_reg_dead_p (3, operands[0]))"
20627   [(set (match_dup 3) (match_dup 4))
20628    (set (match_dup 0) (match_dup 1))]
20629 {
20630   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20631   int scale = 1 << INTVAL (operands[2]);
20632   rtx index = gen_lowpart (Pmode, operands[1]);
20633   rtx base = gen_lowpart (Pmode, operands[3]);
20634   rtx dest = gen_lowpart (mode, operands[5]);
20635
20636   operands[1] = gen_rtx_PLUS (Pmode, base,
20637                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20638   if (mode != Pmode)
20639     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20640   operands[0] = dest;
20641 })
20642 \f
20643 ;; Call-value patterns last so that the wildcard operand does not
20644 ;; disrupt insn-recog's switch tables.
20645
20646 (define_insn "*call_value_pop_0"
20647   [(set (match_operand 0 "" "")
20648         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20649               (match_operand:SI 2 "" "")))
20650    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20651                             (match_operand:SI 3 "immediate_operand" "")))]
20652   "!TARGET_64BIT"
20653 {
20654   if (SIBLING_CALL_P (insn))
20655     return "jmp\t%P1";
20656   else
20657     return "call\t%P1";
20658 }
20659   [(set_attr "type" "callv")])
20660
20661 (define_insn "*call_value_pop_1"
20662   [(set (match_operand 0 "" "")
20663         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20664               (match_operand:SI 2 "" "")))
20665    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20666                             (match_operand:SI 3 "immediate_operand" "i")))]
20667   "!TARGET_64BIT"
20668 {
20669   if (constant_call_address_operand (operands[1], Pmode))
20670     {
20671       if (SIBLING_CALL_P (insn))
20672         return "jmp\t%P1";
20673       else
20674         return "call\t%P1";
20675     }
20676   if (SIBLING_CALL_P (insn))
20677     return "jmp\t%A1";
20678   else
20679     return "call\t%A1";
20680 }
20681   [(set_attr "type" "callv")])
20682
20683 (define_insn "*call_value_0"
20684   [(set (match_operand 0 "" "")
20685         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20686               (match_operand:SI 2 "" "")))]
20687   "!TARGET_64BIT"
20688 {
20689   if (SIBLING_CALL_P (insn))
20690     return "jmp\t%P1";
20691   else
20692     return "call\t%P1";
20693 }
20694   [(set_attr "type" "callv")])
20695
20696 (define_insn "*call_value_0_rex64"
20697   [(set (match_operand 0 "" "")
20698         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20699               (match_operand:DI 2 "const_int_operand" "")))]
20700   "TARGET_64BIT"
20701 {
20702   if (SIBLING_CALL_P (insn))
20703     return "jmp\t%P1";
20704   else
20705     return "call\t%P1";
20706 }
20707   [(set_attr "type" "callv")])
20708
20709 (define_insn "*call_value_1"
20710   [(set (match_operand 0 "" "")
20711         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20712               (match_operand:SI 2 "" "")))]
20713   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20714 {
20715   if (constant_call_address_operand (operands[1], Pmode))
20716     return "call\t%P1";
20717   return "call\t%A1";
20718 }
20719   [(set_attr "type" "callv")])
20720
20721 (define_insn "*sibcall_value_1"
20722   [(set (match_operand 0 "" "")
20723         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20724               (match_operand:SI 2 "" "")))]
20725   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20726 {
20727   if (constant_call_address_operand (operands[1], Pmode))
20728     return "jmp\t%P1";
20729   return "jmp\t%A1";
20730 }
20731   [(set_attr "type" "callv")])
20732
20733 (define_insn "*call_value_1_rex64"
20734   [(set (match_operand 0 "" "")
20735         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20736               (match_operand:DI 2 "" "")))]
20737   "!SIBLING_CALL_P (insn) && TARGET_64BIT
20738    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20739 {
20740   if (constant_call_address_operand (operands[1], Pmode))
20741     return "call\t%P1";
20742   return "call\t%A1";
20743 }
20744   [(set_attr "type" "callv")])
20745
20746 (define_insn "*call_value_1_rex64_large"
20747   [(set (match_operand 0 "" "")
20748         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20749               (match_operand:DI 2 "" "")))]
20750   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20751   "call\t%A1"
20752   [(set_attr "type" "callv")])
20753
20754 (define_insn "*sibcall_value_1_rex64"
20755   [(set (match_operand 0 "" "")
20756         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20757               (match_operand:DI 2 "" "")))]
20758   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20759   "jmp\t%P1"
20760   [(set_attr "type" "callv")])
20761
20762 (define_insn "*sibcall_value_1_rex64_v"
20763   [(set (match_operand 0 "" "")
20764         (call (mem:QI (reg:DI R11_REG))
20765               (match_operand:DI 1 "" "")))]
20766   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20767   "jmp\t*%%r11"
20768   [(set_attr "type" "callv")])
20769 \f
20770 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20771 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20772 ;; caught for use by garbage collectors and the like.  Using an insn that
20773 ;; maps to SIGILL makes it more likely the program will rightfully die.
20774 ;; Keeping with tradition, "6" is in honor of #UD.
20775 (define_insn "trap"
20776   [(trap_if (const_int 1) (const_int 6))]
20777   ""
20778   { return ASM_SHORT "0x0b0f"; }
20779   [(set_attr "length" "2")])
20780
20781 (define_expand "sse_prologue_save"
20782   [(parallel [(set (match_operand:BLK 0 "" "")
20783                    (unspec:BLK [(reg:DI 21)
20784                                 (reg:DI 22)
20785                                 (reg:DI 23)
20786                                 (reg:DI 24)
20787                                 (reg:DI 25)
20788                                 (reg:DI 26)
20789                                 (reg:DI 27)
20790                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20791               (use (match_operand:DI 1 "register_operand" ""))
20792               (use (match_operand:DI 2 "immediate_operand" ""))
20793               (use (label_ref:DI (match_operand 3 "" "")))])]
20794   "TARGET_64BIT"
20795   "")
20796
20797 (define_insn "*sse_prologue_save_insn"
20798   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20799                           (match_operand:DI 4 "const_int_operand" "n")))
20800         (unspec:BLK [(reg:DI 21)
20801                      (reg:DI 22)
20802                      (reg:DI 23)
20803                      (reg:DI 24)
20804                      (reg:DI 25)
20805                      (reg:DI 26)
20806                      (reg:DI 27)
20807                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20808    (use (match_operand:DI 1 "register_operand" "r"))
20809    (use (match_operand:DI 2 "const_int_operand" "i"))
20810    (use (label_ref:DI (match_operand 3 "" "X")))]
20811   "TARGET_64BIT
20812    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20813    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20814   "*
20815 {
20816   int i;
20817   operands[0] = gen_rtx_MEM (Pmode,
20818                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20819   output_asm_insn (\"jmp\\t%A1\", operands);
20820   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20821     {
20822       operands[4] = adjust_address (operands[0], DImode, i*16);
20823       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20824       PUT_MODE (operands[4], TImode);
20825       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20826         output_asm_insn (\"rex\", operands);
20827       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20828     }
20829   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20830                              CODE_LABEL_NUMBER (operands[3]));
20831   return \"\";
20832 }
20833   "
20834   [(set_attr "type" "other")
20835    (set_attr "length_immediate" "0")
20836    (set_attr "length_address" "0")
20837    (set_attr "length" "135")
20838    (set_attr "memory" "store")
20839    (set_attr "modrm" "0")
20840    (set_attr "mode" "DI")])
20841
20842 (define_expand "prefetch"
20843   [(prefetch (match_operand 0 "address_operand" "")
20844              (match_operand:SI 1 "const_int_operand" "")
20845              (match_operand:SI 2 "const_int_operand" ""))]
20846   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20847 {
20848   int rw = INTVAL (operands[1]);
20849   int locality = INTVAL (operands[2]);
20850
20851   gcc_assert (rw == 0 || rw == 1);
20852   gcc_assert (locality >= 0 && locality <= 3);
20853   gcc_assert (GET_MODE (operands[0]) == Pmode
20854               || GET_MODE (operands[0]) == VOIDmode);
20855
20856   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20857      supported by SSE counterpart or the SSE prefetch is not available
20858      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20859      of locality.  */
20860   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20861     operands[2] = GEN_INT (3);
20862   else
20863     operands[1] = const0_rtx;
20864 })
20865
20866 (define_insn "*prefetch_sse"
20867   [(prefetch (match_operand:SI 0 "address_operand" "p")
20868              (const_int 0)
20869              (match_operand:SI 1 "const_int_operand" ""))]
20870   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20871 {
20872   static const char * const patterns[4] = {
20873    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20874   };
20875
20876   int locality = INTVAL (operands[1]);
20877   gcc_assert (locality >= 0 && locality <= 3);
20878
20879   return patterns[locality];
20880 }
20881   [(set_attr "type" "sse")
20882    (set_attr "memory" "none")])
20883
20884 (define_insn "*prefetch_sse_rex"
20885   [(prefetch (match_operand:DI 0 "address_operand" "p")
20886              (const_int 0)
20887              (match_operand:SI 1 "const_int_operand" ""))]
20888   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20889 {
20890   static const char * const patterns[4] = {
20891    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20892   };
20893
20894   int locality = INTVAL (operands[1]);
20895   gcc_assert (locality >= 0 && locality <= 3);
20896
20897   return patterns[locality];
20898 }
20899   [(set_attr "type" "sse")
20900    (set_attr "memory" "none")])
20901
20902 (define_insn "*prefetch_3dnow"
20903   [(prefetch (match_operand:SI 0 "address_operand" "p")
20904              (match_operand:SI 1 "const_int_operand" "n")
20905              (const_int 3))]
20906   "TARGET_3DNOW && !TARGET_64BIT"
20907 {
20908   if (INTVAL (operands[1]) == 0)
20909     return "prefetch\t%a0";
20910   else
20911     return "prefetchw\t%a0";
20912 }
20913   [(set_attr "type" "mmx")
20914    (set_attr "memory" "none")])
20915
20916 (define_insn "*prefetch_3dnow_rex"
20917   [(prefetch (match_operand:DI 0 "address_operand" "p")
20918              (match_operand:SI 1 "const_int_operand" "n")
20919              (const_int 3))]
20920   "TARGET_3DNOW && TARGET_64BIT"
20921 {
20922   if (INTVAL (operands[1]) == 0)
20923     return "prefetch\t%a0";
20924   else
20925     return "prefetchw\t%a0";
20926 }
20927   [(set_attr "type" "mmx")
20928    (set_attr "memory" "none")])
20929
20930 (define_expand "stack_protect_set"
20931   [(match_operand 0 "memory_operand" "")
20932    (match_operand 1 "memory_operand" "")]
20933   ""
20934 {
20935 #ifdef TARGET_THREAD_SSP_OFFSET
20936   if (TARGET_64BIT)
20937     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20938                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20939   else
20940     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20941                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20942 #else
20943   if (TARGET_64BIT)
20944     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20945   else
20946     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20947 #endif
20948   DONE;
20949 })
20950
20951 (define_insn "stack_protect_set_si"
20952   [(set (match_operand:SI 0 "memory_operand" "=m")
20953         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20954    (set (match_scratch:SI 2 "=&r") (const_int 0))
20955    (clobber (reg:CC FLAGS_REG))]
20956   ""
20957   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20958   [(set_attr "type" "multi")])
20959
20960 (define_insn "stack_protect_set_di"
20961   [(set (match_operand:DI 0 "memory_operand" "=m")
20962         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20963    (set (match_scratch:DI 2 "=&r") (const_int 0))
20964    (clobber (reg:CC FLAGS_REG))]
20965   "TARGET_64BIT"
20966   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20967   [(set_attr "type" "multi")])
20968
20969 (define_insn "stack_tls_protect_set_si"
20970   [(set (match_operand:SI 0 "memory_operand" "=m")
20971         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20972    (set (match_scratch:SI 2 "=&r") (const_int 0))
20973    (clobber (reg:CC FLAGS_REG))]
20974   ""
20975   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20976   [(set_attr "type" "multi")])
20977
20978 (define_insn "stack_tls_protect_set_di"
20979   [(set (match_operand:DI 0 "memory_operand" "=m")
20980         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20981    (set (match_scratch:DI 2 "=&r") (const_int 0))
20982    (clobber (reg:CC FLAGS_REG))]
20983   "TARGET_64BIT"
20984   {
20985      /* The kernel uses a different segment register for performance reasons; a
20986         system call would not have to trash the userspace segment register,
20987         which would be expensive */
20988      if (ix86_cmodel != CM_KERNEL)
20989         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20990      else
20991         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20992   }
20993   [(set_attr "type" "multi")])
20994
20995 (define_expand "stack_protect_test"
20996   [(match_operand 0 "memory_operand" "")
20997    (match_operand 1 "memory_operand" "")
20998    (match_operand 2 "" "")]
20999   ""
21000 {
21001   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21002   ix86_compare_op0 = operands[0];
21003   ix86_compare_op1 = operands[1];
21004   ix86_compare_emitted = flags;
21005
21006 #ifdef TARGET_THREAD_SSP_OFFSET
21007   if (TARGET_64BIT)
21008     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21009                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21010   else
21011     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21012                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21013 #else
21014   if (TARGET_64BIT)
21015     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21016   else
21017     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21018 #endif
21019   emit_jump_insn (gen_beq (operands[2]));
21020   DONE;
21021 })
21022
21023 (define_insn "stack_protect_test_si"
21024   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21025         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21026                      (match_operand:SI 2 "memory_operand" "m")]
21027                     UNSPEC_SP_TEST))
21028    (clobber (match_scratch:SI 3 "=&r"))]
21029   ""
21030   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21031   [(set_attr "type" "multi")])
21032
21033 (define_insn "stack_protect_test_di"
21034   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21035         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21036                      (match_operand:DI 2 "memory_operand" "m")]
21037                     UNSPEC_SP_TEST))
21038    (clobber (match_scratch:DI 3 "=&r"))]
21039   "TARGET_64BIT"
21040   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21041   [(set_attr "type" "multi")])
21042
21043 (define_insn "stack_tls_protect_test_si"
21044   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21045         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21046                      (match_operand:SI 2 "const_int_operand" "i")]
21047                     UNSPEC_SP_TLS_TEST))
21048    (clobber (match_scratch:SI 3 "=r"))]
21049   ""
21050   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21051   [(set_attr "type" "multi")])
21052
21053 (define_insn "stack_tls_protect_test_di"
21054   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21055         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21056                      (match_operand:DI 2 "const_int_operand" "i")]
21057                     UNSPEC_SP_TLS_TEST))
21058    (clobber (match_scratch:DI 3 "=r"))]
21059   "TARGET_64BIT"
21060   {
21061      /* The kernel uses a different segment register for performance reasons; a
21062         system call would not have to trash the userspace segment register,
21063         which would be expensive */
21064      if (ix86_cmodel != CM_KERNEL)
21065         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21066      else
21067         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21068   }
21069   [(set_attr "type" "multi")])
21070
21071 (include "mmx.md")
21072 (include "sse.md")
21073 (include "sync.md")