OSDN Git Service

PR target/35540
[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, 2008
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.  */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
31 ;;     operands[1].
32 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
33 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
34 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
35 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
36 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
37 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
38 ;; 'J' Print the appropriate jump operand.
39 ;;
40 ;; 'b' Print the QImode name of the register for the indicated operand.
41 ;;     %b0 would print %al if operands[0] is reg 0.
42 ;; 'w' Likewise, print the HImode name of the register.
43 ;; 'k' Likewise, print the SImode name of the register.
44 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
45 ;; 'y' Print "st(0)" instead of "st" as a register.
46
47 ;; UNSPEC usage:
48
49 (define_constants
50   [; Relocation specifiers
51    (UNSPEC_GOT                  0)
52    (UNSPEC_GOTOFF               1)
53    (UNSPEC_GOTPCREL             2)
54    (UNSPEC_GOTTPOFF             3)
55    (UNSPEC_TPOFF                4)
56    (UNSPEC_NTPOFF               5)
57    (UNSPEC_DTPOFF               6)
58    (UNSPEC_GOTNTPOFF            7)
59    (UNSPEC_INDNTPOFF            8)
60    (UNSPEC_PLTOFF               9)
61
62    ; Prologue support
63    (UNSPEC_STACK_ALLOC          11)
64    (UNSPEC_SET_GOT              12)
65    (UNSPEC_SSE_PROLOGUE_SAVE    13)
66    (UNSPEC_REG_SAVE             14)
67    (UNSPEC_DEF_CFA              15)
68    (UNSPEC_SET_RIP              16)
69    (UNSPEC_SET_GOT_OFFSET       17)
70
71    ; TLS support
72    (UNSPEC_TP                   18)
73    (UNSPEC_TLS_GD               19)
74    (UNSPEC_TLS_LD_BASE          20)
75    (UNSPEC_TLSDESC              21)
76
77    ; Other random patterns
78    (UNSPEC_SCAS                 30)
79    (UNSPEC_FNSTSW               31)
80    (UNSPEC_SAHF                 32)
81    (UNSPEC_FSTCW                33)
82    (UNSPEC_ADD_CARRY            34)
83    (UNSPEC_FLDCW                35)
84    (UNSPEC_REP                  36)
85    (UNSPEC_EH_RETURN            37)
86    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
87    (UNSPEC_TRUNC_NOOP           39)
88
89    ; For SSE/MMX support:
90    (UNSPEC_FIX_NOTRUNC          40)
91    (UNSPEC_MASKMOV              41)
92    (UNSPEC_MOVMSK               42)
93    (UNSPEC_MOVNT                43)
94    (UNSPEC_MOVU                 44)
95    (UNSPEC_RCP                  45)
96    (UNSPEC_RSQRT                46)
97    (UNSPEC_SFENCE               47)
98    (UNSPEC_PFRCP                49)
99    (UNSPEC_PFRCPIT1             40)
100    (UNSPEC_PFRCPIT2             41)
101    (UNSPEC_PFRSQRT              42)
102    (UNSPEC_PFRSQIT1             43)
103    (UNSPEC_MFENCE               44)
104    (UNSPEC_LFENCE               45)
105    (UNSPEC_PSADBW               46)
106    (UNSPEC_LDDQU                47)
107
108    ; Generic math support
109    (UNSPEC_COPYSIGN             50)
110    (UNSPEC_IEEE_MIN             51)     ; not commutative
111    (UNSPEC_IEEE_MAX             52)     ; not commutative
112
113    ; x87 Floating point
114    (UNSPEC_SIN                  60)
115    (UNSPEC_COS                  61)
116    (UNSPEC_FPATAN               62)
117    (UNSPEC_FYL2X                63)
118    (UNSPEC_FYL2XP1              64)
119    (UNSPEC_FRNDINT              65)
120    (UNSPEC_FIST                 66)
121    (UNSPEC_F2XM1                67)
122    (UNSPEC_TAN                  68)
123    (UNSPEC_FXAM                 69)
124
125    ; x87 Rounding
126    (UNSPEC_FRNDINT_FLOOR        70)
127    (UNSPEC_FRNDINT_CEIL         71)
128    (UNSPEC_FRNDINT_TRUNC        72)
129    (UNSPEC_FRNDINT_MASK_PM      73)
130    (UNSPEC_FIST_FLOOR           74)
131    (UNSPEC_FIST_CEIL            75)
132
133    ; x87 Double output FP
134    (UNSPEC_SINCOS_COS           80)
135    (UNSPEC_SINCOS_SIN           81)
136    (UNSPEC_XTRACT_FRACT         84)
137    (UNSPEC_XTRACT_EXP           85)
138    (UNSPEC_FSCALE_FRACT         86)
139    (UNSPEC_FSCALE_EXP           87)
140    (UNSPEC_FPREM_F              88)
141    (UNSPEC_FPREM_U              89)
142    (UNSPEC_FPREM1_F             90)
143    (UNSPEC_FPREM1_U             91)
144
145    (UNSPEC_C2_FLAG              95)
146
147    ; SSP patterns
148    (UNSPEC_SP_SET               100)
149    (UNSPEC_SP_TEST              101)
150    (UNSPEC_SP_TLS_SET           102)
151    (UNSPEC_SP_TLS_TEST          103)
152
153    ; SSSE3
154    (UNSPEC_PSHUFB               120)
155    (UNSPEC_PSIGN                121)
156    (UNSPEC_PALIGNR              122)
157
158    ; For SSE4A support
159    (UNSPEC_EXTRQI               130)
160    (UNSPEC_EXTRQ                131)
161    (UNSPEC_INSERTQI             132)
162    (UNSPEC_INSERTQ              133)
163
164    ; For SSE4.1 support
165    (UNSPEC_BLENDV               134)
166    (UNSPEC_INSERTPS             135)
167    (UNSPEC_DP                   136)
168    (UNSPEC_MOVNTDQA             137)
169    (UNSPEC_MPSADBW              138)
170    (UNSPEC_PHMINPOSUW           139)
171    (UNSPEC_PTEST                140)
172    (UNSPEC_ROUND                141)
173
174    ; For SSE4.2 support
175    (UNSPEC_CRC32                143)
176    (UNSPEC_PCMPESTR             144)
177    (UNSPEC_PCMPISTR             145)
178
179    ;; For SSE5
180    (UNSPEC_SSE5_INTRINSIC       150)
181    (UNSPEC_SSE5_UNSIGNED_CMP    151)
182    (UNSPEC_SSE5_TRUEFALSE       152)
183    (UNSPEC_SSE5_PERMUTE         153)
184    (UNSPEC_SSE5_ASHIFT          154)
185    (UNSPEC_SSE5_LSHIFT          155)
186    (UNSPEC_FRCZ                 156)
187    (UNSPEC_CVTPH2PS             157)
188    (UNSPEC_CVTPS2PH             158)
189   ])
190
191 (define_constants
192   [(UNSPECV_BLOCKAGE            0)
193    (UNSPECV_STACK_PROBE         1)
194    (UNSPECV_EMMS                2)
195    (UNSPECV_LDMXCSR             3)
196    (UNSPECV_STMXCSR             4)
197    (UNSPECV_FEMMS               5)
198    (UNSPECV_CLFLUSH             6)
199    (UNSPECV_ALIGN               7)
200    (UNSPECV_MONITOR             8)
201    (UNSPECV_MWAIT               9)
202    (UNSPECV_CMPXCHG_1           10)
203    (UNSPECV_CMPXCHG_2           11)
204    (UNSPECV_XCHG                12)
205    (UNSPECV_LOCK                13)
206    (UNSPECV_PROLOGUE_USE        14)
207   ])
208
209 ;; Constants to represent pcomtrue/pcomfalse variants
210 (define_constants
211   [(PCOM_FALSE                  0)
212    (PCOM_TRUE                   1)
213    (COM_FALSE_S                 2)
214    (COM_FALSE_P                 3)
215    (COM_TRUE_S                  4)
216    (COM_TRUE_P                  5)
217   ])
218
219 ;; Registers by name.
220 (define_constants
221   [(AX_REG                       0)
222    (DX_REG                       1)
223    (CX_REG                       2)
224    (SI_REG                       4)
225    (DI_REG                       5)
226    (BP_REG                       6)
227    (SP_REG                       7)
228    (FLAGS_REG                   17)
229    (FPSR_REG                    18)
230    (FPCR_REG                    19)
231    (R10_REG                     39)
232    (R11_REG                     40)
233   ])
234
235 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
236 ;; from i386.c.
237
238 ;; In C guard expressions, put expressions which may be compile-time
239 ;; constants first.  This allows for better optimization.  For
240 ;; example, write "TARGET_64BIT && reload_completed", not
241 ;; "reload_completed && TARGET_64BIT".
242
243 \f
244 ;; Processor type.  This attribute must exactly match the processor_type
245 ;; enumeration in i386.h.
246 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
247                     nocona,core2,generic32,generic64,amdfam10"
248   (const (symbol_ref "ix86_tune")))
249
250 ;; A basic instruction type.  Refinements due to arguments to be
251 ;; provided in other attributes.
252 (define_attr "type"
253   "other,multi,
254    alu,alu1,negnot,imov,imovx,lea,
255    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
256    icmp,test,ibr,setcc,icmov,
257    push,pop,call,callv,leave,
258    str,bitmanip,
259    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
260    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
261    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
262    ssemuladd,sse4arg,
263    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
264   (const_string "other"))
265
266 ;; Main data type used by the insn
267 (define_attr "mode"
268   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
269   (const_string "unknown"))
270
271 ;; The CPU unit operations uses.
272 (define_attr "unit" "integer,i387,sse,mmx,unknown"
273   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
274            (const_string "i387")
275          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
276                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
277                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
278            (const_string "sse")
279          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
280            (const_string "mmx")
281          (eq_attr "type" "other")
282            (const_string "unknown")]
283          (const_string "integer")))
284
285 ;; The (bounding maximum) length of an instruction immediate.
286 (define_attr "length_immediate" ""
287   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
288                           bitmanip")
289            (const_int 0)
290          (eq_attr "unit" "i387,sse,mmx")
291            (const_int 0)
292          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
293                           imul,icmp,push,pop")
294            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
295          (eq_attr "type" "imov,test")
296            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
297          (eq_attr "type" "call")
298            (if_then_else (match_operand 0 "constant_call_address_operand" "")
299              (const_int 4)
300              (const_int 0))
301          (eq_attr "type" "callv")
302            (if_then_else (match_operand 1 "constant_call_address_operand" "")
303              (const_int 4)
304              (const_int 0))
305          ;; We don't know the size before shorten_branches.  Expect
306          ;; the instruction to fit for better scheduling.
307          (eq_attr "type" "ibr")
308            (const_int 1)
309          ]
310          (symbol_ref "/* Update immediate_length and other attributes! */
311                       gcc_unreachable (),1")))
312
313 ;; The (bounding maximum) length of an instruction address.
314 (define_attr "length_address" ""
315   (cond [(eq_attr "type" "str,other,multi,fxch")
316            (const_int 0)
317          (and (eq_attr "type" "call")
318               (match_operand 0 "constant_call_address_operand" ""))
319              (const_int 0)
320          (and (eq_attr "type" "callv")
321               (match_operand 1 "constant_call_address_operand" ""))
322              (const_int 0)
323          ]
324          (symbol_ref "ix86_attr_length_address_default (insn)")))
325
326 ;; Set when length prefix is used.
327 (define_attr "prefix_data16" ""
328   (if_then_else (ior (eq_attr "mode" "HI")
329                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
330     (const_int 1)
331     (const_int 0)))
332
333 ;; Set when string REP prefix is used.
334 (define_attr "prefix_rep" ""
335   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
336     (const_int 1)
337     (const_int 0)))
338
339 ;; Set when 0f opcode prefix is used.
340 (define_attr "prefix_0f" ""
341   (if_then_else
342     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
343          (eq_attr "unit" "sse,mmx"))
344     (const_int 1)
345     (const_int 0)))
346
347 ;; Set when REX opcode prefix is used.
348 (define_attr "prefix_rex" ""
349   (cond [(and (eq_attr "mode" "DI")
350               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
351            (const_int 1)
352          (and (eq_attr "mode" "QI")
353               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
354                   (const_int 0)))
355            (const_int 1)
356          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
357              (const_int 0))
358            (const_int 1)
359         ]
360         (const_int 0)))
361
362 ;; There are also additional prefixes in SSSE3.
363 (define_attr "prefix_extra" "" (const_int 0))
364
365 ;; Set when modrm byte is used.
366 (define_attr "modrm" ""
367   (cond [(eq_attr "type" "str,leave")
368            (const_int 0)
369          (eq_attr "unit" "i387")
370            (const_int 0)
371          (and (eq_attr "type" "incdec")
372               (ior (match_operand:SI 1 "register_operand" "")
373                    (match_operand:HI 1 "register_operand" "")))
374            (const_int 0)
375          (and (eq_attr "type" "push")
376               (not (match_operand 1 "memory_operand" "")))
377            (const_int 0)
378          (and (eq_attr "type" "pop")
379               (not (match_operand 0 "memory_operand" "")))
380            (const_int 0)
381          (and (eq_attr "type" "imov")
382               (ior (and (match_operand 0 "register_operand" "")
383                         (match_operand 1 "immediate_operand" ""))
384                    (ior (and (match_operand 0 "ax_reg_operand" "")
385                              (match_operand 1 "memory_displacement_only_operand" ""))
386                         (and (match_operand 0 "memory_displacement_only_operand" "")
387                              (match_operand 1 "ax_reg_operand" "")))))
388            (const_int 0)
389          (and (eq_attr "type" "call")
390               (match_operand 0 "constant_call_address_operand" ""))
391              (const_int 0)
392          (and (eq_attr "type" "callv")
393               (match_operand 1 "constant_call_address_operand" ""))
394              (const_int 0)
395          ]
396          (const_int 1)))
397
398 ;; The (bounding maximum) length of an instruction in bytes.
399 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
400 ;; Later we may want to split them and compute proper length as for
401 ;; other insns.
402 (define_attr "length" ""
403   (cond [(eq_attr "type" "other,multi,fistp,frndint")
404            (const_int 16)
405          (eq_attr "type" "fcmp")
406            (const_int 4)
407          (eq_attr "unit" "i387")
408            (plus (const_int 2)
409                  (plus (attr "prefix_data16")
410                        (attr "length_address")))]
411          (plus (plus (attr "modrm")
412                      (plus (attr "prefix_0f")
413                            (plus (attr "prefix_rex")
414                                  (plus (attr "prefix_extra")
415                                        (const_int 1)))))
416                (plus (attr "prefix_rep")
417                      (plus (attr "prefix_data16")
418                            (plus (attr "length_immediate")
419                                  (attr "length_address")))))))
420
421 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
422 ;; `store' if there is a simple memory reference therein, or `unknown'
423 ;; if the instruction is complex.
424
425 (define_attr "memory" "none,load,store,both,unknown"
426   (cond [(eq_attr "type" "other,multi,str")
427            (const_string "unknown")
428          (eq_attr "type" "lea,fcmov,fpspc")
429            (const_string "none")
430          (eq_attr "type" "fistp,leave")
431            (const_string "both")
432          (eq_attr "type" "frndint")
433            (const_string "load")
434          (eq_attr "type" "push")
435            (if_then_else (match_operand 1 "memory_operand" "")
436              (const_string "both")
437              (const_string "store"))
438          (eq_attr "type" "pop")
439            (if_then_else (match_operand 0 "memory_operand" "")
440              (const_string "both")
441              (const_string "load"))
442          (eq_attr "type" "setcc")
443            (if_then_else (match_operand 0 "memory_operand" "")
444              (const_string "store")
445              (const_string "none"))
446          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
447            (if_then_else (ior (match_operand 0 "memory_operand" "")
448                               (match_operand 1 "memory_operand" ""))
449              (const_string "load")
450              (const_string "none"))
451          (eq_attr "type" "ibr")
452            (if_then_else (match_operand 0 "memory_operand" "")
453              (const_string "load")
454              (const_string "none"))
455          (eq_attr "type" "call")
456            (if_then_else (match_operand 0 "constant_call_address_operand" "")
457              (const_string "none")
458              (const_string "load"))
459          (eq_attr "type" "callv")
460            (if_then_else (match_operand 1 "constant_call_address_operand" "")
461              (const_string "none")
462              (const_string "load"))
463          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
464               (match_operand 1 "memory_operand" ""))
465            (const_string "both")
466          (and (match_operand 0 "memory_operand" "")
467               (match_operand 1 "memory_operand" ""))
468            (const_string "both")
469          (match_operand 0 "memory_operand" "")
470            (const_string "store")
471          (match_operand 1 "memory_operand" "")
472            (const_string "load")
473          (and (eq_attr "type"
474                  "!alu1,negnot,ishift1,
475                    imov,imovx,icmp,test,bitmanip,
476                    fmov,fcmp,fsgn,
477                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
478                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
479               (match_operand 2 "memory_operand" ""))
480            (const_string "load")
481          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
482               (match_operand 3 "memory_operand" ""))
483            (const_string "load")
484         ]
485         (const_string "none")))
486
487 ;; Indicates if an instruction has both an immediate and a displacement.
488
489 (define_attr "imm_disp" "false,true,unknown"
490   (cond [(eq_attr "type" "other,multi")
491            (const_string "unknown")
492          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
493               (and (match_operand 0 "memory_displacement_operand" "")
494                    (match_operand 1 "immediate_operand" "")))
495            (const_string "true")
496          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
497               (and (match_operand 0 "memory_displacement_operand" "")
498                    (match_operand 2 "immediate_operand" "")))
499            (const_string "true")
500         ]
501         (const_string "false")))
502
503 ;; Indicates if an FP operation has an integer source.
504
505 (define_attr "fp_int_src" "false,true"
506   (const_string "false"))
507
508 ;; Defines rounding mode of an FP operation.
509
510 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
511   (const_string "any"))
512
513 ;; Describe a user's asm statement.
514 (define_asm_attributes
515   [(set_attr "length" "128")
516    (set_attr "type" "multi")])
517
518 (define_code_iterator plusminus [plus minus])
519
520 ;; Base name for define_insn and insn mnemonic.
521 (define_code_attr addsub [(plus "add") (minus "sub")])
522
523 ;; Mark commutative operators as such in constraints.
524 (define_code_attr comm [(plus "%") (minus "")])
525
526 ;; All single word integer modes.
527 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
528
529 ;; Instruction suffix for integer modes.
530 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
531
532 ;; Register class for integer modes.
533 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
534
535 ;; Immediate operand constraint for integer modes.
536 (define_mode_attr i [(QI "i") (HI "i") (SI "i") (DI "e")])
537
538 ;; General operand predicate for integer modes.
539 (define_mode_attr general_operand
540         [(QI "general_operand")
541          (HI "general_operand")
542          (SI "general_operand")
543          (DI "x86_64_general_operand")])
544
545 ;; SSE and x87 SFmode and DFmode floating point modes
546 (define_mode_iterator MODEF [SF DF])
547
548 ;; All x87 floating point modes
549 (define_mode_iterator X87MODEF [SF DF XF])
550
551 ;; All integer modes handled by x87 fisttp operator.
552 (define_mode_iterator X87MODEI [HI SI DI])
553
554 ;; All integer modes handled by integer x87 operators.
555 (define_mode_iterator X87MODEI12 [HI SI])
556
557 ;; All integer modes handled by SSE cvtts?2si* operators.
558 (define_mode_iterator SSEMODEI24 [SI DI])
559
560 ;; SSE asm suffix for floating point modes
561 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
562
563 ;; SSE vector mode corresponding to a scalar mode
564 (define_mode_attr ssevecmode
565   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
566 \f
567 ;; Scheduling descriptions
568
569 (include "pentium.md")
570 (include "ppro.md")
571 (include "k6.md")
572 (include "athlon.md")
573 (include "geode.md")
574
575 \f
576 ;; Operand and operator predicates and constraints
577
578 (include "predicates.md")
579 (include "constraints.md")
580
581 \f
582 ;; Compare instructions.
583
584 ;; All compare insns have expanders that save the operands away without
585 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
586 ;; after the cmp) will actually emit the cmpM.
587
588 (define_expand "cmpti"
589   [(set (reg:CC FLAGS_REG)
590         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
591                     (match_operand:TI 1 "x86_64_general_operand" "")))]
592   "TARGET_64BIT"
593 {
594   if (MEM_P (operands[0]) && MEM_P (operands[1]))
595     operands[0] = force_reg (TImode, operands[0]);
596   ix86_compare_op0 = operands[0];
597   ix86_compare_op1 = operands[1];
598   DONE;
599 })
600
601 (define_expand "cmpdi"
602   [(set (reg:CC FLAGS_REG)
603         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
604                     (match_operand:DI 1 "x86_64_general_operand" "")))]
605   ""
606 {
607   if (MEM_P (operands[0]) && MEM_P (operands[1]))
608     operands[0] = force_reg (DImode, operands[0]);
609   ix86_compare_op0 = operands[0];
610   ix86_compare_op1 = operands[1];
611   DONE;
612 })
613
614 (define_expand "cmpsi"
615   [(set (reg:CC FLAGS_REG)
616         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
617                     (match_operand:SI 1 "general_operand" "")))]
618   ""
619 {
620   if (MEM_P (operands[0]) && MEM_P (operands[1]))
621     operands[0] = force_reg (SImode, operands[0]);
622   ix86_compare_op0 = operands[0];
623   ix86_compare_op1 = operands[1];
624   DONE;
625 })
626
627 (define_expand "cmphi"
628   [(set (reg:CC FLAGS_REG)
629         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
630                     (match_operand:HI 1 "general_operand" "")))]
631   ""
632 {
633   if (MEM_P (operands[0]) && MEM_P (operands[1]))
634     operands[0] = force_reg (HImode, operands[0]);
635   ix86_compare_op0 = operands[0];
636   ix86_compare_op1 = operands[1];
637   DONE;
638 })
639
640 (define_expand "cmpqi"
641   [(set (reg:CC FLAGS_REG)
642         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
643                     (match_operand:QI 1 "general_operand" "")))]
644   "TARGET_QIMODE_MATH"
645 {
646   if (MEM_P (operands[0]) && MEM_P (operands[1]))
647     operands[0] = force_reg (QImode, operands[0]);
648   ix86_compare_op0 = operands[0];
649   ix86_compare_op1 = operands[1];
650   DONE;
651 })
652
653 (define_insn "cmpdi_ccno_1_rex64"
654   [(set (reg FLAGS_REG)
655         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
656                  (match_operand:DI 1 "const0_operand" "n,n")))]
657   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
658   "@
659    test{q}\t%0, %0
660    cmp{q}\t{%1, %0|%0, %1}"
661   [(set_attr "type" "test,icmp")
662    (set_attr "length_immediate" "0,1")
663    (set_attr "mode" "DI")])
664
665 (define_insn "*cmpdi_minus_1_rex64"
666   [(set (reg FLAGS_REG)
667         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
668                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
669                  (const_int 0)))]
670   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
671   "cmp{q}\t{%1, %0|%0, %1}"
672   [(set_attr "type" "icmp")
673    (set_attr "mode" "DI")])
674
675 (define_expand "cmpdi_1_rex64"
676   [(set (reg:CC FLAGS_REG)
677         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
678                     (match_operand:DI 1 "general_operand" "")))]
679   "TARGET_64BIT"
680   "")
681
682 (define_insn "cmpdi_1_insn_rex64"
683   [(set (reg FLAGS_REG)
684         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
685                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
686   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
687   "cmp{q}\t{%1, %0|%0, %1}"
688   [(set_attr "type" "icmp")
689    (set_attr "mode" "DI")])
690
691
692 (define_insn "*cmpsi_ccno_1"
693   [(set (reg FLAGS_REG)
694         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
695                  (match_operand:SI 1 "const0_operand" "n,n")))]
696   "ix86_match_ccmode (insn, CCNOmode)"
697   "@
698    test{l}\t%0, %0
699    cmp{l}\t{%1, %0|%0, %1}"
700   [(set_attr "type" "test,icmp")
701    (set_attr "length_immediate" "0,1")
702    (set_attr "mode" "SI")])
703
704 (define_insn "*cmpsi_minus_1"
705   [(set (reg FLAGS_REG)
706         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
707                            (match_operand:SI 1 "general_operand" "ri,mr"))
708                  (const_int 0)))]
709   "ix86_match_ccmode (insn, CCGOCmode)"
710   "cmp{l}\t{%1, %0|%0, %1}"
711   [(set_attr "type" "icmp")
712    (set_attr "mode" "SI")])
713
714 (define_expand "cmpsi_1"
715   [(set (reg:CC FLAGS_REG)
716         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
717                     (match_operand:SI 1 "general_operand" "")))]
718   ""
719   "")
720
721 (define_insn "*cmpsi_1_insn"
722   [(set (reg FLAGS_REG)
723         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
724                  (match_operand:SI 1 "general_operand" "ri,mr")))]
725   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
726     && ix86_match_ccmode (insn, CCmode)"
727   "cmp{l}\t{%1, %0|%0, %1}"
728   [(set_attr "type" "icmp")
729    (set_attr "mode" "SI")])
730
731 (define_insn "*cmphi_ccno_1"
732   [(set (reg FLAGS_REG)
733         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
734                  (match_operand:HI 1 "const0_operand" "n,n")))]
735   "ix86_match_ccmode (insn, CCNOmode)"
736   "@
737    test{w}\t%0, %0
738    cmp{w}\t{%1, %0|%0, %1}"
739   [(set_attr "type" "test,icmp")
740    (set_attr "length_immediate" "0,1")
741    (set_attr "mode" "HI")])
742
743 (define_insn "*cmphi_minus_1"
744   [(set (reg FLAGS_REG)
745         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
746                            (match_operand:HI 1 "general_operand" "ri,mr"))
747                  (const_int 0)))]
748   "ix86_match_ccmode (insn, CCGOCmode)"
749   "cmp{w}\t{%1, %0|%0, %1}"
750   [(set_attr "type" "icmp")
751    (set_attr "mode" "HI")])
752
753 (define_insn "*cmphi_1"
754   [(set (reg FLAGS_REG)
755         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
756                  (match_operand:HI 1 "general_operand" "ri,mr")))]
757   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
758    && ix86_match_ccmode (insn, CCmode)"
759   "cmp{w}\t{%1, %0|%0, %1}"
760   [(set_attr "type" "icmp")
761    (set_attr "mode" "HI")])
762
763 (define_insn "*cmpqi_ccno_1"
764   [(set (reg FLAGS_REG)
765         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
766                  (match_operand:QI 1 "const0_operand" "n,n")))]
767   "ix86_match_ccmode (insn, CCNOmode)"
768   "@
769    test{b}\t%0, %0
770    cmp{b}\t{$0, %0|%0, 0}"
771   [(set_attr "type" "test,icmp")
772    (set_attr "length_immediate" "0,1")
773    (set_attr "mode" "QI")])
774
775 (define_insn "*cmpqi_1"
776   [(set (reg FLAGS_REG)
777         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
778                  (match_operand:QI 1 "general_operand" "qi,mq")))]
779   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
780     && ix86_match_ccmode (insn, CCmode)"
781   "cmp{b}\t{%1, %0|%0, %1}"
782   [(set_attr "type" "icmp")
783    (set_attr "mode" "QI")])
784
785 (define_insn "*cmpqi_minus_1"
786   [(set (reg FLAGS_REG)
787         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
788                            (match_operand:QI 1 "general_operand" "qi,mq"))
789                  (const_int 0)))]
790   "ix86_match_ccmode (insn, CCGOCmode)"
791   "cmp{b}\t{%1, %0|%0, %1}"
792   [(set_attr "type" "icmp")
793    (set_attr "mode" "QI")])
794
795 (define_insn "*cmpqi_ext_1"
796   [(set (reg FLAGS_REG)
797         (compare
798           (match_operand:QI 0 "general_operand" "Qm")
799           (subreg:QI
800             (zero_extract:SI
801               (match_operand 1 "ext_register_operand" "Q")
802               (const_int 8)
803               (const_int 8)) 0)))]
804   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
805   "cmp{b}\t{%h1, %0|%0, %h1}"
806   [(set_attr "type" "icmp")
807    (set_attr "mode" "QI")])
808
809 (define_insn "*cmpqi_ext_1_rex64"
810   [(set (reg FLAGS_REG)
811         (compare
812           (match_operand:QI 0 "register_operand" "Q")
813           (subreg:QI
814             (zero_extract:SI
815               (match_operand 1 "ext_register_operand" "Q")
816               (const_int 8)
817               (const_int 8)) 0)))]
818   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
819   "cmp{b}\t{%h1, %0|%0, %h1}"
820   [(set_attr "type" "icmp")
821    (set_attr "mode" "QI")])
822
823 (define_insn "*cmpqi_ext_2"
824   [(set (reg FLAGS_REG)
825         (compare
826           (subreg:QI
827             (zero_extract:SI
828               (match_operand 0 "ext_register_operand" "Q")
829               (const_int 8)
830               (const_int 8)) 0)
831           (match_operand:QI 1 "const0_operand" "n")))]
832   "ix86_match_ccmode (insn, CCNOmode)"
833   "test{b}\t%h0, %h0"
834   [(set_attr "type" "test")
835    (set_attr "length_immediate" "0")
836    (set_attr "mode" "QI")])
837
838 (define_expand "cmpqi_ext_3"
839   [(set (reg:CC FLAGS_REG)
840         (compare:CC
841           (subreg:QI
842             (zero_extract:SI
843               (match_operand 0 "ext_register_operand" "")
844               (const_int 8)
845               (const_int 8)) 0)
846           (match_operand:QI 1 "general_operand" "")))]
847   ""
848   "")
849
850 (define_insn "cmpqi_ext_3_insn"
851   [(set (reg FLAGS_REG)
852         (compare
853           (subreg:QI
854             (zero_extract:SI
855               (match_operand 0 "ext_register_operand" "Q")
856               (const_int 8)
857               (const_int 8)) 0)
858           (match_operand:QI 1 "general_operand" "Qmn")))]
859   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
860   "cmp{b}\t{%1, %h0|%h0, %1}"
861   [(set_attr "type" "icmp")
862    (set_attr "mode" "QI")])
863
864 (define_insn "cmpqi_ext_3_insn_rex64"
865   [(set (reg FLAGS_REG)
866         (compare
867           (subreg:QI
868             (zero_extract:SI
869               (match_operand 0 "ext_register_operand" "Q")
870               (const_int 8)
871               (const_int 8)) 0)
872           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
873   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
874   "cmp{b}\t{%1, %h0|%h0, %1}"
875   [(set_attr "type" "icmp")
876    (set_attr "mode" "QI")])
877
878 (define_insn "*cmpqi_ext_4"
879   [(set (reg FLAGS_REG)
880         (compare
881           (subreg:QI
882             (zero_extract:SI
883               (match_operand 0 "ext_register_operand" "Q")
884               (const_int 8)
885               (const_int 8)) 0)
886           (subreg:QI
887             (zero_extract:SI
888               (match_operand 1 "ext_register_operand" "Q")
889               (const_int 8)
890               (const_int 8)) 0)))]
891   "ix86_match_ccmode (insn, CCmode)"
892   "cmp{b}\t{%h1, %h0|%h0, %h1}"
893   [(set_attr "type" "icmp")
894    (set_attr "mode" "QI")])
895
896 ;; These implement float point compares.
897 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
898 ;; which would allow mix and match FP modes on the compares.  Which is what
899 ;; the old patterns did, but with many more of them.
900
901 (define_expand "cmpxf"
902   [(set (reg:CC FLAGS_REG)
903         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
904                     (match_operand:XF 1 "nonmemory_operand" "")))]
905   "TARGET_80387"
906 {
907   ix86_compare_op0 = operands[0];
908   ix86_compare_op1 = operands[1];
909   DONE;
910 })
911
912 (define_expand "cmp<mode>"
913   [(set (reg:CC FLAGS_REG)
914         (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
915                     (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
916   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
917 {
918   ix86_compare_op0 = operands[0];
919   ix86_compare_op1 = operands[1];
920   DONE;
921 })
922
923 ;; FP compares, step 1:
924 ;; Set the FP condition codes.
925 ;;
926 ;; CCFPmode     compare with exceptions
927 ;; CCFPUmode    compare with no exceptions
928
929 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
930 ;; used to manage the reg stack popping would not be preserved.
931
932 (define_insn "*cmpfp_0"
933   [(set (match_operand:HI 0 "register_operand" "=a")
934         (unspec:HI
935           [(compare:CCFP
936              (match_operand 1 "register_operand" "f")
937              (match_operand 2 "const0_operand" "X"))]
938         UNSPEC_FNSTSW))]
939   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
940    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
941   "* return output_fp_compare (insn, operands, 0, 0);"
942   [(set_attr "type" "multi")
943    (set_attr "unit" "i387")
944    (set (attr "mode")
945      (cond [(match_operand:SF 1 "" "")
946               (const_string "SF")
947             (match_operand:DF 1 "" "")
948               (const_string "DF")
949            ]
950            (const_string "XF")))])
951
952 (define_insn_and_split "*cmpfp_0_cc"
953   [(set (reg:CCFP FLAGS_REG)
954         (compare:CCFP
955           (match_operand 1 "register_operand" "f")
956           (match_operand 2 "const0_operand" "X")))
957    (clobber (match_operand:HI 0 "register_operand" "=a"))]
958   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
959    && TARGET_SAHF && !TARGET_CMOVE
960    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
961   "#"
962   "&& reload_completed"
963   [(set (match_dup 0)
964         (unspec:HI
965           [(compare:CCFP (match_dup 1)(match_dup 2))]
966         UNSPEC_FNSTSW))
967    (set (reg:CC FLAGS_REG)
968         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
969   ""
970   [(set_attr "type" "multi")
971    (set_attr "unit" "i387")
972    (set (attr "mode")
973      (cond [(match_operand:SF 1 "" "")
974               (const_string "SF")
975             (match_operand:DF 1 "" "")
976               (const_string "DF")
977            ]
978            (const_string "XF")))])
979
980 (define_insn "*cmpfp_xf"
981   [(set (match_operand:HI 0 "register_operand" "=a")
982         (unspec:HI
983           [(compare:CCFP
984              (match_operand:XF 1 "register_operand" "f")
985              (match_operand:XF 2 "register_operand" "f"))]
986           UNSPEC_FNSTSW))]
987   "TARGET_80387"
988   "* return output_fp_compare (insn, operands, 0, 0);"
989   [(set_attr "type" "multi")
990    (set_attr "unit" "i387")
991    (set_attr "mode" "XF")])
992
993 (define_insn_and_split "*cmpfp_xf_cc"
994   [(set (reg:CCFP FLAGS_REG)
995         (compare:CCFP
996           (match_operand:XF 1 "register_operand" "f")
997           (match_operand:XF 2 "register_operand" "f")))
998    (clobber (match_operand:HI 0 "register_operand" "=a"))]
999   "TARGET_80387
1000    && TARGET_SAHF && !TARGET_CMOVE"
1001   "#"
1002   "&& reload_completed"
1003   [(set (match_dup 0)
1004         (unspec:HI
1005           [(compare:CCFP (match_dup 1)(match_dup 2))]
1006         UNSPEC_FNSTSW))
1007    (set (reg:CC FLAGS_REG)
1008         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1009   ""
1010   [(set_attr "type" "multi")
1011    (set_attr "unit" "i387")
1012    (set_attr "mode" "XF")])
1013
1014 (define_insn "*cmpfp_<mode>"
1015   [(set (match_operand:HI 0 "register_operand" "=a")
1016         (unspec:HI
1017           [(compare:CCFP
1018              (match_operand:MODEF 1 "register_operand" "f")
1019              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1020           UNSPEC_FNSTSW))]
1021   "TARGET_80387"
1022   "* return output_fp_compare (insn, operands, 0, 0);"
1023   [(set_attr "type" "multi")
1024    (set_attr "unit" "i387")
1025    (set_attr "mode" "<MODE>")])
1026
1027 (define_insn_and_split "*cmpfp_<mode>_cc"
1028   [(set (reg:CCFP FLAGS_REG)
1029         (compare:CCFP
1030           (match_operand:MODEF 1 "register_operand" "f")
1031           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1032    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1033   "TARGET_80387
1034    && TARGET_SAHF && !TARGET_CMOVE"
1035   "#"
1036   "&& reload_completed"
1037   [(set (match_dup 0)
1038         (unspec:HI
1039           [(compare:CCFP (match_dup 1)(match_dup 2))]
1040         UNSPEC_FNSTSW))
1041    (set (reg:CC FLAGS_REG)
1042         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1043   ""
1044   [(set_attr "type" "multi")
1045    (set_attr "unit" "i387")
1046    (set_attr "mode" "<MODE>")])
1047
1048 (define_insn "*cmpfp_u"
1049   [(set (match_operand:HI 0 "register_operand" "=a")
1050         (unspec:HI
1051           [(compare:CCFPU
1052              (match_operand 1 "register_operand" "f")
1053              (match_operand 2 "register_operand" "f"))]
1054           UNSPEC_FNSTSW))]
1055   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1056    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1057   "* return output_fp_compare (insn, operands, 0, 1);"
1058   [(set_attr "type" "multi")
1059    (set_attr "unit" "i387")
1060    (set (attr "mode")
1061      (cond [(match_operand:SF 1 "" "")
1062               (const_string "SF")
1063             (match_operand:DF 1 "" "")
1064               (const_string "DF")
1065            ]
1066            (const_string "XF")))])
1067
1068 (define_insn_and_split "*cmpfp_u_cc"
1069   [(set (reg:CCFPU FLAGS_REG)
1070         (compare:CCFPU
1071           (match_operand 1 "register_operand" "f")
1072           (match_operand 2 "register_operand" "f")))
1073    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1074   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1075    && TARGET_SAHF && !TARGET_CMOVE
1076    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1077   "#"
1078   "&& reload_completed"
1079   [(set (match_dup 0)
1080         (unspec:HI
1081           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1082         UNSPEC_FNSTSW))
1083    (set (reg:CC FLAGS_REG)
1084         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1085   ""
1086   [(set_attr "type" "multi")
1087    (set_attr "unit" "i387")
1088    (set (attr "mode")
1089      (cond [(match_operand:SF 1 "" "")
1090               (const_string "SF")
1091             (match_operand:DF 1 "" "")
1092               (const_string "DF")
1093            ]
1094            (const_string "XF")))])
1095
1096 (define_insn "*cmpfp_<mode>"
1097   [(set (match_operand:HI 0 "register_operand" "=a")
1098         (unspec:HI
1099           [(compare:CCFP
1100              (match_operand 1 "register_operand" "f")
1101              (match_operator 3 "float_operator"
1102                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1103           UNSPEC_FNSTSW))]
1104   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1105    && TARGET_USE_<MODE>MODE_FIOP
1106    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1107   "* return output_fp_compare (insn, operands, 0, 0);"
1108   [(set_attr "type" "multi")
1109    (set_attr "unit" "i387")
1110    (set_attr "fp_int_src" "true")
1111    (set_attr "mode" "<MODE>")])
1112
1113 (define_insn_and_split "*cmpfp_<mode>_cc"
1114   [(set (reg:CCFP FLAGS_REG)
1115         (compare:CCFP
1116           (match_operand 1 "register_operand" "f")
1117           (match_operator 3 "float_operator"
1118             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1119    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1120   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1121    && TARGET_SAHF && !TARGET_CMOVE
1122    && TARGET_USE_<MODE>MODE_FIOP
1123    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1124   "#"
1125   "&& reload_completed"
1126   [(set (match_dup 0)
1127         (unspec:HI
1128           [(compare:CCFP
1129              (match_dup 1)
1130              (match_op_dup 3 [(match_dup 2)]))]
1131         UNSPEC_FNSTSW))
1132    (set (reg:CC FLAGS_REG)
1133         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1134   ""
1135   [(set_attr "type" "multi")
1136    (set_attr "unit" "i387")
1137    (set_attr "fp_int_src" "true")
1138    (set_attr "mode" "<MODE>")])
1139
1140 ;; FP compares, step 2
1141 ;; Move the fpsw to ax.
1142
1143 (define_insn "x86_fnstsw_1"
1144   [(set (match_operand:HI 0 "register_operand" "=a")
1145         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1146   "TARGET_80387"
1147   "fnstsw\t%0"
1148   [(set_attr "length" "2")
1149    (set_attr "mode" "SI")
1150    (set_attr "unit" "i387")])
1151
1152 ;; FP compares, step 3
1153 ;; Get ax into flags, general case.
1154
1155 (define_insn "x86_sahf_1"
1156   [(set (reg:CC FLAGS_REG)
1157         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1158                    UNSPEC_SAHF))]
1159   "TARGET_SAHF"
1160 {
1161 #ifdef HAVE_AS_IX86_SAHF
1162   return "sahf";
1163 #else
1164   return ".byte\t0x9e";
1165 #endif
1166 }
1167   [(set_attr "length" "1")
1168    (set_attr "athlon_decode" "vector")
1169    (set_attr "amdfam10_decode" "direct")
1170    (set_attr "mode" "SI")])
1171
1172 ;; Pentium Pro can do steps 1 through 3 in one go.
1173 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1174 (define_insn "*cmpfp_i_mixed"
1175   [(set (reg:CCFP FLAGS_REG)
1176         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1177                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1178   "TARGET_MIX_SSE_I387
1179    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1180    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1181   "* return output_fp_compare (insn, operands, 1, 0);"
1182   [(set_attr "type" "fcmp,ssecomi")
1183    (set (attr "mode")
1184      (if_then_else (match_operand:SF 1 "" "")
1185         (const_string "SF")
1186         (const_string "DF")))
1187    (set_attr "athlon_decode" "vector")
1188    (set_attr "amdfam10_decode" "direct")])
1189
1190 (define_insn "*cmpfp_i_sse"
1191   [(set (reg:CCFP FLAGS_REG)
1192         (compare:CCFP (match_operand 0 "register_operand" "x")
1193                       (match_operand 1 "nonimmediate_operand" "xm")))]
1194   "TARGET_SSE_MATH
1195    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1196    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1197   "* return output_fp_compare (insn, operands, 1, 0);"
1198   [(set_attr "type" "ssecomi")
1199    (set (attr "mode")
1200      (if_then_else (match_operand:SF 1 "" "")
1201         (const_string "SF")
1202         (const_string "DF")))
1203    (set_attr "athlon_decode" "vector")
1204    (set_attr "amdfam10_decode" "direct")])
1205
1206 (define_insn "*cmpfp_i_i387"
1207   [(set (reg:CCFP FLAGS_REG)
1208         (compare:CCFP (match_operand 0 "register_operand" "f")
1209                       (match_operand 1 "register_operand" "f")))]
1210   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1211    && TARGET_CMOVE
1212    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1213    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1214   "* return output_fp_compare (insn, operands, 1, 0);"
1215   [(set_attr "type" "fcmp")
1216    (set (attr "mode")
1217      (cond [(match_operand:SF 1 "" "")
1218               (const_string "SF")
1219             (match_operand:DF 1 "" "")
1220               (const_string "DF")
1221            ]
1222            (const_string "XF")))
1223    (set_attr "athlon_decode" "vector")
1224    (set_attr "amdfam10_decode" "direct")])
1225
1226 (define_insn "*cmpfp_iu_mixed"
1227   [(set (reg:CCFPU FLAGS_REG)
1228         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1229                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1230   "TARGET_MIX_SSE_I387
1231    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1232    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1233   "* return output_fp_compare (insn, operands, 1, 1);"
1234   [(set_attr "type" "fcmp,ssecomi")
1235    (set (attr "mode")
1236      (if_then_else (match_operand:SF 1 "" "")
1237         (const_string "SF")
1238         (const_string "DF")))
1239    (set_attr "athlon_decode" "vector")
1240    (set_attr "amdfam10_decode" "direct")])
1241
1242 (define_insn "*cmpfp_iu_sse"
1243   [(set (reg:CCFPU FLAGS_REG)
1244         (compare:CCFPU (match_operand 0 "register_operand" "x")
1245                        (match_operand 1 "nonimmediate_operand" "xm")))]
1246   "TARGET_SSE_MATH
1247    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1248    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1249   "* return output_fp_compare (insn, operands, 1, 1);"
1250   [(set_attr "type" "ssecomi")
1251    (set (attr "mode")
1252      (if_then_else (match_operand:SF 1 "" "")
1253         (const_string "SF")
1254         (const_string "DF")))
1255    (set_attr "athlon_decode" "vector")
1256    (set_attr "amdfam10_decode" "direct")])
1257
1258 (define_insn "*cmpfp_iu_387"
1259   [(set (reg:CCFPU FLAGS_REG)
1260         (compare:CCFPU (match_operand 0 "register_operand" "f")
1261                        (match_operand 1 "register_operand" "f")))]
1262   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1263    && TARGET_CMOVE
1264    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1265    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1266   "* return output_fp_compare (insn, operands, 1, 1);"
1267   [(set_attr "type" "fcmp")
1268    (set (attr "mode")
1269      (cond [(match_operand:SF 1 "" "")
1270               (const_string "SF")
1271             (match_operand:DF 1 "" "")
1272               (const_string "DF")
1273            ]
1274            (const_string "XF")))
1275    (set_attr "athlon_decode" "vector")
1276    (set_attr "amdfam10_decode" "direct")])
1277 \f
1278 ;; Move instructions.
1279
1280 ;; General case of fullword move.
1281
1282 (define_expand "movsi"
1283   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1284         (match_operand:SI 1 "general_operand" ""))]
1285   ""
1286   "ix86_expand_move (SImode, operands); DONE;")
1287
1288 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1289 ;; general_operand.
1290 ;;
1291 ;; %%% We don't use a post-inc memory reference because x86 is not a
1292 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1293 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1294 ;; targets without our curiosities, and it is just as easy to represent
1295 ;; this differently.
1296
1297 (define_insn "*pushsi2"
1298   [(set (match_operand:SI 0 "push_operand" "=<")
1299         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1300   "!TARGET_64BIT"
1301   "push{l}\t%1"
1302   [(set_attr "type" "push")
1303    (set_attr "mode" "SI")])
1304
1305 ;; For 64BIT abi we always round up to 8 bytes.
1306 (define_insn "*pushsi2_rex64"
1307   [(set (match_operand:SI 0 "push_operand" "=X")
1308         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1309   "TARGET_64BIT"
1310   "push{q}\t%q1"
1311   [(set_attr "type" "push")
1312    (set_attr "mode" "SI")])
1313
1314 (define_insn "*pushsi2_prologue"
1315   [(set (match_operand:SI 0 "push_operand" "=<")
1316         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1317    (clobber (mem:BLK (scratch)))]
1318   "!TARGET_64BIT"
1319   "push{l}\t%1"
1320   [(set_attr "type" "push")
1321    (set_attr "mode" "SI")])
1322
1323 (define_insn "*popsi1_epilogue"
1324   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1325         (mem:SI (reg:SI SP_REG)))
1326    (set (reg:SI SP_REG)
1327         (plus:SI (reg:SI SP_REG) (const_int 4)))
1328    (clobber (mem:BLK (scratch)))]
1329   "!TARGET_64BIT"
1330   "pop{l}\t%0"
1331   [(set_attr "type" "pop")
1332    (set_attr "mode" "SI")])
1333
1334 (define_insn "popsi1"
1335   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1336         (mem:SI (reg:SI SP_REG)))
1337    (set (reg:SI SP_REG)
1338         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1339   "!TARGET_64BIT"
1340   "pop{l}\t%0"
1341   [(set_attr "type" "pop")
1342    (set_attr "mode" "SI")])
1343
1344 (define_insn "*movsi_xor"
1345   [(set (match_operand:SI 0 "register_operand" "=r")
1346         (match_operand:SI 1 "const0_operand" "i"))
1347    (clobber (reg:CC FLAGS_REG))]
1348   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1349   "xor{l}\t%0, %0"
1350   [(set_attr "type" "alu1")
1351    (set_attr "mode" "SI")
1352    (set_attr "length_immediate" "0")])
1353
1354 (define_insn "*movsi_or"
1355   [(set (match_operand:SI 0 "register_operand" "=r")
1356         (match_operand:SI 1 "immediate_operand" "i"))
1357    (clobber (reg:CC FLAGS_REG))]
1358   "reload_completed
1359    && operands[1] == constm1_rtx
1360    && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1361 {
1362   operands[1] = constm1_rtx;
1363   return "or{l}\t{%1, %0|%0, %1}";
1364 }
1365   [(set_attr "type" "alu1")
1366    (set_attr "mode" "SI")
1367    (set_attr "length_immediate" "1")])
1368
1369 (define_insn "*movsi_1"
1370   [(set (match_operand:SI 0 "nonimmediate_operand"
1371                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1372         (match_operand:SI 1 "general_operand"
1373                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1374   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1375 {
1376   switch (get_attr_type (insn))
1377     {
1378     case TYPE_SSELOG1:
1379       if (get_attr_mode (insn) == MODE_TI)
1380         return "pxor\t%0, %0";
1381       return "xorps\t%0, %0";
1382
1383     case TYPE_SSEMOV:
1384       switch (get_attr_mode (insn))
1385         {
1386         case MODE_TI:
1387           return "movdqa\t{%1, %0|%0, %1}";
1388         case MODE_V4SF:
1389           return "movaps\t{%1, %0|%0, %1}";
1390         case MODE_SI:
1391           return "movd\t{%1, %0|%0, %1}";
1392         case MODE_SF:
1393           return "movss\t{%1, %0|%0, %1}";
1394         default:
1395           gcc_unreachable ();
1396         }
1397
1398     case TYPE_MMXADD:
1399       return "pxor\t%0, %0";
1400
1401     case TYPE_MMXMOV:
1402       if (get_attr_mode (insn) == MODE_DI)
1403         return "movq\t{%1, %0|%0, %1}";
1404       return "movd\t{%1, %0|%0, %1}";
1405
1406     case TYPE_LEA:
1407       return "lea{l}\t{%1, %0|%0, %1}";
1408
1409     default:
1410       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1411       return "mov{l}\t{%1, %0|%0, %1}";
1412     }
1413 }
1414   [(set (attr "type")
1415      (cond [(eq_attr "alternative" "2")
1416               (const_string "mmxadd")
1417             (eq_attr "alternative" "3,4,5")
1418               (const_string "mmxmov")
1419             (eq_attr "alternative" "6")
1420               (const_string "sselog1")
1421             (eq_attr "alternative" "7,8,9,10,11")
1422               (const_string "ssemov")
1423             (match_operand:DI 1 "pic_32bit_operand" "")
1424               (const_string "lea")
1425            ]
1426            (const_string "imov")))
1427    (set (attr "mode")
1428      (cond [(eq_attr "alternative" "2,3")
1429               (const_string "DI")
1430             (eq_attr "alternative" "6,7")
1431               (if_then_else
1432                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1433                 (const_string "V4SF")
1434                 (const_string "TI"))
1435             (and (eq_attr "alternative" "8,9,10,11")
1436                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1437               (const_string "SF")
1438            ]
1439            (const_string "SI")))])
1440
1441 ;; Stores and loads of ax to arbitrary constant address.
1442 ;; We fake an second form of instruction to force reload to load address
1443 ;; into register when rax is not available
1444 (define_insn "*movabssi_1_rex64"
1445   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1446         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1447   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1448   "@
1449    movabs{l}\t{%1, %P0|%P0, %1}
1450    mov{l}\t{%1, %a0|%a0, %1}"
1451   [(set_attr "type" "imov")
1452    (set_attr "modrm" "0,*")
1453    (set_attr "length_address" "8,0")
1454    (set_attr "length_immediate" "0,*")
1455    (set_attr "memory" "store")
1456    (set_attr "mode" "SI")])
1457
1458 (define_insn "*movabssi_2_rex64"
1459   [(set (match_operand:SI 0 "register_operand" "=a,r")
1460         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1461   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1462   "@
1463    movabs{l}\t{%P1, %0|%0, %P1}
1464    mov{l}\t{%a1, %0|%0, %a1}"
1465   [(set_attr "type" "imov")
1466    (set_attr "modrm" "0,*")
1467    (set_attr "length_address" "8,0")
1468    (set_attr "length_immediate" "0")
1469    (set_attr "memory" "load")
1470    (set_attr "mode" "SI")])
1471
1472 (define_insn "*swapsi"
1473   [(set (match_operand:SI 0 "register_operand" "+r")
1474         (match_operand:SI 1 "register_operand" "+r"))
1475    (set (match_dup 1)
1476         (match_dup 0))]
1477   ""
1478   "xchg{l}\t%1, %0"
1479   [(set_attr "type" "imov")
1480    (set_attr "mode" "SI")
1481    (set_attr "pent_pair" "np")
1482    (set_attr "athlon_decode" "vector")
1483    (set_attr "amdfam10_decode" "double")])
1484
1485 (define_expand "movhi"
1486   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1487         (match_operand:HI 1 "general_operand" ""))]
1488   ""
1489   "ix86_expand_move (HImode, operands); DONE;")
1490
1491 (define_insn "*pushhi2"
1492   [(set (match_operand:HI 0 "push_operand" "=X")
1493         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1494   "!TARGET_64BIT"
1495   "push{l}\t%k1"
1496   [(set_attr "type" "push")
1497    (set_attr "mode" "SI")])
1498
1499 ;; For 64BIT abi we always round up to 8 bytes.
1500 (define_insn "*pushhi2_rex64"
1501   [(set (match_operand:HI 0 "push_operand" "=X")
1502         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1503   "TARGET_64BIT"
1504   "push{q}\t%q1"
1505   [(set_attr "type" "push")
1506    (set_attr "mode" "DI")])
1507
1508 (define_insn "*movhi_1"
1509   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1510         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1511   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1512 {
1513   switch (get_attr_type (insn))
1514     {
1515     case TYPE_IMOVX:
1516       /* movzwl is faster than movw on p2 due to partial word stalls,
1517          though not as fast as an aligned movl.  */
1518       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1519     default:
1520       if (get_attr_mode (insn) == MODE_SI)
1521         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1522       else
1523         return "mov{w}\t{%1, %0|%0, %1}";
1524     }
1525 }
1526   [(set (attr "type")
1527      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1528               (const_string "imov")
1529             (and (eq_attr "alternative" "0")
1530                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1531                           (const_int 0))
1532                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1533                           (const_int 0))))
1534               (const_string "imov")
1535             (and (eq_attr "alternative" "1,2")
1536                  (match_operand:HI 1 "aligned_operand" ""))
1537               (const_string "imov")
1538             (and (ne (symbol_ref "TARGET_MOVX")
1539                      (const_int 0))
1540                  (eq_attr "alternative" "0,2"))
1541               (const_string "imovx")
1542            ]
1543            (const_string "imov")))
1544     (set (attr "mode")
1545       (cond [(eq_attr "type" "imovx")
1546                (const_string "SI")
1547              (and (eq_attr "alternative" "1,2")
1548                   (match_operand:HI 1 "aligned_operand" ""))
1549                (const_string "SI")
1550              (and (eq_attr "alternative" "0")
1551                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1552                            (const_int 0))
1553                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1554                            (const_int 0))))
1555                (const_string "SI")
1556             ]
1557             (const_string "HI")))])
1558
1559 ;; Stores and loads of ax to arbitrary constant address.
1560 ;; We fake an second form of instruction to force reload to load address
1561 ;; into register when rax is not available
1562 (define_insn "*movabshi_1_rex64"
1563   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1564         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1565   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1566   "@
1567    movabs{w}\t{%1, %P0|%P0, %1}
1568    mov{w}\t{%1, %a0|%a0, %1}"
1569   [(set_attr "type" "imov")
1570    (set_attr "modrm" "0,*")
1571    (set_attr "length_address" "8,0")
1572    (set_attr "length_immediate" "0,*")
1573    (set_attr "memory" "store")
1574    (set_attr "mode" "HI")])
1575
1576 (define_insn "*movabshi_2_rex64"
1577   [(set (match_operand:HI 0 "register_operand" "=a,r")
1578         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1579   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1580   "@
1581    movabs{w}\t{%P1, %0|%0, %P1}
1582    mov{w}\t{%a1, %0|%0, %a1}"
1583   [(set_attr "type" "imov")
1584    (set_attr "modrm" "0,*")
1585    (set_attr "length_address" "8,0")
1586    (set_attr "length_immediate" "0")
1587    (set_attr "memory" "load")
1588    (set_attr "mode" "HI")])
1589
1590 (define_insn "*swaphi_1"
1591   [(set (match_operand:HI 0 "register_operand" "+r")
1592         (match_operand:HI 1 "register_operand" "+r"))
1593    (set (match_dup 1)
1594         (match_dup 0))]
1595   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1596   "xchg{l}\t%k1, %k0"
1597   [(set_attr "type" "imov")
1598    (set_attr "mode" "SI")
1599    (set_attr "pent_pair" "np")
1600    (set_attr "athlon_decode" "vector")
1601    (set_attr "amdfam10_decode" "double")])
1602
1603 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1604 (define_insn "*swaphi_2"
1605   [(set (match_operand:HI 0 "register_operand" "+r")
1606         (match_operand:HI 1 "register_operand" "+r"))
1607    (set (match_dup 1)
1608         (match_dup 0))]
1609   "TARGET_PARTIAL_REG_STALL"
1610   "xchg{w}\t%1, %0"
1611   [(set_attr "type" "imov")
1612    (set_attr "mode" "HI")
1613    (set_attr "pent_pair" "np")
1614    (set_attr "athlon_decode" "vector")])
1615
1616 (define_expand "movstricthi"
1617   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1618         (match_operand:HI 1 "general_operand" ""))]
1619   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1620 {
1621   /* Don't generate memory->memory moves, go through a register */
1622   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1623     operands[1] = force_reg (HImode, operands[1]);
1624 })
1625
1626 (define_insn "*movstricthi_1"
1627   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1628         (match_operand:HI 1 "general_operand" "rn,m"))]
1629   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1630    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1631   "mov{w}\t{%1, %0|%0, %1}"
1632   [(set_attr "type" "imov")
1633    (set_attr "mode" "HI")])
1634
1635 (define_insn "*movstricthi_xor"
1636   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1637         (match_operand:HI 1 "const0_operand" "i"))
1638    (clobber (reg:CC FLAGS_REG))]
1639   "reload_completed
1640    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1641   "xor{w}\t%0, %0"
1642   [(set_attr "type" "alu1")
1643    (set_attr "mode" "HI")
1644    (set_attr "length_immediate" "0")])
1645
1646 (define_expand "movqi"
1647   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1648         (match_operand:QI 1 "general_operand" ""))]
1649   ""
1650   "ix86_expand_move (QImode, operands); DONE;")
1651
1652 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1653 ;; "push a byte".  But actually we use pushl, which has the effect
1654 ;; of rounding the amount pushed up to a word.
1655
1656 (define_insn "*pushqi2"
1657   [(set (match_operand:QI 0 "push_operand" "=X")
1658         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1659   "!TARGET_64BIT"
1660   "push{l}\t%k1"
1661   [(set_attr "type" "push")
1662    (set_attr "mode" "SI")])
1663
1664 ;; For 64BIT abi we always round up to 8 bytes.
1665 (define_insn "*pushqi2_rex64"
1666   [(set (match_operand:QI 0 "push_operand" "=X")
1667         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1668   "TARGET_64BIT"
1669   "push{q}\t%q1"
1670   [(set_attr "type" "push")
1671    (set_attr "mode" "DI")])
1672
1673 ;; Situation is quite tricky about when to choose full sized (SImode) move
1674 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1675 ;; partial register dependency machines (such as AMD Athlon), where QImode
1676 ;; moves issue extra dependency and for partial register stalls machines
1677 ;; that don't use QImode patterns (and QImode move cause stall on the next
1678 ;; instruction).
1679 ;;
1680 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1681 ;; register stall machines with, where we use QImode instructions, since
1682 ;; partial register stall can be caused there.  Then we use movzx.
1683 (define_insn "*movqi_1"
1684   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1685         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1686   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1687 {
1688   switch (get_attr_type (insn))
1689     {
1690     case TYPE_IMOVX:
1691       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1692       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1693     default:
1694       if (get_attr_mode (insn) == MODE_SI)
1695         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1696       else
1697         return "mov{b}\t{%1, %0|%0, %1}";
1698     }
1699 }
1700   [(set (attr "type")
1701      (cond [(and (eq_attr "alternative" "5")
1702                  (not (match_operand:QI 1 "aligned_operand" "")))
1703               (const_string "imovx")
1704             (ne (symbol_ref "optimize_size") (const_int 0))
1705               (const_string "imov")
1706             (and (eq_attr "alternative" "3")
1707                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1708                           (const_int 0))
1709                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1710                           (const_int 0))))
1711               (const_string "imov")
1712             (eq_attr "alternative" "3,5")
1713               (const_string "imovx")
1714             (and (ne (symbol_ref "TARGET_MOVX")
1715                      (const_int 0))
1716                  (eq_attr "alternative" "2"))
1717               (const_string "imovx")
1718            ]
1719            (const_string "imov")))
1720    (set (attr "mode")
1721       (cond [(eq_attr "alternative" "3,4,5")
1722                (const_string "SI")
1723              (eq_attr "alternative" "6")
1724                (const_string "QI")
1725              (eq_attr "type" "imovx")
1726                (const_string "SI")
1727              (and (eq_attr "type" "imov")
1728                   (and (eq_attr "alternative" "0,1")
1729                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1730                                 (const_int 0))
1731                             (and (eq (symbol_ref "optimize_size")
1732                                      (const_int 0))
1733                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1734                                      (const_int 0))))))
1735                (const_string "SI")
1736              ;; Avoid partial register stalls when not using QImode arithmetic
1737              (and (eq_attr "type" "imov")
1738                   (and (eq_attr "alternative" "0,1")
1739                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1740                                 (const_int 0))
1741                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1742                                 (const_int 0)))))
1743                (const_string "SI")
1744            ]
1745            (const_string "QI")))])
1746
1747 (define_expand "reload_outqi"
1748   [(parallel [(match_operand:QI 0 "" "=m")
1749               (match_operand:QI 1 "register_operand" "r")
1750               (match_operand:QI 2 "register_operand" "=&q")])]
1751   ""
1752 {
1753   rtx op0, op1, op2;
1754   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1755
1756   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1757   if (! q_regs_operand (op1, QImode))
1758     {
1759       emit_insn (gen_movqi (op2, op1));
1760       op1 = op2;
1761     }
1762   emit_insn (gen_movqi (op0, op1));
1763   DONE;
1764 })
1765
1766 (define_insn "*swapqi_1"
1767   [(set (match_operand:QI 0 "register_operand" "+r")
1768         (match_operand:QI 1 "register_operand" "+r"))
1769    (set (match_dup 1)
1770         (match_dup 0))]
1771   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1772   "xchg{l}\t%k1, %k0"
1773   [(set_attr "type" "imov")
1774    (set_attr "mode" "SI")
1775    (set_attr "pent_pair" "np")
1776    (set_attr "athlon_decode" "vector")
1777    (set_attr "amdfam10_decode" "vector")])
1778
1779 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1780 (define_insn "*swapqi_2"
1781   [(set (match_operand:QI 0 "register_operand" "+q")
1782         (match_operand:QI 1 "register_operand" "+q"))
1783    (set (match_dup 1)
1784         (match_dup 0))]
1785   "TARGET_PARTIAL_REG_STALL"
1786   "xchg{b}\t%1, %0"
1787   [(set_attr "type" "imov")
1788    (set_attr "mode" "QI")
1789    (set_attr "pent_pair" "np")
1790    (set_attr "athlon_decode" "vector")])
1791
1792 (define_expand "movstrictqi"
1793   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1794         (match_operand:QI 1 "general_operand" ""))]
1795   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1796 {
1797   /* Don't generate memory->memory moves, go through a register.  */
1798   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1799     operands[1] = force_reg (QImode, operands[1]);
1800 })
1801
1802 (define_insn "*movstrictqi_1"
1803   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1804         (match_operand:QI 1 "general_operand" "*qn,m"))]
1805   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1806    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1807   "mov{b}\t{%1, %0|%0, %1}"
1808   [(set_attr "type" "imov")
1809    (set_attr "mode" "QI")])
1810
1811 (define_insn "*movstrictqi_xor"
1812   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1813         (match_operand:QI 1 "const0_operand" "i"))
1814    (clobber (reg:CC FLAGS_REG))]
1815   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1816   "xor{b}\t%0, %0"
1817   [(set_attr "type" "alu1")
1818    (set_attr "mode" "QI")
1819    (set_attr "length_immediate" "0")])
1820
1821 (define_insn "*movsi_extv_1"
1822   [(set (match_operand:SI 0 "register_operand" "=R")
1823         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1824                          (const_int 8)
1825                          (const_int 8)))]
1826   ""
1827   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1828   [(set_attr "type" "imovx")
1829    (set_attr "mode" "SI")])
1830
1831 (define_insn "*movhi_extv_1"
1832   [(set (match_operand:HI 0 "register_operand" "=R")
1833         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1834                          (const_int 8)
1835                          (const_int 8)))]
1836   ""
1837   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1838   [(set_attr "type" "imovx")
1839    (set_attr "mode" "SI")])
1840
1841 (define_insn "*movqi_extv_1"
1842   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1843         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1844                          (const_int 8)
1845                          (const_int 8)))]
1846   "!TARGET_64BIT"
1847 {
1848   switch (get_attr_type (insn))
1849     {
1850     case TYPE_IMOVX:
1851       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1852     default:
1853       return "mov{b}\t{%h1, %0|%0, %h1}";
1854     }
1855 }
1856   [(set (attr "type")
1857      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1858                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1859                              (ne (symbol_ref "TARGET_MOVX")
1860                                  (const_int 0))))
1861         (const_string "imovx")
1862         (const_string "imov")))
1863    (set (attr "mode")
1864      (if_then_else (eq_attr "type" "imovx")
1865         (const_string "SI")
1866         (const_string "QI")))])
1867
1868 (define_insn "*movqi_extv_1_rex64"
1869   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1870         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1871                          (const_int 8)
1872                          (const_int 8)))]
1873   "TARGET_64BIT"
1874 {
1875   switch (get_attr_type (insn))
1876     {
1877     case TYPE_IMOVX:
1878       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1879     default:
1880       return "mov{b}\t{%h1, %0|%0, %h1}";
1881     }
1882 }
1883   [(set (attr "type")
1884      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1885                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1886                              (ne (symbol_ref "TARGET_MOVX")
1887                                  (const_int 0))))
1888         (const_string "imovx")
1889         (const_string "imov")))
1890    (set (attr "mode")
1891      (if_then_else (eq_attr "type" "imovx")
1892         (const_string "SI")
1893         (const_string "QI")))])
1894
1895 ;; Stores and loads of ax to arbitrary constant address.
1896 ;; We fake an second form of instruction to force reload to load address
1897 ;; into register when rax is not available
1898 (define_insn "*movabsqi_1_rex64"
1899   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1900         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1901   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1902   "@
1903    movabs{b}\t{%1, %P0|%P0, %1}
1904    mov{b}\t{%1, %a0|%a0, %1}"
1905   [(set_attr "type" "imov")
1906    (set_attr "modrm" "0,*")
1907    (set_attr "length_address" "8,0")
1908    (set_attr "length_immediate" "0,*")
1909    (set_attr "memory" "store")
1910    (set_attr "mode" "QI")])
1911
1912 (define_insn "*movabsqi_2_rex64"
1913   [(set (match_operand:QI 0 "register_operand" "=a,r")
1914         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1915   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1916   "@
1917    movabs{b}\t{%P1, %0|%0, %P1}
1918    mov{b}\t{%a1, %0|%0, %a1}"
1919   [(set_attr "type" "imov")
1920    (set_attr "modrm" "0,*")
1921    (set_attr "length_address" "8,0")
1922    (set_attr "length_immediate" "0")
1923    (set_attr "memory" "load")
1924    (set_attr "mode" "QI")])
1925
1926 (define_insn "*movdi_extzv_1"
1927   [(set (match_operand:DI 0 "register_operand" "=R")
1928         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1929                          (const_int 8)
1930                          (const_int 8)))]
1931   "TARGET_64BIT"
1932   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1933   [(set_attr "type" "imovx")
1934    (set_attr "mode" "DI")])
1935
1936 (define_insn "*movsi_extzv_1"
1937   [(set (match_operand:SI 0 "register_operand" "=R")
1938         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1939                          (const_int 8)
1940                          (const_int 8)))]
1941   ""
1942   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1943   [(set_attr "type" "imovx")
1944    (set_attr "mode" "SI")])
1945
1946 (define_insn "*movqi_extzv_2"
1947   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1948         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1949                                     (const_int 8)
1950                                     (const_int 8)) 0))]
1951   "!TARGET_64BIT"
1952 {
1953   switch (get_attr_type (insn))
1954     {
1955     case TYPE_IMOVX:
1956       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1957     default:
1958       return "mov{b}\t{%h1, %0|%0, %h1}";
1959     }
1960 }
1961   [(set (attr "type")
1962      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1963                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1964                              (ne (symbol_ref "TARGET_MOVX")
1965                                  (const_int 0))))
1966         (const_string "imovx")
1967         (const_string "imov")))
1968    (set (attr "mode")
1969      (if_then_else (eq_attr "type" "imovx")
1970         (const_string "SI")
1971         (const_string "QI")))])
1972
1973 (define_insn "*movqi_extzv_2_rex64"
1974   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1975         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1976                                     (const_int 8)
1977                                     (const_int 8)) 0))]
1978   "TARGET_64BIT"
1979 {
1980   switch (get_attr_type (insn))
1981     {
1982     case TYPE_IMOVX:
1983       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1984     default:
1985       return "mov{b}\t{%h1, %0|%0, %h1}";
1986     }
1987 }
1988   [(set (attr "type")
1989      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1990                         (ne (symbol_ref "TARGET_MOVX")
1991                             (const_int 0)))
1992         (const_string "imovx")
1993         (const_string "imov")))
1994    (set (attr "mode")
1995      (if_then_else (eq_attr "type" "imovx")
1996         (const_string "SI")
1997         (const_string "QI")))])
1998
1999 (define_insn "movsi_insv_1"
2000   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2001                          (const_int 8)
2002                          (const_int 8))
2003         (match_operand:SI 1 "general_operand" "Qmn"))]
2004   "!TARGET_64BIT"
2005   "mov{b}\t{%b1, %h0|%h0, %b1}"
2006   [(set_attr "type" "imov")
2007    (set_attr "mode" "QI")])
2008
2009 (define_insn "*movsi_insv_1_rex64"
2010   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2011                          (const_int 8)
2012                          (const_int 8))
2013         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2014   "TARGET_64BIT"
2015   "mov{b}\t{%b1, %h0|%h0, %b1}"
2016   [(set_attr "type" "imov")
2017    (set_attr "mode" "QI")])
2018
2019 (define_insn "movdi_insv_1_rex64"
2020   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2021                          (const_int 8)
2022                          (const_int 8))
2023         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2024   "TARGET_64BIT"
2025   "mov{b}\t{%b1, %h0|%h0, %b1}"
2026   [(set_attr "type" "imov")
2027    (set_attr "mode" "QI")])
2028
2029 (define_insn "*movqi_insv_2"
2030   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2031                          (const_int 8)
2032                          (const_int 8))
2033         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2034                      (const_int 8)))]
2035   ""
2036   "mov{b}\t{%h1, %h0|%h0, %h1}"
2037   [(set_attr "type" "imov")
2038    (set_attr "mode" "QI")])
2039
2040 (define_expand "movdi"
2041   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2042         (match_operand:DI 1 "general_operand" ""))]
2043   ""
2044   "ix86_expand_move (DImode, operands); DONE;")
2045
2046 (define_insn "*pushdi"
2047   [(set (match_operand:DI 0 "push_operand" "=<")
2048         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2049   "!TARGET_64BIT"
2050   "#")
2051
2052 (define_insn "*pushdi2_rex64"
2053   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2054         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2055   "TARGET_64BIT"
2056   "@
2057    push{q}\t%1
2058    #"
2059   [(set_attr "type" "push,multi")
2060    (set_attr "mode" "DI")])
2061
2062 ;; Convert impossible pushes of immediate to existing instructions.
2063 ;; First try to get scratch register and go through it.  In case this
2064 ;; fails, push sign extended lower part first and then overwrite
2065 ;; upper part by 32bit move.
2066 (define_peephole2
2067   [(match_scratch:DI 2 "r")
2068    (set (match_operand:DI 0 "push_operand" "")
2069         (match_operand:DI 1 "immediate_operand" ""))]
2070   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2071    && !x86_64_immediate_operand (operands[1], DImode)"
2072   [(set (match_dup 2) (match_dup 1))
2073    (set (match_dup 0) (match_dup 2))]
2074   "")
2075
2076 ;; We need to define this as both peepholer and splitter for case
2077 ;; peephole2 pass is not run.
2078 ;; "&& 1" is needed to keep it from matching the previous pattern.
2079 (define_peephole2
2080   [(set (match_operand:DI 0 "push_operand" "")
2081         (match_operand:DI 1 "immediate_operand" ""))]
2082   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2083    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2084   [(set (match_dup 0) (match_dup 1))
2085    (set (match_dup 2) (match_dup 3))]
2086   "split_di (operands + 1, 1, operands + 2, operands + 3);
2087    operands[1] = gen_lowpart (DImode, operands[2]);
2088    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2089                                                     GEN_INT (4)));
2090   ")
2091
2092 (define_split
2093   [(set (match_operand:DI 0 "push_operand" "")
2094         (match_operand:DI 1 "immediate_operand" ""))]
2095   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2096                     ? epilogue_completed : reload_completed)
2097    && !symbolic_operand (operands[1], DImode)
2098    && !x86_64_immediate_operand (operands[1], DImode)"
2099   [(set (match_dup 0) (match_dup 1))
2100    (set (match_dup 2) (match_dup 3))]
2101   "split_di (operands + 1, 1, operands + 2, operands + 3);
2102    operands[1] = gen_lowpart (DImode, operands[2]);
2103    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2104                                                     GEN_INT (4)));
2105   ")
2106
2107 (define_insn "*pushdi2_prologue_rex64"
2108   [(set (match_operand:DI 0 "push_operand" "=<")
2109         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2110    (clobber (mem:BLK (scratch)))]
2111   "TARGET_64BIT"
2112   "push{q}\t%1"
2113   [(set_attr "type" "push")
2114    (set_attr "mode" "DI")])
2115
2116 (define_insn "*popdi1_epilogue_rex64"
2117   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2118         (mem:DI (reg:DI SP_REG)))
2119    (set (reg:DI SP_REG)
2120         (plus:DI (reg:DI SP_REG) (const_int 8)))
2121    (clobber (mem:BLK (scratch)))]
2122   "TARGET_64BIT"
2123   "pop{q}\t%0"
2124   [(set_attr "type" "pop")
2125    (set_attr "mode" "DI")])
2126
2127 (define_insn "popdi1"
2128   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2129         (mem:DI (reg:DI SP_REG)))
2130    (set (reg:DI SP_REG)
2131         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2132   "TARGET_64BIT"
2133   "pop{q}\t%0"
2134   [(set_attr "type" "pop")
2135    (set_attr "mode" "DI")])
2136
2137 (define_insn "*movdi_xor_rex64"
2138   [(set (match_operand:DI 0 "register_operand" "=r")
2139         (match_operand:DI 1 "const0_operand" "i"))
2140    (clobber (reg:CC FLAGS_REG))]
2141   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2142    && reload_completed"
2143   "xor{l}\t%k0, %k0";
2144   [(set_attr "type" "alu1")
2145    (set_attr "mode" "SI")
2146    (set_attr "length_immediate" "0")])
2147
2148 (define_insn "*movdi_or_rex64"
2149   [(set (match_operand:DI 0 "register_operand" "=r")
2150         (match_operand:DI 1 "const_int_operand" "i"))
2151    (clobber (reg:CC FLAGS_REG))]
2152   "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2153    && reload_completed
2154    && operands[1] == constm1_rtx"
2155 {
2156   operands[1] = constm1_rtx;
2157   return "or{q}\t{%1, %0|%0, %1}";
2158 }
2159   [(set_attr "type" "alu1")
2160    (set_attr "mode" "DI")
2161    (set_attr "length_immediate" "1")])
2162
2163 (define_insn "*movdi_2"
2164   [(set (match_operand:DI 0 "nonimmediate_operand"
2165                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2166         (match_operand:DI 1 "general_operand"
2167                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2168   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2169   "@
2170    #
2171    #
2172    pxor\t%0, %0
2173    movq\t{%1, %0|%0, %1}
2174    movq\t{%1, %0|%0, %1}
2175    pxor\t%0, %0
2176    movq\t{%1, %0|%0, %1}
2177    movdqa\t{%1, %0|%0, %1}
2178    movq\t{%1, %0|%0, %1}
2179    xorps\t%0, %0
2180    movlps\t{%1, %0|%0, %1}
2181    movaps\t{%1, %0|%0, %1}
2182    movlps\t{%1, %0|%0, %1}"
2183   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2184    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2185
2186 (define_split
2187   [(set (match_operand:DI 0 "push_operand" "")
2188         (match_operand:DI 1 "general_operand" ""))]
2189   "!TARGET_64BIT && reload_completed
2190    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2191   [(const_int 0)]
2192   "ix86_split_long_move (operands); DONE;")
2193
2194 ;; %%% This multiword shite has got to go.
2195 (define_split
2196   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2197         (match_operand:DI 1 "general_operand" ""))]
2198   "!TARGET_64BIT && reload_completed
2199    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2200    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2201   [(const_int 0)]
2202   "ix86_split_long_move (operands); DONE;")
2203
2204 (define_insn "*movdi_1_rex64"
2205   [(set (match_operand:DI 0 "nonimmediate_operand"
2206           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2207         (match_operand:DI 1 "general_operand"
2208           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2209   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2210 {
2211   switch (get_attr_type (insn))
2212     {
2213     case TYPE_SSECVT:
2214       if (SSE_REG_P (operands[0]))
2215         return "movq2dq\t{%1, %0|%0, %1}";
2216       else
2217         return "movdq2q\t{%1, %0|%0, %1}";
2218
2219     case TYPE_SSEMOV:
2220       if (get_attr_mode (insn) == MODE_TI)
2221         return "movdqa\t{%1, %0|%0, %1}";
2222       /* FALLTHRU */
2223
2224     case TYPE_MMXMOV:
2225       /* Moves from and into integer register is done using movd
2226          opcode with REX prefix.  */
2227       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2228         return "movd\t{%1, %0|%0, %1}";
2229       return "movq\t{%1, %0|%0, %1}";
2230
2231     case TYPE_SSELOG1:
2232     case TYPE_MMXADD:
2233       return "pxor\t%0, %0";
2234
2235     case TYPE_MULTI:
2236       return "#";
2237
2238     case TYPE_LEA:
2239       return "lea{q}\t{%a1, %0|%0, %a1}";
2240
2241     default:
2242       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2243       if (get_attr_mode (insn) == MODE_SI)
2244         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2245       else if (which_alternative == 2)
2246         return "movabs{q}\t{%1, %0|%0, %1}";
2247       else
2248         return "mov{q}\t{%1, %0|%0, %1}";
2249     }
2250 }
2251   [(set (attr "type")
2252      (cond [(eq_attr "alternative" "5")
2253               (const_string "mmxadd")
2254             (eq_attr "alternative" "6,7,8,9,10")
2255               (const_string "mmxmov")
2256             (eq_attr "alternative" "11")
2257               (const_string "sselog1")
2258             (eq_attr "alternative" "12,13,14,15,16")
2259               (const_string "ssemov")
2260             (eq_attr "alternative" "17,18")
2261               (const_string "ssecvt")
2262             (eq_attr "alternative" "4")
2263               (const_string "multi")
2264             (match_operand:DI 1 "pic_32bit_operand" "")
2265               (const_string "lea")
2266            ]
2267            (const_string "imov")))
2268    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2269    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2270    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2271
2272 ;; Stores and loads of ax to arbitrary constant address.
2273 ;; We fake an second form of instruction to force reload to load address
2274 ;; into register when rax is not available
2275 (define_insn "*movabsdi_1_rex64"
2276   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2277         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2278   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2279   "@
2280    movabs{q}\t{%1, %P0|%P0, %1}
2281    mov{q}\t{%1, %a0|%a0, %1}"
2282   [(set_attr "type" "imov")
2283    (set_attr "modrm" "0,*")
2284    (set_attr "length_address" "8,0")
2285    (set_attr "length_immediate" "0,*")
2286    (set_attr "memory" "store")
2287    (set_attr "mode" "DI")])
2288
2289 (define_insn "*movabsdi_2_rex64"
2290   [(set (match_operand:DI 0 "register_operand" "=a,r")
2291         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2292   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2293   "@
2294    movabs{q}\t{%P1, %0|%0, %P1}
2295    mov{q}\t{%a1, %0|%0, %a1}"
2296   [(set_attr "type" "imov")
2297    (set_attr "modrm" "0,*")
2298    (set_attr "length_address" "8,0")
2299    (set_attr "length_immediate" "0")
2300    (set_attr "memory" "load")
2301    (set_attr "mode" "DI")])
2302
2303 ;; Convert impossible stores of immediate to existing instructions.
2304 ;; First try to get scratch register and go through it.  In case this
2305 ;; fails, move by 32bit parts.
2306 (define_peephole2
2307   [(match_scratch:DI 2 "r")
2308    (set (match_operand:DI 0 "memory_operand" "")
2309         (match_operand:DI 1 "immediate_operand" ""))]
2310   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2311    && !x86_64_immediate_operand (operands[1], DImode)"
2312   [(set (match_dup 2) (match_dup 1))
2313    (set (match_dup 0) (match_dup 2))]
2314   "")
2315
2316 ;; We need to define this as both peepholer and splitter for case
2317 ;; peephole2 pass is not run.
2318 ;; "&& 1" is needed to keep it from matching the previous pattern.
2319 (define_peephole2
2320   [(set (match_operand:DI 0 "memory_operand" "")
2321         (match_operand:DI 1 "immediate_operand" ""))]
2322   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2323    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2324   [(set (match_dup 2) (match_dup 3))
2325    (set (match_dup 4) (match_dup 5))]
2326   "split_di (operands, 2, operands + 2, operands + 4);")
2327
2328 (define_split
2329   [(set (match_operand:DI 0 "memory_operand" "")
2330         (match_operand:DI 1 "immediate_operand" ""))]
2331   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2332                     ? epilogue_completed : reload_completed)
2333    && !symbolic_operand (operands[1], DImode)
2334    && !x86_64_immediate_operand (operands[1], DImode)"
2335   [(set (match_dup 2) (match_dup 3))
2336    (set (match_dup 4) (match_dup 5))]
2337   "split_di (operands, 2, operands + 2, operands + 4);")
2338
2339 (define_insn "*swapdi_rex64"
2340   [(set (match_operand:DI 0 "register_operand" "+r")
2341         (match_operand:DI 1 "register_operand" "+r"))
2342    (set (match_dup 1)
2343         (match_dup 0))]
2344   "TARGET_64BIT"
2345   "xchg{q}\t%1, %0"
2346   [(set_attr "type" "imov")
2347    (set_attr "mode" "DI")
2348    (set_attr "pent_pair" "np")
2349    (set_attr "athlon_decode" "vector")
2350    (set_attr "amdfam10_decode" "double")])
2351
2352 (define_expand "movti"
2353   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2354         (match_operand:TI 1 "nonimmediate_operand" ""))]
2355   "TARGET_SSE || TARGET_64BIT"
2356 {
2357   if (TARGET_64BIT)
2358     ix86_expand_move (TImode, operands);
2359   else if (push_operand (operands[0], TImode))
2360     ix86_expand_push (TImode, operands[1]);
2361   else
2362     ix86_expand_vector_move (TImode, operands);
2363   DONE;
2364 })
2365
2366 (define_insn "*movti_internal"
2367   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2368         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2369   "TARGET_SSE && !TARGET_64BIT
2370    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2371 {
2372   switch (which_alternative)
2373     {
2374     case 0:
2375       if (get_attr_mode (insn) == MODE_V4SF)
2376         return "xorps\t%0, %0";
2377       else
2378         return "pxor\t%0, %0";
2379     case 1:
2380     case 2:
2381       if (get_attr_mode (insn) == MODE_V4SF)
2382         return "movaps\t{%1, %0|%0, %1}";
2383       else
2384         return "movdqa\t{%1, %0|%0, %1}";
2385     default:
2386       gcc_unreachable ();
2387     }
2388 }
2389   [(set_attr "type" "sselog1,ssemov,ssemov")
2390    (set (attr "mode")
2391         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2392                     (ne (symbol_ref "optimize_size") (const_int 0)))
2393                  (const_string "V4SF")
2394                (and (eq_attr "alternative" "2")
2395                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2396                         (const_int 0)))
2397                  (const_string "V4SF")]
2398               (const_string "TI")))])
2399
2400 (define_insn "*movti_rex64"
2401   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2402         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2403   "TARGET_64BIT
2404    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2405 {
2406   switch (which_alternative)
2407     {
2408     case 0:
2409     case 1:
2410       return "#";
2411     case 2:
2412       if (get_attr_mode (insn) == MODE_V4SF)
2413         return "xorps\t%0, %0";
2414       else
2415         return "pxor\t%0, %0";
2416     case 3:
2417     case 4:
2418       if (get_attr_mode (insn) == MODE_V4SF)
2419         return "movaps\t{%1, %0|%0, %1}";
2420       else
2421         return "movdqa\t{%1, %0|%0, %1}";
2422     default:
2423       gcc_unreachable ();
2424     }
2425 }
2426   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2427    (set (attr "mode")
2428         (cond [(eq_attr "alternative" "2,3")
2429                  (if_then_else
2430                    (ne (symbol_ref "optimize_size")
2431                        (const_int 0))
2432                    (const_string "V4SF")
2433                    (const_string "TI"))
2434                (eq_attr "alternative" "4")
2435                  (if_then_else
2436                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2437                             (const_int 0))
2438                         (ne (symbol_ref "optimize_size")
2439                             (const_int 0)))
2440                    (const_string "V4SF")
2441                    (const_string "TI"))]
2442                (const_string "DI")))])
2443
2444 (define_split
2445   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2446         (match_operand:TI 1 "general_operand" ""))]
2447   "reload_completed && !SSE_REG_P (operands[0])
2448    && !SSE_REG_P (operands[1])"
2449   [(const_int 0)]
2450   "ix86_split_long_move (operands); DONE;")
2451
2452 ;; This expands to what emit_move_complex would generate if we didn't
2453 ;; have a movti pattern.  Having this avoids problems with reload on
2454 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2455 ;; to have around all the time.
2456 (define_expand "movcdi"
2457   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2458         (match_operand:CDI 1 "general_operand" ""))]
2459   ""
2460 {
2461   if (push_operand (operands[0], CDImode))
2462     emit_move_complex_push (CDImode, operands[0], operands[1]);
2463   else
2464     emit_move_complex_parts (operands[0], operands[1]);
2465   DONE;
2466 })
2467
2468 (define_expand "movsf"
2469   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2470         (match_operand:SF 1 "general_operand" ""))]
2471   ""
2472   "ix86_expand_move (SFmode, operands); DONE;")
2473
2474 (define_insn "*pushsf"
2475   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2476         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2477   "!TARGET_64BIT"
2478 {
2479   /* Anything else should be already split before reg-stack.  */
2480   gcc_assert (which_alternative == 1);
2481   return "push{l}\t%1";
2482 }
2483   [(set_attr "type" "multi,push,multi")
2484    (set_attr "unit" "i387,*,*")
2485    (set_attr "mode" "SF,SI,SF")])
2486
2487 (define_insn "*pushsf_rex64"
2488   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2489         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2490   "TARGET_64BIT"
2491 {
2492   /* Anything else should be already split before reg-stack.  */
2493   gcc_assert (which_alternative == 1);
2494   return "push{q}\t%q1";
2495 }
2496   [(set_attr "type" "multi,push,multi")
2497    (set_attr "unit" "i387,*,*")
2498    (set_attr "mode" "SF,DI,SF")])
2499
2500 (define_split
2501   [(set (match_operand:SF 0 "push_operand" "")
2502         (match_operand:SF 1 "memory_operand" ""))]
2503   "reload_completed
2504    && MEM_P (operands[1])
2505    && (operands[2] = find_constant_src (insn))"
2506   [(set (match_dup 0)
2507         (match_dup 2))])
2508
2509
2510 ;; %%% Kill this when call knows how to work this out.
2511 (define_split
2512   [(set (match_operand:SF 0 "push_operand" "")
2513         (match_operand:SF 1 "any_fp_register_operand" ""))]
2514   "!TARGET_64BIT"
2515   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2516    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2517
2518 (define_split
2519   [(set (match_operand:SF 0 "push_operand" "")
2520         (match_operand:SF 1 "any_fp_register_operand" ""))]
2521   "TARGET_64BIT"
2522   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2523    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2524
2525 (define_insn "*movsf_1"
2526   [(set (match_operand:SF 0 "nonimmediate_operand"
2527           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2528         (match_operand:SF 1 "general_operand"
2529           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2530   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2531    && (reload_in_progress || reload_completed
2532        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2533        || (!TARGET_SSE_MATH && optimize_size
2534            && standard_80387_constant_p (operands[1]))
2535        || GET_CODE (operands[1]) != CONST_DOUBLE
2536        || memory_operand (operands[0], SFmode))"
2537 {
2538   switch (which_alternative)
2539     {
2540     case 0:
2541     case 1:
2542       return output_387_reg_move (insn, operands);
2543
2544     case 2:
2545       return standard_80387_constant_opcode (operands[1]);
2546
2547     case 3:
2548     case 4:
2549       return "mov{l}\t{%1, %0|%0, %1}";
2550     case 5:
2551       if (get_attr_mode (insn) == MODE_TI)
2552         return "pxor\t%0, %0";
2553       else
2554         return "xorps\t%0, %0";
2555     case 6:
2556       if (get_attr_mode (insn) == MODE_V4SF)
2557         return "movaps\t{%1, %0|%0, %1}";
2558       else
2559         return "movss\t{%1, %0|%0, %1}";
2560     case 7: case 8:
2561       return "movss\t{%1, %0|%0, %1}";
2562
2563     case 9: case 10:
2564     case 12: case 13: case 14: case 15:
2565       return "movd\t{%1, %0|%0, %1}";
2566
2567     case 11:
2568       return "movq\t{%1, %0|%0, %1}";
2569
2570     default:
2571       gcc_unreachable ();
2572     }
2573 }
2574   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2575    (set (attr "mode")
2576         (cond [(eq_attr "alternative" "3,4,9,10")
2577                  (const_string "SI")
2578                (eq_attr "alternative" "5")
2579                  (if_then_else
2580                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2581                                  (const_int 0))
2582                              (ne (symbol_ref "TARGET_SSE2")
2583                                  (const_int 0)))
2584                         (eq (symbol_ref "optimize_size")
2585                             (const_int 0)))
2586                    (const_string "TI")
2587                    (const_string "V4SF"))
2588                /* For architectures resolving dependencies on
2589                   whole SSE registers use APS move to break dependency
2590                   chains, otherwise use short move to avoid extra work.
2591
2592                   Do the same for architectures resolving dependencies on
2593                   the parts.  While in DF mode it is better to always handle
2594                   just register parts, the SF mode is different due to lack
2595                   of instructions to load just part of the register.  It is
2596                   better to maintain the whole registers in single format
2597                   to avoid problems on using packed logical operations.  */
2598                (eq_attr "alternative" "6")
2599                  (if_then_else
2600                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2601                             (const_int 0))
2602                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2603                             (const_int 0)))
2604                    (const_string "V4SF")
2605                    (const_string "SF"))
2606                (eq_attr "alternative" "11")
2607                  (const_string "DI")]
2608                (const_string "SF")))])
2609
2610 (define_insn "*swapsf"
2611   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2612         (match_operand:SF 1 "fp_register_operand" "+f"))
2613    (set (match_dup 1)
2614         (match_dup 0))]
2615   "reload_completed || TARGET_80387"
2616 {
2617   if (STACK_TOP_P (operands[0]))
2618     return "fxch\t%1";
2619   else
2620     return "fxch\t%0";
2621 }
2622   [(set_attr "type" "fxch")
2623    (set_attr "mode" "SF")])
2624
2625 (define_expand "movdf"
2626   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2627         (match_operand:DF 1 "general_operand" ""))]
2628   ""
2629   "ix86_expand_move (DFmode, operands); DONE;")
2630
2631 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2632 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2633 ;; On the average, pushdf using integers can be still shorter.  Allow this
2634 ;; pattern for optimize_size too.
2635
2636 (define_insn "*pushdf_nointeger"
2637   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2638         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2639   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2640 {
2641   /* This insn should be already split before reg-stack.  */
2642   gcc_unreachable ();
2643 }
2644   [(set_attr "type" "multi")
2645    (set_attr "unit" "i387,*,*,*")
2646    (set_attr "mode" "DF,SI,SI,DF")])
2647
2648 (define_insn "*pushdf_integer"
2649   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2650         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2651   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2652 {
2653   /* This insn should be already split before reg-stack.  */
2654   gcc_unreachable ();
2655 }
2656   [(set_attr "type" "multi")
2657    (set_attr "unit" "i387,*,*")
2658    (set_attr "mode" "DF,SI,DF")])
2659
2660 ;; %%% Kill this when call knows how to work this out.
2661 (define_split
2662   [(set (match_operand:DF 0 "push_operand" "")
2663         (match_operand:DF 1 "any_fp_register_operand" ""))]
2664   "!TARGET_64BIT && reload_completed"
2665   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2666    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2667   "")
2668
2669 (define_split
2670   [(set (match_operand:DF 0 "push_operand" "")
2671         (match_operand:DF 1 "any_fp_register_operand" ""))]
2672   "TARGET_64BIT && reload_completed"
2673   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2674    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2675   "")
2676
2677 (define_split
2678   [(set (match_operand:DF 0 "push_operand" "")
2679         (match_operand:DF 1 "general_operand" ""))]
2680   "reload_completed"
2681   [(const_int 0)]
2682   "ix86_split_long_move (operands); DONE;")
2683
2684 ;; Moving is usually shorter when only FP registers are used. This separate
2685 ;; movdf pattern avoids the use of integer registers for FP operations
2686 ;; when optimizing for size.
2687
2688 (define_insn "*movdf_nointeger"
2689   [(set (match_operand:DF 0 "nonimmediate_operand"
2690                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2691         (match_operand:DF 1 "general_operand"
2692                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
2693   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2694    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2695    && (reload_in_progress || reload_completed
2696        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2697        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2698            && !memory_operand (operands[0], DFmode)
2699            && standard_80387_constant_p (operands[1]))
2700        || GET_CODE (operands[1]) != CONST_DOUBLE
2701        || ((optimize_size
2702             || !TARGET_MEMORY_MISMATCH_STALL
2703             || reload_in_progress || reload_completed)
2704            && memory_operand (operands[0], DFmode)))"
2705 {
2706   switch (which_alternative)
2707     {
2708     case 0:
2709     case 1:
2710       return output_387_reg_move (insn, operands);
2711
2712     case 2:
2713       return standard_80387_constant_opcode (operands[1]);
2714
2715     case 3:
2716     case 4:
2717       return "#";
2718     case 5:
2719       switch (get_attr_mode (insn))
2720         {
2721         case MODE_V4SF:
2722           return "xorps\t%0, %0";
2723         case MODE_V2DF:
2724           return "xorpd\t%0, %0";
2725         case MODE_TI:
2726           return "pxor\t%0, %0";
2727         default:
2728           gcc_unreachable ();
2729         }
2730     case 6:
2731     case 7:
2732     case 8:
2733       switch (get_attr_mode (insn))
2734         {
2735         case MODE_V4SF:
2736           return "movaps\t{%1, %0|%0, %1}";
2737         case MODE_V2DF:
2738           return "movapd\t{%1, %0|%0, %1}";
2739         case MODE_TI:
2740           return "movdqa\t{%1, %0|%0, %1}";
2741         case MODE_DI:
2742           return "movq\t{%1, %0|%0, %1}";
2743         case MODE_DF:
2744           return "movsd\t{%1, %0|%0, %1}";
2745         case MODE_V1DF:
2746           return "movlpd\t{%1, %0|%0, %1}";
2747         case MODE_V2SF:
2748           return "movlps\t{%1, %0|%0, %1}";
2749         default:
2750           gcc_unreachable ();
2751         }
2752
2753     default:
2754       gcc_unreachable ();
2755     }
2756 }
2757   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2758    (set (attr "mode")
2759         (cond [(eq_attr "alternative" "0,1,2")
2760                  (const_string "DF")
2761                (eq_attr "alternative" "3,4")
2762                  (const_string "SI")
2763
2764                /* For SSE1, we have many fewer alternatives.  */
2765                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2766                  (cond [(eq_attr "alternative" "5,6")
2767                           (const_string "V4SF")
2768                        ]
2769                    (const_string "V2SF"))
2770
2771                /* xorps is one byte shorter.  */
2772                (eq_attr "alternative" "5")
2773                  (cond [(ne (symbol_ref "optimize_size")
2774                             (const_int 0))
2775                           (const_string "V4SF")
2776                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2777                             (const_int 0))
2778                           (const_string "TI")
2779                        ]
2780                        (const_string "V2DF"))
2781
2782                /* For architectures resolving dependencies on
2783                   whole SSE registers use APD move to break dependency
2784                   chains, otherwise use short move to avoid extra work.
2785
2786                   movaps encodes one byte shorter.  */
2787                (eq_attr "alternative" "6")
2788                  (cond
2789                    [(ne (symbol_ref "optimize_size")
2790                         (const_int 0))
2791                       (const_string "V4SF")
2792                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2793                         (const_int 0))
2794                       (const_string "V2DF")
2795                    ]
2796                    (const_string "DF"))
2797                /* For architectures resolving dependencies on register
2798                   parts we may avoid extra work to zero out upper part
2799                   of register.  */
2800                (eq_attr "alternative" "7")
2801                  (if_then_else
2802                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2803                        (const_int 0))
2804                    (const_string "V1DF")
2805                    (const_string "DF"))
2806               ]
2807               (const_string "DF")))])
2808
2809 (define_insn "*movdf_integer_rex64"
2810   [(set (match_operand:DF 0 "nonimmediate_operand"
2811                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2812         (match_operand:DF 1 "general_operand"
2813                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2814   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2815    && (reload_in_progress || reload_completed
2816        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2817        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2818            && standard_80387_constant_p (operands[1]))
2819        || GET_CODE (operands[1]) != CONST_DOUBLE
2820        || memory_operand (operands[0], DFmode))"
2821 {
2822   switch (which_alternative)
2823     {
2824     case 0:
2825     case 1:
2826       return output_387_reg_move (insn, operands);
2827
2828     case 2:
2829       return standard_80387_constant_opcode (operands[1]);
2830
2831     case 3:
2832     case 4:
2833       return "#";
2834
2835     case 5:
2836       switch (get_attr_mode (insn))
2837         {
2838         case MODE_V4SF:
2839           return "xorps\t%0, %0";
2840         case MODE_V2DF:
2841           return "xorpd\t%0, %0";
2842         case MODE_TI:
2843           return "pxor\t%0, %0";
2844         default:
2845           gcc_unreachable ();
2846         }
2847     case 6:
2848     case 7:
2849     case 8:
2850       switch (get_attr_mode (insn))
2851         {
2852         case MODE_V4SF:
2853           return "movaps\t{%1, %0|%0, %1}";
2854         case MODE_V2DF:
2855           return "movapd\t{%1, %0|%0, %1}";
2856         case MODE_TI:
2857           return "movdqa\t{%1, %0|%0, %1}";
2858         case MODE_DI:
2859           return "movq\t{%1, %0|%0, %1}";
2860         case MODE_DF:
2861           return "movsd\t{%1, %0|%0, %1}";
2862         case MODE_V1DF:
2863           return "movlpd\t{%1, %0|%0, %1}";
2864         case MODE_V2SF:
2865           return "movlps\t{%1, %0|%0, %1}";
2866         default:
2867           gcc_unreachable ();
2868         }
2869
2870     case 9:
2871     case 10:
2872       return "movd\t{%1, %0|%0, %1}";
2873
2874     default:
2875       gcc_unreachable();
2876     }
2877 }
2878   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2879    (set (attr "mode")
2880         (cond [(eq_attr "alternative" "0,1,2")
2881                  (const_string "DF")
2882                (eq_attr "alternative" "3,4,9,10")
2883                  (const_string "DI")
2884
2885                /* For SSE1, we have many fewer alternatives.  */
2886                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2887                  (cond [(eq_attr "alternative" "5,6")
2888                           (const_string "V4SF")
2889                        ]
2890                    (const_string "V2SF"))
2891
2892                /* xorps is one byte shorter.  */
2893                (eq_attr "alternative" "5")
2894                  (cond [(ne (symbol_ref "optimize_size")
2895                             (const_int 0))
2896                           (const_string "V4SF")
2897                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2898                             (const_int 0))
2899                           (const_string "TI")
2900                        ]
2901                        (const_string "V2DF"))
2902
2903                /* For architectures resolving dependencies on
2904                   whole SSE registers use APD move to break dependency
2905                   chains, otherwise use short move to avoid extra work.
2906
2907                   movaps encodes one byte shorter.  */
2908                (eq_attr "alternative" "6")
2909                  (cond
2910                    [(ne (symbol_ref "optimize_size")
2911                         (const_int 0))
2912                       (const_string "V4SF")
2913                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2914                         (const_int 0))
2915                       (const_string "V2DF")
2916                    ]
2917                    (const_string "DF"))
2918                /* For architectures resolving dependencies on register
2919                   parts we may avoid extra work to zero out upper part
2920                   of register.  */
2921                (eq_attr "alternative" "7")
2922                  (if_then_else
2923                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2924                        (const_int 0))
2925                    (const_string "V1DF")
2926                    (const_string "DF"))
2927               ]
2928               (const_string "DF")))])
2929
2930 (define_insn "*movdf_integer"
2931   [(set (match_operand:DF 0 "nonimmediate_operand"
2932                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
2933         (match_operand:DF 1 "general_operand"
2934                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
2935   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2936    && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2937    && (reload_in_progress || reload_completed
2938        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2939        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2940            && standard_80387_constant_p (operands[1]))
2941        || GET_CODE (operands[1]) != CONST_DOUBLE
2942        || memory_operand (operands[0], DFmode))"
2943 {
2944   switch (which_alternative)
2945     {
2946     case 0:
2947     case 1:
2948       return output_387_reg_move (insn, operands);
2949
2950     case 2:
2951       return standard_80387_constant_opcode (operands[1]);
2952
2953     case 3:
2954     case 4:
2955       return "#";
2956
2957     case 5:
2958       switch (get_attr_mode (insn))
2959         {
2960         case MODE_V4SF:
2961           return "xorps\t%0, %0";
2962         case MODE_V2DF:
2963           return "xorpd\t%0, %0";
2964         case MODE_TI:
2965           return "pxor\t%0, %0";
2966         default:
2967           gcc_unreachable ();
2968         }
2969     case 6:
2970     case 7:
2971     case 8:
2972       switch (get_attr_mode (insn))
2973         {
2974         case MODE_V4SF:
2975           return "movaps\t{%1, %0|%0, %1}";
2976         case MODE_V2DF:
2977           return "movapd\t{%1, %0|%0, %1}";
2978         case MODE_TI:
2979           return "movdqa\t{%1, %0|%0, %1}";
2980         case MODE_DI:
2981           return "movq\t{%1, %0|%0, %1}";
2982         case MODE_DF:
2983           return "movsd\t{%1, %0|%0, %1}";
2984         case MODE_V1DF:
2985           return "movlpd\t{%1, %0|%0, %1}";
2986         case MODE_V2SF:
2987           return "movlps\t{%1, %0|%0, %1}";
2988         default:
2989           gcc_unreachable ();
2990         }
2991
2992     default:
2993       gcc_unreachable();
2994     }
2995 }
2996   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2997    (set (attr "mode")
2998         (cond [(eq_attr "alternative" "0,1,2")
2999                  (const_string "DF")
3000                (eq_attr "alternative" "3,4")
3001                  (const_string "SI")
3002
3003                /* For SSE1, we have many fewer alternatives.  */
3004                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3005                  (cond [(eq_attr "alternative" "5,6")
3006                           (const_string "V4SF")
3007                        ]
3008                    (const_string "V2SF"))
3009
3010                /* xorps is one byte shorter.  */
3011                (eq_attr "alternative" "5")
3012                  (cond [(ne (symbol_ref "optimize_size")
3013                             (const_int 0))
3014                           (const_string "V4SF")
3015                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3016                             (const_int 0))
3017                           (const_string "TI")
3018                        ]
3019                        (const_string "V2DF"))
3020
3021                /* For architectures resolving dependencies on
3022                   whole SSE registers use APD move to break dependency
3023                   chains, otherwise use short move to avoid extra work.
3024
3025                   movaps encodes one byte shorter.  */
3026                (eq_attr "alternative" "6")
3027                  (cond
3028                    [(ne (symbol_ref "optimize_size")
3029                         (const_int 0))
3030                       (const_string "V4SF")
3031                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3032                         (const_int 0))
3033                       (const_string "V2DF")
3034                    ]
3035                    (const_string "DF"))
3036                /* For architectures resolving dependencies on register
3037                   parts we may avoid extra work to zero out upper part
3038                   of register.  */
3039                (eq_attr "alternative" "7")
3040                  (if_then_else
3041                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3042                        (const_int 0))
3043                    (const_string "V1DF")
3044                    (const_string "DF"))
3045               ]
3046               (const_string "DF")))])
3047
3048 (define_split
3049   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3050         (match_operand:DF 1 "general_operand" ""))]
3051   "reload_completed
3052    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3053    && ! (ANY_FP_REG_P (operands[0]) ||
3054          (GET_CODE (operands[0]) == SUBREG
3055           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3056    && ! (ANY_FP_REG_P (operands[1]) ||
3057          (GET_CODE (operands[1]) == SUBREG
3058           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3059   [(const_int 0)]
3060   "ix86_split_long_move (operands); DONE;")
3061
3062 (define_insn "*swapdf"
3063   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3064         (match_operand:DF 1 "fp_register_operand" "+f"))
3065    (set (match_dup 1)
3066         (match_dup 0))]
3067   "reload_completed || TARGET_80387"
3068 {
3069   if (STACK_TOP_P (operands[0]))
3070     return "fxch\t%1";
3071   else
3072     return "fxch\t%0";
3073 }
3074   [(set_attr "type" "fxch")
3075    (set_attr "mode" "DF")])
3076
3077 (define_expand "movxf"
3078   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3079         (match_operand:XF 1 "general_operand" ""))]
3080   ""
3081   "ix86_expand_move (XFmode, operands); DONE;")
3082
3083 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3084 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3085 ;; Pushing using integer instructions is longer except for constants
3086 ;; and direct memory references.
3087 ;; (assuming that any given constant is pushed only once, but this ought to be
3088 ;;  handled elsewhere).
3089
3090 (define_insn "*pushxf_nointeger"
3091   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3092         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3093   "optimize_size"
3094 {
3095   /* This insn should be already split before reg-stack.  */
3096   gcc_unreachable ();
3097 }
3098   [(set_attr "type" "multi")
3099    (set_attr "unit" "i387,*,*")
3100    (set_attr "mode" "XF,SI,SI")])
3101
3102 (define_insn "*pushxf_integer"
3103   [(set (match_operand:XF 0 "push_operand" "=<,<")
3104         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3105   "!optimize_size"
3106 {
3107   /* This insn should be already split before reg-stack.  */
3108   gcc_unreachable ();
3109 }
3110   [(set_attr "type" "multi")
3111    (set_attr "unit" "i387,*")
3112    (set_attr "mode" "XF,SI")])
3113
3114 (define_split
3115   [(set (match_operand 0 "push_operand" "")
3116         (match_operand 1 "general_operand" ""))]
3117   "reload_completed
3118    && (GET_MODE (operands[0]) == XFmode
3119        || GET_MODE (operands[0]) == DFmode)
3120    && !ANY_FP_REG_P (operands[1])"
3121   [(const_int 0)]
3122   "ix86_split_long_move (operands); DONE;")
3123
3124 (define_split
3125   [(set (match_operand:XF 0 "push_operand" "")
3126         (match_operand:XF 1 "any_fp_register_operand" ""))]
3127   "!TARGET_64BIT"
3128   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3129    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
3130   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3131
3132 (define_split
3133   [(set (match_operand:XF 0 "push_operand" "")
3134         (match_operand:XF 1 "any_fp_register_operand" ""))]
3135   "TARGET_64BIT"
3136   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3137    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
3138   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3139
3140 ;; Do not use integer registers when optimizing for size
3141 (define_insn "*movxf_nointeger"
3142   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3143         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3144   "optimize_size
3145    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3146    && (reload_in_progress || reload_completed
3147        || (optimize_size && standard_80387_constant_p (operands[1]))
3148        || GET_CODE (operands[1]) != CONST_DOUBLE
3149        || memory_operand (operands[0], XFmode))"
3150 {
3151   switch (which_alternative)
3152     {
3153     case 0:
3154     case 1:
3155       return output_387_reg_move (insn, operands);
3156
3157     case 2:
3158       return standard_80387_constant_opcode (operands[1]);
3159
3160     case 3: case 4:
3161       return "#";
3162     default:
3163       gcc_unreachable ();
3164     }
3165 }
3166   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3167    (set_attr "mode" "XF,XF,XF,SI,SI")])
3168
3169 (define_insn "*movxf_integer"
3170   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3171         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3172   "!optimize_size
3173    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3174    && (reload_in_progress || reload_completed
3175        || (optimize_size && standard_80387_constant_p (operands[1]))
3176        || GET_CODE (operands[1]) != CONST_DOUBLE
3177        || memory_operand (operands[0], XFmode))"
3178 {
3179   switch (which_alternative)
3180     {
3181     case 0:
3182     case 1:
3183       return output_387_reg_move (insn, operands);
3184
3185     case 2:
3186       return standard_80387_constant_opcode (operands[1]);
3187
3188     case 3: case 4:
3189       return "#";
3190
3191     default:
3192       gcc_unreachable ();
3193     }
3194 }
3195   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3196    (set_attr "mode" "XF,XF,XF,SI,SI")])
3197
3198 (define_expand "movtf"
3199   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3200         (match_operand:TF 1 "nonimmediate_operand" ""))]
3201   "TARGET_64BIT"
3202 {
3203   ix86_expand_move (TFmode, operands);
3204   DONE;
3205 })
3206
3207 (define_insn "*movtf_internal"
3208   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3209         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3210   "TARGET_64BIT
3211    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3212 {
3213   switch (which_alternative)
3214     {
3215     case 0:
3216     case 1:
3217       if (get_attr_mode (insn) == MODE_V4SF)
3218         return "movaps\t{%1, %0|%0, %1}";
3219       else
3220         return "movdqa\t{%1, %0|%0, %1}";
3221     case 2:
3222       if (get_attr_mode (insn) == MODE_V4SF)
3223         return "xorps\t%0, %0";
3224       else
3225         return "pxor\t%0, %0";
3226     case 3:
3227     case 4:
3228         return "#";
3229     default:
3230       gcc_unreachable ();
3231     }
3232 }
3233   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3234    (set (attr "mode")
3235         (cond [(eq_attr "alternative" "0,2")
3236                  (if_then_else
3237                    (ne (symbol_ref "optimize_size")
3238                        (const_int 0))
3239                    (const_string "V4SF")
3240                    (const_string "TI"))
3241                (eq_attr "alternative" "1")
3242                  (if_then_else
3243                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3244                             (const_int 0))
3245                         (ne (symbol_ref "optimize_size")
3246                             (const_int 0)))
3247                    (const_string "V4SF")
3248                    (const_string "TI"))]
3249                (const_string "DI")))])
3250
3251 (define_split
3252   [(set (match_operand 0 "nonimmediate_operand" "")
3253         (match_operand 1 "general_operand" ""))]
3254   "reload_completed
3255    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3256    && GET_MODE (operands[0]) == XFmode
3257    && ! (ANY_FP_REG_P (operands[0]) ||
3258          (GET_CODE (operands[0]) == SUBREG
3259           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3260    && ! (ANY_FP_REG_P (operands[1]) ||
3261          (GET_CODE (operands[1]) == SUBREG
3262           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3263   [(const_int 0)]
3264   "ix86_split_long_move (operands); DONE;")
3265
3266 (define_split
3267   [(set (match_operand 0 "register_operand" "")
3268         (match_operand 1 "memory_operand" ""))]
3269   "reload_completed
3270    && MEM_P (operands[1])
3271    && (GET_MODE (operands[0]) == TFmode
3272        || GET_MODE (operands[0]) == XFmode
3273        || GET_MODE (operands[0]) == SFmode
3274        || GET_MODE (operands[0]) == DFmode)
3275    && (operands[2] = find_constant_src (insn))"
3276   [(set (match_dup 0) (match_dup 2))]
3277 {
3278   rtx c = operands[2];
3279   rtx r = operands[0];
3280
3281   if (GET_CODE (r) == SUBREG)
3282     r = SUBREG_REG (r);
3283
3284   if (SSE_REG_P (r))
3285     {
3286       if (!standard_sse_constant_p (c))
3287         FAIL;
3288     }
3289   else if (FP_REG_P (r))
3290     {
3291       if (!standard_80387_constant_p (c))
3292         FAIL;
3293     }
3294   else if (MMX_REG_P (r))
3295     FAIL;
3296 })
3297
3298 (define_split
3299   [(set (match_operand 0 "register_operand" "")
3300         (float_extend (match_operand 1 "memory_operand" "")))]
3301   "reload_completed
3302    && MEM_P (operands[1])
3303    && (GET_MODE (operands[0]) == TFmode
3304        || GET_MODE (operands[0]) == XFmode
3305        || GET_MODE (operands[0]) == SFmode
3306        || GET_MODE (operands[0]) == DFmode)
3307    && (operands[2] = find_constant_src (insn))"
3308   [(set (match_dup 0) (match_dup 2))]
3309 {
3310   rtx c = operands[2];
3311   rtx r = operands[0];
3312
3313   if (GET_CODE (r) == SUBREG)
3314     r = SUBREG_REG (r);
3315
3316   if (SSE_REG_P (r))
3317     {
3318       if (!standard_sse_constant_p (c))
3319         FAIL;
3320     }
3321   else if (FP_REG_P (r))
3322     {
3323       if (!standard_80387_constant_p (c))
3324         FAIL;
3325     }
3326   else if (MMX_REG_P (r))
3327     FAIL;
3328 })
3329
3330 (define_insn "swapxf"
3331   [(set (match_operand:XF 0 "register_operand" "+f")
3332         (match_operand:XF 1 "register_operand" "+f"))
3333    (set (match_dup 1)
3334         (match_dup 0))]
3335   "TARGET_80387"
3336 {
3337   if (STACK_TOP_P (operands[0]))
3338     return "fxch\t%1";
3339   else
3340     return "fxch\t%0";
3341 }
3342   [(set_attr "type" "fxch")
3343    (set_attr "mode" "XF")])
3344
3345 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3346 (define_split
3347   [(set (match_operand:X87MODEF 0 "register_operand" "")
3348         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3349   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3350    && (standard_80387_constant_p (operands[1]) == 8
3351        || standard_80387_constant_p (operands[1]) == 9)"
3352   [(set (match_dup 0)(match_dup 1))
3353    (set (match_dup 0)
3354         (neg:X87MODEF (match_dup 0)))]
3355 {
3356   REAL_VALUE_TYPE r;
3357
3358   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3359   if (real_isnegzero (&r))
3360     operands[1] = CONST0_RTX (<MODE>mode);
3361   else
3362     operands[1] = CONST1_RTX (<MODE>mode);
3363 })
3364
3365 (define_split
3366   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3367         (match_operand:TF 1 "general_operand" ""))]
3368   "reload_completed
3369    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3370   [(const_int 0)]
3371   "ix86_split_long_move (operands); DONE;")
3372 \f
3373 ;; Zero extension instructions
3374
3375 (define_expand "zero_extendhisi2"
3376   [(set (match_operand:SI 0 "register_operand" "")
3377      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3378   ""
3379 {
3380   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3381     {
3382       operands[1] = force_reg (HImode, operands[1]);
3383       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3384       DONE;
3385     }
3386 })
3387
3388 (define_insn "zero_extendhisi2_and"
3389   [(set (match_operand:SI 0 "register_operand" "=r")
3390      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3391    (clobber (reg:CC FLAGS_REG))]
3392   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3393   "#"
3394   [(set_attr "type" "alu1")
3395    (set_attr "mode" "SI")])
3396
3397 (define_split
3398   [(set (match_operand:SI 0 "register_operand" "")
3399         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3400    (clobber (reg:CC FLAGS_REG))]
3401   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3402   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3403               (clobber (reg:CC FLAGS_REG))])]
3404   "")
3405
3406 (define_insn "*zero_extendhisi2_movzwl"
3407   [(set (match_operand:SI 0 "register_operand" "=r")
3408      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3409   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3410   "movz{wl|x}\t{%1, %0|%0, %1}"
3411   [(set_attr "type" "imovx")
3412    (set_attr "mode" "SI")])
3413
3414 (define_expand "zero_extendqihi2"
3415   [(parallel
3416     [(set (match_operand:HI 0 "register_operand" "")
3417        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3418      (clobber (reg:CC FLAGS_REG))])]
3419   ""
3420   "")
3421
3422 (define_insn "*zero_extendqihi2_and"
3423   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3424      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3425    (clobber (reg:CC FLAGS_REG))]
3426   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3427   "#"
3428   [(set_attr "type" "alu1")
3429    (set_attr "mode" "HI")])
3430
3431 (define_insn "*zero_extendqihi2_movzbw_and"
3432   [(set (match_operand:HI 0 "register_operand" "=r,r")
3433      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3434    (clobber (reg:CC FLAGS_REG))]
3435   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3436   "#"
3437   [(set_attr "type" "imovx,alu1")
3438    (set_attr "mode" "HI")])
3439
3440 ; zero extend to SImode here to avoid partial register stalls
3441 (define_insn "*zero_extendqihi2_movzbl"
3442   [(set (match_operand:HI 0 "register_operand" "=r")
3443      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3444   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3445   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3446   [(set_attr "type" "imovx")
3447    (set_attr "mode" "SI")])
3448
3449 ;; For the movzbw case strip only the clobber
3450 (define_split
3451   [(set (match_operand:HI 0 "register_operand" "")
3452         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3453    (clobber (reg:CC FLAGS_REG))]
3454   "reload_completed
3455    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3456    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3457   [(set (match_operand:HI 0 "register_operand" "")
3458         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3459
3460 ;; When source and destination does not overlap, clear destination
3461 ;; first and then do the movb
3462 (define_split
3463   [(set (match_operand:HI 0 "register_operand" "")
3464         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3465    (clobber (reg:CC FLAGS_REG))]
3466   "reload_completed
3467    && ANY_QI_REG_P (operands[0])
3468    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3469    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3470   [(set (match_dup 0) (const_int 0))
3471    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3472   "operands[2] = gen_lowpart (QImode, operands[0]);")
3473
3474 ;; Rest is handled by single and.
3475 (define_split
3476   [(set (match_operand:HI 0 "register_operand" "")
3477         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3478    (clobber (reg:CC FLAGS_REG))]
3479   "reload_completed
3480    && true_regnum (operands[0]) == true_regnum (operands[1])"
3481   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3482               (clobber (reg:CC FLAGS_REG))])]
3483   "")
3484
3485 (define_expand "zero_extendqisi2"
3486   [(parallel
3487     [(set (match_operand:SI 0 "register_operand" "")
3488        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3489      (clobber (reg:CC FLAGS_REG))])]
3490   ""
3491   "")
3492
3493 (define_insn "*zero_extendqisi2_and"
3494   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3495      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3496    (clobber (reg:CC FLAGS_REG))]
3497   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3498   "#"
3499   [(set_attr "type" "alu1")
3500    (set_attr "mode" "SI")])
3501
3502 (define_insn "*zero_extendqisi2_movzbw_and"
3503   [(set (match_operand:SI 0 "register_operand" "=r,r")
3504      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3505    (clobber (reg:CC FLAGS_REG))]
3506   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3507   "#"
3508   [(set_attr "type" "imovx,alu1")
3509    (set_attr "mode" "SI")])
3510
3511 (define_insn "*zero_extendqisi2_movzbw"
3512   [(set (match_operand:SI 0 "register_operand" "=r")
3513      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3514   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3515   "movz{bl|x}\t{%1, %0|%0, %1}"
3516   [(set_attr "type" "imovx")
3517    (set_attr "mode" "SI")])
3518
3519 ;; For the movzbl case strip only the clobber
3520 (define_split
3521   [(set (match_operand:SI 0 "register_operand" "")
3522         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3523    (clobber (reg:CC FLAGS_REG))]
3524   "reload_completed
3525    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3526    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3527   [(set (match_dup 0)
3528         (zero_extend:SI (match_dup 1)))])
3529
3530 ;; When source and destination does not overlap, clear destination
3531 ;; first and then do the movb
3532 (define_split
3533   [(set (match_operand:SI 0 "register_operand" "")
3534         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3535    (clobber (reg:CC FLAGS_REG))]
3536   "reload_completed
3537    && ANY_QI_REG_P (operands[0])
3538    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3539    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3540    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3541   [(set (match_dup 0) (const_int 0))
3542    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3543   "operands[2] = gen_lowpart (QImode, operands[0]);")
3544
3545 ;; Rest is handled by single and.
3546 (define_split
3547   [(set (match_operand:SI 0 "register_operand" "")
3548         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3549    (clobber (reg:CC FLAGS_REG))]
3550   "reload_completed
3551    && true_regnum (operands[0]) == true_regnum (operands[1])"
3552   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3553               (clobber (reg:CC FLAGS_REG))])]
3554   "")
3555
3556 ;; %%% Kill me once multi-word ops are sane.
3557 (define_expand "zero_extendsidi2"
3558   [(set (match_operand:DI 0 "register_operand" "")
3559      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3560   ""
3561 {
3562   if (!TARGET_64BIT)
3563     {
3564       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3565       DONE;
3566     }
3567 })
3568
3569 (define_insn "zero_extendsidi2_32"
3570   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3571         (zero_extend:DI
3572          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3573    (clobber (reg:CC FLAGS_REG))]
3574   "!TARGET_64BIT"
3575   "@
3576    #
3577    #
3578    #
3579    movd\t{%1, %0|%0, %1}
3580    movd\t{%1, %0|%0, %1}
3581    movd\t{%1, %0|%0, %1}
3582    movd\t{%1, %0|%0, %1}"
3583   [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3584    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3585
3586 (define_insn "zero_extendsidi2_rex64"
3587   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3588      (zero_extend:DI
3589        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3590   "TARGET_64BIT"
3591   "@
3592    mov\t{%k1, %k0|%k0, %k1}
3593    #
3594    movd\t{%1, %0|%0, %1}
3595    movd\t{%1, %0|%0, %1}
3596    movd\t{%1, %0|%0, %1}
3597    movd\t{%1, %0|%0, %1}"
3598   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3599    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3600
3601 (define_split
3602   [(set (match_operand:DI 0 "memory_operand" "")
3603      (zero_extend:DI (match_dup 0)))]
3604   "TARGET_64BIT"
3605   [(set (match_dup 4) (const_int 0))]
3606   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3607
3608 (define_split
3609   [(set (match_operand:DI 0 "register_operand" "")
3610         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3611    (clobber (reg:CC FLAGS_REG))]
3612   "!TARGET_64BIT && reload_completed
3613    && true_regnum (operands[0]) == true_regnum (operands[1])"
3614   [(set (match_dup 4) (const_int 0))]
3615   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3616
3617 (define_split
3618   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3619         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3620    (clobber (reg:CC FLAGS_REG))]
3621   "!TARGET_64BIT && reload_completed
3622    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3623   [(set (match_dup 3) (match_dup 1))
3624    (set (match_dup 4) (const_int 0))]
3625   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3626
3627 (define_insn "zero_extendhidi2"
3628   [(set (match_operand:DI 0 "register_operand" "=r")
3629      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3630   "TARGET_64BIT"
3631   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3632   [(set_attr "type" "imovx")
3633    (set_attr "mode" "DI")])
3634
3635 (define_insn "zero_extendqidi2"
3636   [(set (match_operand:DI 0 "register_operand" "=r")
3637      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3638   "TARGET_64BIT"
3639   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3640   [(set_attr "type" "imovx")
3641    (set_attr "mode" "DI")])
3642 \f
3643 ;; Sign extension instructions
3644
3645 (define_expand "extendsidi2"
3646   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3647                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3648               (clobber (reg:CC FLAGS_REG))
3649               (clobber (match_scratch:SI 2 ""))])]
3650   ""
3651 {
3652   if (TARGET_64BIT)
3653     {
3654       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3655       DONE;
3656     }
3657 })
3658
3659 (define_insn "*extendsidi2_1"
3660   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3661         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3662    (clobber (reg:CC FLAGS_REG))
3663    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3664   "!TARGET_64BIT"
3665   "#")
3666
3667 (define_insn "extendsidi2_rex64"
3668   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3669         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3670   "TARGET_64BIT"
3671   "@
3672    {cltq|cdqe}
3673    movs{lq|x}\t{%1,%0|%0, %1}"
3674   [(set_attr "type" "imovx")
3675    (set_attr "mode" "DI")
3676    (set_attr "prefix_0f" "0")
3677    (set_attr "modrm" "0,1")])
3678
3679 (define_insn "extendhidi2"
3680   [(set (match_operand:DI 0 "register_operand" "=r")
3681         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3682   "TARGET_64BIT"
3683   "movs{wq|x}\t{%1,%0|%0, %1}"
3684   [(set_attr "type" "imovx")
3685    (set_attr "mode" "DI")])
3686
3687 (define_insn "extendqidi2"
3688   [(set (match_operand:DI 0 "register_operand" "=r")
3689         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3690   "TARGET_64BIT"
3691   "movs{bq|x}\t{%1,%0|%0, %1}"
3692    [(set_attr "type" "imovx")
3693     (set_attr "mode" "DI")])
3694
3695 ;; Extend to memory case when source register does die.
3696 (define_split
3697   [(set (match_operand:DI 0 "memory_operand" "")
3698         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3699    (clobber (reg:CC FLAGS_REG))
3700    (clobber (match_operand:SI 2 "register_operand" ""))]
3701   "(reload_completed
3702     && dead_or_set_p (insn, operands[1])
3703     && !reg_mentioned_p (operands[1], operands[0]))"
3704   [(set (match_dup 3) (match_dup 1))
3705    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3706               (clobber (reg:CC FLAGS_REG))])
3707    (set (match_dup 4) (match_dup 1))]
3708   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3709
3710 ;; Extend to memory case when source register does not die.
3711 (define_split
3712   [(set (match_operand:DI 0 "memory_operand" "")
3713         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3714    (clobber (reg:CC FLAGS_REG))
3715    (clobber (match_operand:SI 2 "register_operand" ""))]
3716   "reload_completed"
3717   [(const_int 0)]
3718 {
3719   split_di (&operands[0], 1, &operands[3], &operands[4]);
3720
3721   emit_move_insn (operands[3], operands[1]);
3722
3723   /* Generate a cltd if possible and doing so it profitable.  */
3724   if ((optimize_size || TARGET_USE_CLTD)
3725       && true_regnum (operands[1]) == AX_REG
3726       && true_regnum (operands[2]) == DX_REG)
3727     {
3728       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3729     }
3730   else
3731     {
3732       emit_move_insn (operands[2], operands[1]);
3733       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3734     }
3735   emit_move_insn (operands[4], operands[2]);
3736   DONE;
3737 })
3738
3739 ;; Extend to register case.  Optimize case where source and destination
3740 ;; registers match and cases where we can use cltd.
3741 (define_split
3742   [(set (match_operand:DI 0 "register_operand" "")
3743         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3744    (clobber (reg:CC FLAGS_REG))
3745    (clobber (match_scratch:SI 2 ""))]
3746   "reload_completed"
3747   [(const_int 0)]
3748 {
3749   split_di (&operands[0], 1, &operands[3], &operands[4]);
3750
3751   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3752     emit_move_insn (operands[3], operands[1]);
3753
3754   /* Generate a cltd if possible and doing so it profitable.  */
3755   if ((optimize_size || TARGET_USE_CLTD)
3756       && true_regnum (operands[3]) == AX_REG)
3757     {
3758       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3759       DONE;
3760     }
3761
3762   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3763     emit_move_insn (operands[4], operands[1]);
3764
3765   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3766   DONE;
3767 })
3768
3769 (define_insn "extendhisi2"
3770   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3771         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3772   ""
3773 {
3774   switch (get_attr_prefix_0f (insn))
3775     {
3776     case 0:
3777       return "{cwtl|cwde}";
3778     default:
3779       return "movs{wl|x}\t{%1,%0|%0, %1}";
3780     }
3781 }
3782   [(set_attr "type" "imovx")
3783    (set_attr "mode" "SI")
3784    (set (attr "prefix_0f")
3785      ;; movsx is short decodable while cwtl is vector decoded.
3786      (if_then_else (and (eq_attr "cpu" "!k6")
3787                         (eq_attr "alternative" "0"))
3788         (const_string "0")
3789         (const_string "1")))
3790    (set (attr "modrm")
3791      (if_then_else (eq_attr "prefix_0f" "0")
3792         (const_string "0")
3793         (const_string "1")))])
3794
3795 (define_insn "*extendhisi2_zext"
3796   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3797         (zero_extend:DI
3798           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3799   "TARGET_64BIT"
3800 {
3801   switch (get_attr_prefix_0f (insn))
3802     {
3803     case 0:
3804       return "{cwtl|cwde}";
3805     default:
3806       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3807     }
3808 }
3809   [(set_attr "type" "imovx")
3810    (set_attr "mode" "SI")
3811    (set (attr "prefix_0f")
3812      ;; movsx is short decodable while cwtl is vector decoded.
3813      (if_then_else (and (eq_attr "cpu" "!k6")
3814                         (eq_attr "alternative" "0"))
3815         (const_string "0")
3816         (const_string "1")))
3817    (set (attr "modrm")
3818      (if_then_else (eq_attr "prefix_0f" "0")
3819         (const_string "0")
3820         (const_string "1")))])
3821
3822 (define_insn "extendqihi2"
3823   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3824         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3825   ""
3826 {
3827   switch (get_attr_prefix_0f (insn))
3828     {
3829     case 0:
3830       return "{cbtw|cbw}";
3831     default:
3832       return "movs{bw|x}\t{%1,%0|%0, %1}";
3833     }
3834 }
3835   [(set_attr "type" "imovx")
3836    (set_attr "mode" "HI")
3837    (set (attr "prefix_0f")
3838      ;; movsx is short decodable while cwtl is vector decoded.
3839      (if_then_else (and (eq_attr "cpu" "!k6")
3840                         (eq_attr "alternative" "0"))
3841         (const_string "0")
3842         (const_string "1")))
3843    (set (attr "modrm")
3844      (if_then_else (eq_attr "prefix_0f" "0")
3845         (const_string "0")
3846         (const_string "1")))])
3847
3848 (define_insn "extendqisi2"
3849   [(set (match_operand:SI 0 "register_operand" "=r")
3850         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3851   ""
3852   "movs{bl|x}\t{%1,%0|%0, %1}"
3853    [(set_attr "type" "imovx")
3854     (set_attr "mode" "SI")])
3855
3856 (define_insn "*extendqisi2_zext"
3857   [(set (match_operand:DI 0 "register_operand" "=r")
3858         (zero_extend:DI
3859           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3860   "TARGET_64BIT"
3861   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3862    [(set_attr "type" "imovx")
3863     (set_attr "mode" "SI")])
3864 \f
3865 ;; Conversions between float and double.
3866
3867 ;; These are all no-ops in the model used for the 80387.  So just
3868 ;; emit moves.
3869
3870 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3871 (define_insn "*dummy_extendsfdf2"
3872   [(set (match_operand:DF 0 "push_operand" "=<")
3873         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3874   "0"
3875   "#")
3876
3877 (define_split
3878   [(set (match_operand:DF 0 "push_operand" "")
3879         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3880   "!TARGET_64BIT"
3881   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3882    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3883
3884 (define_split
3885   [(set (match_operand:DF 0 "push_operand" "")
3886         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3887   "TARGET_64BIT"
3888   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3889    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3890
3891 (define_insn "*dummy_extendsfxf2"
3892   [(set (match_operand:XF 0 "push_operand" "=<")
3893         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3894   "0"
3895   "#")
3896
3897 (define_split
3898   [(set (match_operand:XF 0 "push_operand" "")
3899         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3900   ""
3901   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3902    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3903   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3904
3905 (define_split
3906   [(set (match_operand:XF 0 "push_operand" "")
3907         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3908   "TARGET_64BIT"
3909   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3910    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3911   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3912
3913 (define_split
3914   [(set (match_operand:XF 0 "push_operand" "")
3915         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3916   ""
3917   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3918    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3919   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3920
3921 (define_split
3922   [(set (match_operand:XF 0 "push_operand" "")
3923         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3924   "TARGET_64BIT"
3925   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3926    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3927   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3928
3929 (define_expand "extendsfdf2"
3930   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3931         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3932   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3933 {
3934   /* ??? Needed for compress_float_constant since all fp constants
3935      are LEGITIMATE_CONSTANT_P.  */
3936   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3937     {
3938       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3939           && standard_80387_constant_p (operands[1]) > 0)
3940         {
3941           operands[1] = simplify_const_unary_operation
3942             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3943           emit_move_insn_1 (operands[0], operands[1]);
3944           DONE;
3945         }
3946       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3947     }
3948 })
3949
3950 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3951    cvtss2sd:
3952       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3953       cvtps2pd xmm2,xmm1
3954    We do the conversion post reload to avoid producing of 128bit spills
3955    that might lead to ICE on 32bit target.  The sequence unlikely combine
3956    anyway.  */
3957 (define_split
3958   [(set (match_operand:DF 0 "register_operand" "")
3959         (float_extend:DF
3960           (match_operand:SF 1 "nonimmediate_operand" "")))]
3961   "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
3962    && reload_completed && SSE_REG_P (operands[0])"
3963    [(set (match_dup 2)
3964          (float_extend:V2DF
3965            (vec_select:V2SF
3966              (match_dup 3)
3967              (parallel [(const_int 0) (const_int 1)]))))]
3968 {
3969   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3970   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3971   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3972      Try to avoid move when unpacking can be done in source.  */
3973   if (REG_P (operands[1]))
3974     {
3975       /* If it is unsafe to overwrite upper half of source, we need
3976          to move to destination and unpack there.  */
3977       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3978            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3979           && true_regnum (operands[0]) != true_regnum (operands[1]))
3980         {
3981           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3982           emit_move_insn (tmp, operands[1]);
3983         }
3984       else
3985         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3986       emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
3987     }
3988   else
3989     emit_insn (gen_vec_setv4sf_0 (operands[3],
3990                                   CONST0_RTX (V4SFmode), operands[1]));
3991 })
3992
3993 (define_insn "*extendsfdf2_mixed"
3994   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3995         (float_extend:DF
3996           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3997   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3998 {
3999   switch (which_alternative)
4000     {
4001     case 0:
4002     case 1:
4003       return output_387_reg_move (insn, operands);
4004
4005     case 2:
4006       return "cvtss2sd\t{%1, %0|%0, %1}";
4007
4008     default:
4009       gcc_unreachable ();
4010     }
4011 }
4012   [(set_attr "type" "fmov,fmov,ssecvt")
4013    (set_attr "mode" "SF,XF,DF")])
4014
4015 (define_insn "*extendsfdf2_sse"
4016   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4017         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4018   "TARGET_SSE2 && TARGET_SSE_MATH"
4019   "cvtss2sd\t{%1, %0|%0, %1}"
4020   [(set_attr "type" "ssecvt")
4021    (set_attr "mode" "DF")])
4022
4023 (define_insn "*extendsfdf2_i387"
4024   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4025         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4026   "TARGET_80387"
4027   "* return output_387_reg_move (insn, operands);"
4028   [(set_attr "type" "fmov")
4029    (set_attr "mode" "SF,XF")])
4030
4031 (define_expand "extend<mode>xf2"
4032   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4033         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4034   "TARGET_80387"
4035 {
4036   /* ??? Needed for compress_float_constant since all fp constants
4037      are LEGITIMATE_CONSTANT_P.  */
4038   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4039     {
4040       if (standard_80387_constant_p (operands[1]) > 0)
4041         {
4042           operands[1] = simplify_const_unary_operation
4043             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4044           emit_move_insn_1 (operands[0], operands[1]);
4045           DONE;
4046         }
4047       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4048     }
4049 })
4050
4051 (define_insn "*extend<mode>xf2_i387"
4052   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4053         (float_extend:XF
4054           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4055   "TARGET_80387"
4056   "* return output_387_reg_move (insn, operands);"
4057   [(set_attr "type" "fmov")
4058    (set_attr "mode" "<MODE>,XF")])
4059
4060 ;; %%% This seems bad bad news.
4061 ;; This cannot output into an f-reg because there is no way to be sure
4062 ;; of truncating in that case.  Otherwise this is just like a simple move
4063 ;; insn.  So we pretend we can output to a reg in order to get better
4064 ;; register preferencing, but we really use a stack slot.
4065
4066 ;; Conversion from DFmode to SFmode.
4067
4068 (define_expand "truncdfsf2"
4069   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4070         (float_truncate:SF
4071           (match_operand:DF 1 "nonimmediate_operand" "")))]
4072   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4073 {
4074   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4075     ;
4076   else if (flag_unsafe_math_optimizations)
4077     ;
4078   else
4079     {
4080       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4081       rtx temp = assign_386_stack_local (SFmode, slot);
4082       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4083       DONE;
4084     }
4085 })
4086
4087 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4088    cvtsd2ss:
4089       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4090       cvtpd2ps xmm2,xmm1
4091    We do the conversion post reload to avoid producing of 128bit spills
4092    that might lead to ICE on 32bit target.  The sequence unlikely combine
4093    anyway.  */
4094 (define_split
4095   [(set (match_operand:SF 0 "register_operand" "")
4096         (float_truncate:SF
4097           (match_operand:DF 1 "nonimmediate_operand" "")))]
4098   "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4099    && reload_completed && SSE_REG_P (operands[0])"
4100    [(set (match_dup 2)
4101          (vec_concat:V4SF
4102            (float_truncate:V2SF
4103              (match_dup 4))
4104            (match_dup 3)))]
4105 {
4106   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4107   operands[3] = CONST0_RTX (V2SFmode);
4108   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4109   /* Use movsd for loading from memory, unpcklpd for registers.
4110      Try to avoid move when unpacking can be done in source, or SSE3
4111      movddup is available.  */
4112   if (REG_P (operands[1]))
4113     {
4114       if (!TARGET_SSE3
4115           && true_regnum (operands[0]) != true_regnum (operands[1])
4116           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4117               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4118         {
4119           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4120           emit_move_insn (tmp, operands[1]);
4121           operands[1] = tmp;
4122         }
4123       else if (!TARGET_SSE3)
4124         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4125       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4126     }
4127   else
4128     emit_insn (gen_sse2_loadlpd (operands[4],
4129                                  CONST0_RTX (V2DFmode), operands[1]));
4130 })
4131
4132 (define_expand "truncdfsf2_with_temp"
4133   [(parallel [(set (match_operand:SF 0 "" "")
4134                    (float_truncate:SF (match_operand:DF 1 "" "")))
4135               (clobber (match_operand:SF 2 "" ""))])]
4136   "")
4137
4138 (define_insn "*truncdfsf_fast_mixed"
4139   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,x")
4140         (float_truncate:SF
4141           (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
4142   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4143 {
4144   switch (which_alternative)
4145     {
4146     case 0:
4147     case 1:
4148       return output_387_reg_move (insn, operands);
4149     case 2:
4150       return "cvtsd2ss\t{%1, %0|%0, %1}";
4151     default:
4152       gcc_unreachable ();
4153     }
4154 }
4155   [(set_attr "type" "fmov,fmov,ssecvt")
4156    (set_attr "mode" "SF")])
4157
4158 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4159 ;; because nothing we do here is unsafe.
4160 (define_insn "*truncdfsf_fast_sse"
4161   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4162         (float_truncate:SF
4163           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4164   "TARGET_SSE2 && TARGET_SSE_MATH"
4165   "cvtsd2ss\t{%1, %0|%0, %1}"
4166   [(set_attr "type" "ssecvt")
4167    (set_attr "mode" "SF")])
4168
4169 (define_insn "*truncdfsf_fast_i387"
4170   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4171         (float_truncate:SF
4172           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4173   "TARGET_80387 && flag_unsafe_math_optimizations"
4174   "* return output_387_reg_move (insn, operands);"
4175   [(set_attr "type" "fmov")
4176    (set_attr "mode" "SF")])
4177
4178 (define_insn "*truncdfsf_mixed"
4179   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y2")
4180         (float_truncate:SF
4181           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Y2m")))
4182    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
4183   "TARGET_MIX_SSE_I387"
4184 {
4185   switch (which_alternative)
4186     {
4187     case 0:
4188       return output_387_reg_move (insn, operands);
4189
4190     case 1:
4191       return "#";
4192     case 2:
4193       return "cvtsd2ss\t{%1, %0|%0, %1}";
4194     default:
4195       gcc_unreachable ();
4196     }
4197 }
4198   [(set_attr "type" "fmov,multi,ssecvt")
4199    (set_attr "unit" "*,i387,*")
4200    (set_attr "mode" "SF")])
4201
4202 (define_insn "*truncdfsf_i387"
4203   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4204         (float_truncate:SF
4205           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4206    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4207   "TARGET_80387"
4208 {
4209   switch (which_alternative)
4210     {
4211     case 0:
4212       return output_387_reg_move (insn, operands);
4213
4214     case 1:
4215       return "#";
4216     default:
4217       gcc_unreachable ();
4218     }
4219 }
4220   [(set_attr "type" "fmov,multi")
4221    (set_attr "unit" "*,i387")
4222    (set_attr "mode" "SF")])
4223
4224 (define_insn "*truncdfsf2_i387_1"
4225   [(set (match_operand:SF 0 "memory_operand" "=m")
4226         (float_truncate:SF
4227           (match_operand:DF 1 "register_operand" "f")))]
4228   "TARGET_80387
4229    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4230    && !TARGET_MIX_SSE_I387"
4231   "* return output_387_reg_move (insn, operands);"
4232   [(set_attr "type" "fmov")
4233    (set_attr "mode" "SF")])
4234
4235 (define_split
4236   [(set (match_operand:SF 0 "register_operand" "")
4237         (float_truncate:SF
4238          (match_operand:DF 1 "fp_register_operand" "")))
4239    (clobber (match_operand 2 "" ""))]
4240   "reload_completed"
4241   [(set (match_dup 2) (match_dup 1))
4242    (set (match_dup 0) (match_dup 2))]
4243 {
4244   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4245 })
4246
4247 ;; Conversion from XFmode to {SF,DF}mode
4248
4249 (define_expand "truncxf<mode>2"
4250   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4251                    (float_truncate:MODEF
4252                      (match_operand:XF 1 "register_operand" "")))
4253               (clobber (match_dup 2))])]
4254   "TARGET_80387"
4255 {
4256   if (flag_unsafe_math_optimizations)
4257     {
4258       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4259       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4260       if (reg != operands[0])
4261         emit_move_insn (operands[0], reg);
4262       DONE;
4263     }
4264   else
4265     {
4266       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4267       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4268     }
4269 })
4270
4271 (define_insn "*truncxfsf2_mixed"
4272   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4273         (float_truncate:SF
4274           (match_operand:XF 1 "register_operand" "f,f")))
4275    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4276   "TARGET_80387"
4277 {
4278   gcc_assert (!which_alternative);
4279   return output_387_reg_move (insn, operands);
4280 }
4281   [(set_attr "type" "fmov,multi")
4282    (set_attr "unit" "*,i387")
4283    (set_attr "mode" "SF")])
4284
4285 (define_insn "*truncxfdf2_mixed"
4286   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4287         (float_truncate:DF
4288           (match_operand:XF 1 "register_operand" "f,f")))
4289    (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4290   "TARGET_80387"
4291 {
4292   gcc_assert (!which_alternative);
4293   return output_387_reg_move (insn, operands);
4294 }
4295   [(set_attr "type" "fmov,multi")
4296    (set_attr "unit" "*,i387")
4297    (set_attr "mode" "DF")])
4298
4299 (define_insn "truncxf<mode>2_i387_noop"
4300   [(set (match_operand:MODEF 0 "register_operand" "=f")
4301         (float_truncate:MODEF
4302           (match_operand:XF 1 "register_operand" "f")))]
4303   "TARGET_80387 && flag_unsafe_math_optimizations"
4304   "* return output_387_reg_move (insn, operands);"
4305   [(set_attr "type" "fmov")
4306    (set_attr "mode" "<MODE>")])
4307
4308 (define_insn "*truncxf<mode>2_i387"
4309   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4310         (float_truncate:MODEF
4311           (match_operand:XF 1 "register_operand" "f")))]
4312   "TARGET_80387"
4313   "* return output_387_reg_move (insn, operands);"
4314   [(set_attr "type" "fmov")
4315    (set_attr "mode" "<MODE>")])
4316
4317 (define_split
4318   [(set (match_operand:MODEF 0 "register_operand" "")
4319         (float_truncate:MODEF
4320           (match_operand:XF 1 "register_operand" "")))
4321    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4322   "TARGET_80387 && reload_completed"
4323   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4324    (set (match_dup 0) (match_dup 2))]
4325   "")
4326
4327 (define_split
4328   [(set (match_operand:MODEF 0 "memory_operand" "")
4329         (float_truncate:MODEF
4330           (match_operand:XF 1 "register_operand" "")))
4331    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4332   "TARGET_80387"
4333   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4334   "")
4335 \f
4336 ;; Signed conversion to DImode.
4337
4338 (define_expand "fix_truncxfdi2"
4339   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4340                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4341               (clobber (reg:CC FLAGS_REG))])]
4342   "TARGET_80387"
4343 {
4344   if (TARGET_FISTTP)
4345    {
4346      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4347      DONE;
4348    }
4349 })
4350
4351 (define_expand "fix_trunc<mode>di2"
4352   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4353                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4354               (clobber (reg:CC FLAGS_REG))])]
4355   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4356 {
4357   if (TARGET_FISTTP
4358       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4359    {
4360      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4361      DONE;
4362    }
4363   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4364    {
4365      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4366      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4367      if (out != operands[0])
4368         emit_move_insn (operands[0], out);
4369      DONE;
4370    }
4371 })
4372
4373 ;; Signed conversion to SImode.
4374
4375 (define_expand "fix_truncxfsi2"
4376   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4377                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4378               (clobber (reg:CC FLAGS_REG))])]
4379   "TARGET_80387"
4380 {
4381   if (TARGET_FISTTP)
4382    {
4383      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4384      DONE;
4385    }
4386 })
4387
4388 (define_expand "fix_trunc<mode>si2"
4389   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4390                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4391               (clobber (reg:CC FLAGS_REG))])]
4392   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4393 {
4394   if (TARGET_FISTTP
4395       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4396    {
4397      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4398      DONE;
4399    }
4400   if (SSE_FLOAT_MODE_P (<MODE>mode))
4401    {
4402      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4403      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4404      if (out != operands[0])
4405         emit_move_insn (operands[0], out);
4406      DONE;
4407    }
4408 })
4409
4410 ;; Signed conversion to HImode.
4411
4412 (define_expand "fix_trunc<mode>hi2"
4413   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4414                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4415               (clobber (reg:CC FLAGS_REG))])]
4416   "TARGET_80387
4417    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4418 {
4419   if (TARGET_FISTTP)
4420    {
4421      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4422      DONE;
4423    }
4424 })
4425
4426 ;; Unsigned conversion to SImode.
4427
4428 (define_expand "fixuns_trunc<mode>si2"
4429   [(parallel
4430     [(set (match_operand:SI 0 "register_operand" "")
4431           (unsigned_fix:SI
4432             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4433      (use (match_dup 2))
4434      (clobber (match_scratch:<ssevecmode> 3 ""))
4435      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4436   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4437 {
4438   enum machine_mode mode = <MODE>mode;
4439   enum machine_mode vecmode = <ssevecmode>mode;
4440   REAL_VALUE_TYPE TWO31r;
4441   rtx two31;
4442
4443   real_ldexp (&TWO31r, &dconst1, 31);
4444   two31 = const_double_from_real_value (TWO31r, mode);
4445   two31 = ix86_build_const_vector (mode, true, two31);
4446   operands[2] = force_reg (vecmode, two31);
4447 })
4448
4449 (define_insn_and_split "*fixuns_trunc<mode>_1"
4450   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4451         (unsigned_fix:SI
4452           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4453    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4454    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4455    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4456   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4457   "#"
4458   "&& reload_completed"
4459   [(const_int 0)]
4460 {
4461   ix86_split_convert_uns_si_sse (operands);
4462   DONE;
4463 })
4464
4465 ;; Unsigned conversion to HImode.
4466 ;; Without these patterns, we'll try the unsigned SI conversion which
4467 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4468
4469 (define_expand "fixuns_trunc<mode>hi2"
4470   [(set (match_dup 2)
4471         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4472    (set (match_operand:HI 0 "nonimmediate_operand" "")
4473         (subreg:HI (match_dup 2) 0))]
4474   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4475   "operands[2] = gen_reg_rtx (SImode);")
4476
4477 ;; When SSE is available, it is always faster to use it!
4478 (define_insn "fix_trunc<mode>di_sse"
4479   [(set (match_operand:DI 0 "register_operand" "=r,r")
4480         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4481   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4482    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4483   "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4484   [(set_attr "type" "sseicvt")
4485    (set_attr "mode" "<MODE>")
4486    (set_attr "athlon_decode" "double,vector")
4487    (set_attr "amdfam10_decode" "double,double")])
4488
4489 (define_insn "fix_trunc<mode>si_sse"
4490   [(set (match_operand:SI 0 "register_operand" "=r,r")
4491         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4492   "SSE_FLOAT_MODE_P (<MODE>mode)
4493    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4494   "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4495   [(set_attr "type" "sseicvt")
4496    (set_attr "mode" "<MODE>")
4497    (set_attr "athlon_decode" "double,vector")
4498    (set_attr "amdfam10_decode" "double,double")])
4499
4500 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4501 (define_peephole2
4502   [(set (match_operand:MODEF 0 "register_operand" "")
4503         (match_operand:MODEF 1 "memory_operand" ""))
4504    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4505         (fix:SSEMODEI24 (match_dup 0)))]
4506   "TARGET_SHORTEN_X87_SSE
4507    && peep2_reg_dead_p (2, operands[0])"
4508   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4509   "")
4510
4511 ;; Avoid vector decoded forms of the instruction.
4512 (define_peephole2
4513   [(match_scratch:DF 2 "Y2")
4514    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4515         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4516   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4517   [(set (match_dup 2) (match_dup 1))
4518    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4519   "")
4520
4521 (define_peephole2
4522   [(match_scratch:SF 2 "x")
4523    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4524         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4525   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4526   [(set (match_dup 2) (match_dup 1))
4527    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4528   "")
4529
4530 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4531   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4532         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4533   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4534    && TARGET_FISTTP
4535    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4536          && (TARGET_64BIT || <MODE>mode != DImode))
4537         && TARGET_SSE_MATH)
4538    && !(reload_completed || reload_in_progress)"
4539   "#"
4540   "&& 1"
4541   [(const_int 0)]
4542 {
4543   if (memory_operand (operands[0], VOIDmode))
4544     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4545   else
4546     {
4547       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4548       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4549                                                             operands[1],
4550                                                             operands[2]));
4551     }
4552   DONE;
4553 }
4554   [(set_attr "type" "fisttp")
4555    (set_attr "mode" "<MODE>")])
4556
4557 (define_insn "fix_trunc<mode>_i387_fisttp"
4558   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4559         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4560    (clobber (match_scratch:XF 2 "=&1f"))]
4561   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4562    && TARGET_FISTTP
4563    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4564          && (TARGET_64BIT || <MODE>mode != DImode))
4565         && TARGET_SSE_MATH)"
4566   "* return output_fix_trunc (insn, operands, 1);"
4567   [(set_attr "type" "fisttp")
4568    (set_attr "mode" "<MODE>")])
4569
4570 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4571   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4572         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4573    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4574    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4575   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4576    && TARGET_FISTTP
4577    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4578         && (TARGET_64BIT || <MODE>mode != DImode))
4579         && TARGET_SSE_MATH)"
4580   "#"
4581   [(set_attr "type" "fisttp")
4582    (set_attr "mode" "<MODE>")])
4583
4584 (define_split
4585   [(set (match_operand:X87MODEI 0 "register_operand" "")
4586         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4587    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4588    (clobber (match_scratch 3 ""))]
4589   "reload_completed"
4590   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4591               (clobber (match_dup 3))])
4592    (set (match_dup 0) (match_dup 2))]
4593   "")
4594
4595 (define_split
4596   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4597         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4598    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4599    (clobber (match_scratch 3 ""))]
4600   "reload_completed"
4601   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4602               (clobber (match_dup 3))])]
4603   "")
4604
4605 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4606 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4607 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4608 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4609 ;; function in i386.c.
4610 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4611   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4612         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4613    (clobber (reg:CC FLAGS_REG))]
4614   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4615    && !TARGET_FISTTP
4616    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4617          && (TARGET_64BIT || <MODE>mode != DImode))
4618    && !(reload_completed || reload_in_progress)"
4619   "#"
4620   "&& 1"
4621   [(const_int 0)]
4622 {
4623   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4624
4625   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4626   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4627   if (memory_operand (operands[0], VOIDmode))
4628     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4629                                          operands[2], operands[3]));
4630   else
4631     {
4632       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4633       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4634                                                      operands[2], operands[3],
4635                                                      operands[4]));
4636     }
4637   DONE;
4638 }
4639   [(set_attr "type" "fistp")
4640    (set_attr "i387_cw" "trunc")
4641    (set_attr "mode" "<MODE>")])
4642
4643 (define_insn "fix_truncdi_i387"
4644   [(set (match_operand:DI 0 "memory_operand" "=m")
4645         (fix:DI (match_operand 1 "register_operand" "f")))
4646    (use (match_operand:HI 2 "memory_operand" "m"))
4647    (use (match_operand:HI 3 "memory_operand" "m"))
4648    (clobber (match_scratch:XF 4 "=&1f"))]
4649   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4650    && !TARGET_FISTTP
4651    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4652   "* return output_fix_trunc (insn, operands, 0);"
4653   [(set_attr "type" "fistp")
4654    (set_attr "i387_cw" "trunc")
4655    (set_attr "mode" "DI")])
4656
4657 (define_insn "fix_truncdi_i387_with_temp"
4658   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4659         (fix:DI (match_operand 1 "register_operand" "f,f")))
4660    (use (match_operand:HI 2 "memory_operand" "m,m"))
4661    (use (match_operand:HI 3 "memory_operand" "m,m"))
4662    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4663    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4664   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4665    && !TARGET_FISTTP
4666    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4667   "#"
4668   [(set_attr "type" "fistp")
4669    (set_attr "i387_cw" "trunc")
4670    (set_attr "mode" "DI")])
4671
4672 (define_split
4673   [(set (match_operand:DI 0 "register_operand" "")
4674         (fix:DI (match_operand 1 "register_operand" "")))
4675    (use (match_operand:HI 2 "memory_operand" ""))
4676    (use (match_operand:HI 3 "memory_operand" ""))
4677    (clobber (match_operand:DI 4 "memory_operand" ""))
4678    (clobber (match_scratch 5 ""))]
4679   "reload_completed"
4680   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4681               (use (match_dup 2))
4682               (use (match_dup 3))
4683               (clobber (match_dup 5))])
4684    (set (match_dup 0) (match_dup 4))]
4685   "")
4686
4687 (define_split
4688   [(set (match_operand:DI 0 "memory_operand" "")
4689         (fix:DI (match_operand 1 "register_operand" "")))
4690    (use (match_operand:HI 2 "memory_operand" ""))
4691    (use (match_operand:HI 3 "memory_operand" ""))
4692    (clobber (match_operand:DI 4 "memory_operand" ""))
4693    (clobber (match_scratch 5 ""))]
4694   "reload_completed"
4695   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4696               (use (match_dup 2))
4697               (use (match_dup 3))
4698               (clobber (match_dup 5))])]
4699   "")
4700
4701 (define_insn "fix_trunc<mode>_i387"
4702   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4703         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4704    (use (match_operand:HI 2 "memory_operand" "m"))
4705    (use (match_operand:HI 3 "memory_operand" "m"))]
4706   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4707    && !TARGET_FISTTP
4708    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4709   "* return output_fix_trunc (insn, operands, 0);"
4710   [(set_attr "type" "fistp")
4711    (set_attr "i387_cw" "trunc")
4712    (set_attr "mode" "<MODE>")])
4713
4714 (define_insn "fix_trunc<mode>_i387_with_temp"
4715   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4716         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4717    (use (match_operand:HI 2 "memory_operand" "m,m"))
4718    (use (match_operand:HI 3 "memory_operand" "m,m"))
4719    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4720   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4721    && !TARGET_FISTTP
4722    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4723   "#"
4724   [(set_attr "type" "fistp")
4725    (set_attr "i387_cw" "trunc")
4726    (set_attr "mode" "<MODE>")])
4727
4728 (define_split
4729   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4730         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4731    (use (match_operand:HI 2 "memory_operand" ""))
4732    (use (match_operand:HI 3 "memory_operand" ""))
4733    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4734   "reload_completed"
4735   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4736               (use (match_dup 2))
4737               (use (match_dup 3))])
4738    (set (match_dup 0) (match_dup 4))]
4739   "")
4740
4741 (define_split
4742   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4743         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4744    (use (match_operand:HI 2 "memory_operand" ""))
4745    (use (match_operand:HI 3 "memory_operand" ""))
4746    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4747   "reload_completed"
4748   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4749               (use (match_dup 2))
4750               (use (match_dup 3))])]
4751   "")
4752
4753 (define_insn "x86_fnstcw_1"
4754   [(set (match_operand:HI 0 "memory_operand" "=m")
4755         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4756   "TARGET_80387"
4757   "fnstcw\t%0"
4758   [(set_attr "length" "2")
4759    (set_attr "mode" "HI")
4760    (set_attr "unit" "i387")])
4761
4762 (define_insn "x86_fldcw_1"
4763   [(set (reg:HI FPCR_REG)
4764         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4765   "TARGET_80387"
4766   "fldcw\t%0"
4767   [(set_attr "length" "2")
4768    (set_attr "mode" "HI")
4769    (set_attr "unit" "i387")
4770    (set_attr "athlon_decode" "vector")
4771    (set_attr "amdfam10_decode" "vector")])
4772 \f
4773 ;; Conversion between fixed point and floating point.
4774
4775 ;; Even though we only accept memory inputs, the backend _really_
4776 ;; wants to be able to do this between registers.
4777
4778 (define_expand "floathi<mode>2"
4779   [(set (match_operand:MODEF 0 "register_operand" "")
4780         (float:MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4781   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4782 {
4783   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4784     {
4785       emit_insn
4786         (gen_floatsi<mode>2 (operands[0],
4787                              convert_to_mode (SImode, operands[1], 0)));
4788       DONE;
4789     }
4790 })
4791
4792 (define_insn "*floathi<mode>2_i387"
4793   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
4794         (float:MODEF
4795           (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4796   "TARGET_80387
4797    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4798        || TARGET_MIX_SSE_I387)"
4799   "@
4800    fild%z1\t%1
4801    #"
4802   [(set_attr "type" "fmov,multi")
4803    (set_attr "mode" "<MODE>")
4804    (set_attr "unit" "*,i387")
4805    (set_attr "fp_int_src" "true")])
4806
4807 (define_expand "floatsi<mode>2"
4808   [(set (match_operand:MODEF 0 "register_operand" "")
4809         (float:MODEF (match_operand:SI 1 "nonimmediate_operand" "")))]
4810   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4811   "
4812    /* When we use vector converts, we can't have input in memory.  */
4813    if (GET_MODE (operands[0]) == DFmode
4814        && TARGET_USE_VECTOR_CONVERTS && !optimize_size && TARGET_SSE_MATH
4815        && SSE_FLOAT_MODE_P (DFmode))
4816      operands[1] = force_reg (SImode, operands[1]);
4817    else if (GET_MODE (operands[0]) == SFmode
4818             && !optimize_size && TARGET_USE_VECTOR_CONVERTS && TARGET_SSE_MATH
4819             && SSE_FLOAT_MODE_P (SFmode))
4820      {
4821        /* When !flag_trapping_math, we handle SImode->SFmode vector
4822           conversions same way as SImode->DFmode.
4823
4824           For flat_trapping_math we can't safely use vector conversion without
4825           clearing upper half, otherwise precision exception might occur.
4826           However we can still generate the common sequence converting value
4827           from general register to XMM register as:
4828
4829             mov         reg32, mem32
4830             movd        mem32, xmm
4831             cvtdq2pd xmm,xmm
4832
4833           because we know that movd clears the upper half.
4834
4835           Sadly in this case we can't rely on reload moving the value to XMM
4836           register, since we need to know if upper half is OK, so we need
4837           to do reloading by hand.  We force operand to memory unless target
4838           supports inter unit moves.  */
4839        if (!flag_trapping_math)
4840          operands[1] = force_reg (SImode, operands[1]);
4841        else if (!MEM_P (operands[1]))
4842          {
4843            int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4844            rtx tmp = assign_386_stack_local (SImode, slot);
4845            emit_move_insn (tmp, operands[1]);
4846            operands[1] = tmp;
4847          }
4848      }
4849    /* Offload operand of cvtsi2ss and cvtsi2sd into memory for
4850       !TARGET_INTER_UNIT_CONVERSIONS
4851       It is necessary for the patterns to not accept nonmemory operands
4852       as we would optimize out later.  */
4853    else if (!TARGET_INTER_UNIT_CONVERSIONS
4854             && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
4855             && !optimize_size
4856             && !MEM_P (operands[1]))
4857      {
4858        int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4859        rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
4860        emit_move_insn (tmp, operands[1]);
4861        operands[1] = tmp;
4862      }
4863   ")
4864
4865 (define_insn "*floatsisf2_mixed_vector"
4866   [(set (match_operand:SF 0 "register_operand" "=x,f,?f")
4867         (float:SF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
4868   "TARGET_MIX_SSE_I387 && !flag_trapping_math
4869    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4870   "@
4871    cvtdq2ps\t{%1, %0|%0, %1}
4872    fild%z1\t%1
4873    #"
4874   [(set_attr "type" "sseicvt,fmov,multi")
4875    (set_attr "mode" "SF")
4876    (set_attr "unit" "*,i387,*")
4877    (set_attr "athlon_decode" "double,*,*")
4878    (set_attr "amdfam10_decode" "double,*,*")
4879    (set_attr "fp_int_src" "false,true,true")])
4880
4881 (define_insn "*floatsisf2_mixed"
4882   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4883         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4884   "TARGET_MIX_SSE_I387
4885    && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
4886        || optimize_size)"
4887   "@
4888    fild%z1\t%1
4889    #
4890    cvtsi2ss\t{%1, %0|%0, %1}
4891    cvtsi2ss\t{%1, %0|%0, %1}"
4892   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4893    (set_attr "mode" "SF")
4894    (set_attr "unit" "*,i387,*,*")
4895    (set_attr "athlon_decode" "*,*,vector,double")
4896    (set_attr "amdfam10_decode" "*,*,vector,double")
4897    (set_attr "fp_int_src" "true")])
4898
4899 (define_insn "*floatsisf2_mixed_memory"
4900   [(set (match_operand:SF 0 "register_operand" "=f,x")
4901         (float:SF (match_operand:SI 1 "memory_operand" "m,m")))]
4902   "TARGET_MIX_SSE_I387
4903    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
4904   "@
4905    fild%z1\t%1
4906    cvtsi2ss\t{%1, %0|%0, %1}"
4907   [(set_attr "type" "fmov,sseicvt")
4908    (set_attr "mode" "SF")
4909    (set_attr "athlon_decode" "*,double")
4910    (set_attr "amdfam10_decode" "*,double")
4911    (set_attr "fp_int_src" "true")])
4912
4913 (define_insn "*floatsisf2_sse_vector_nointernunit"
4914   [(set (match_operand:SF 0 "register_operand" "=x")
4915         (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4916   "TARGET_SSE_MATH && flag_trapping_math
4917    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4918    && !TARGET_INTER_UNIT_MOVES"
4919   "#"
4920   [(set_attr "type" "multi")])
4921
4922 (define_insn "*floatsisf2_sse_vector_internunit"
4923   [(set (match_operand:SF 0 "register_operand" "=x,x")
4924         (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm,x")))]
4925   "TARGET_SSE_MATH && flag_trapping_math
4926    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4927    && TARGET_INTER_UNIT_MOVES"
4928   "#"
4929   [(set_attr "type" "multi")])
4930
4931 (define_split
4932   [(set (match_operand:SF 0 "register_operand" "")
4933         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4934   "flag_trapping_math
4935    && TARGET_USE_VECTOR_CONVERTS && reload_completed
4936    && (TARGET_INTER_UNIT_MOVES || MEM_P (operands[1]))
4937    && !SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4938   [(set (match_dup 0)
4939         (float:V4SF (match_dup 2)))]
4940 {
4941   operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4942   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4943   emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
4944 })
4945
4946 (define_split
4947   [(set (match_operand:SF 0 "register_operand" "")
4948         (float:SF (match_operand:SI 1 "register_operand" "")))]
4949   "flag_trapping_math
4950    && TARGET_USE_VECTOR_CONVERTS && reload_completed
4951    && SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4952   [(set (match_dup 2) (vec_duplicate:V4SI (match_dup 1)))
4953    (set (match_dup 0)
4954         (float:V4SF (match_dup 2)))]
4955 {
4956   operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4957   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4958 })
4959
4960 (define_insn "*floatsisf2_sse_vector"
4961   [(set (match_operand:SF 0 "register_operand" "=x")
4962         (float:SF (match_operand:SI 1 "register_operand" "x")))]
4963   "TARGET_SSE_MATH && !flag_trapping_math
4964    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4965    && !TARGET_INTER_UNIT_MOVES"
4966   "cvtdq2ps\t{%1, %0|%0, %1}"
4967   [(set_attr "type" "sseicvt")
4968    (set_attr "mode" "SF")
4969    (set_attr "athlon_decode" "double")
4970    (set_attr "amdfam10_decode" "double")
4971    (set_attr "fp_int_src" "true")])
4972
4973 (define_insn "*floatsisf2_sse"
4974   [(set (match_operand:SF 0 "register_operand" "=x,x")
4975         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4976   "TARGET_SSE_MATH
4977    && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
4978        || optimize_size)"
4979   "cvtsi2ss\t{%1, %0|%0, %1}"
4980   [(set_attr "type" "sseicvt")
4981    (set_attr "mode" "SF")
4982    (set_attr "athlon_decode" "vector,double")
4983    (set_attr "amdfam10_decode" "vector,double")
4984    (set_attr "fp_int_src" "true")])
4985
4986 (define_insn "*floatsisf2_sse_memory"
4987   [(set (match_operand:SF 0 "register_operand" "=x")
4988         (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4989   "TARGET_SSE_MATH
4990    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
4991   "cvtsi2ss\t{%1, %0|%0, %1}"
4992   [(set_attr "type" "sseicvt")
4993    (set_attr "mode" "SF")
4994    (set_attr "athlon_decode" "double")
4995    (set_attr "amdfam10_decode" "double")
4996    (set_attr "fp_int_src" "true")])
4997
4998 (define_insn "*floatsidf2_mixed_vector"
4999   [(set (match_operand:DF 0 "register_operand" "=x,f,f")
5000         (float:DF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
5001   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5002    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5003   "@
5004    cvtdq2pd\t{%1, %0|%0, %1}
5005    fild%z1\t%1
5006    #"
5007   [(set_attr "type" "sseicvt,fmov,multi")
5008    (set_attr "mode" "V2DF,DF,DF")
5009    (set_attr "unit" "*,*,i387")
5010    (set_attr "athlon_decode" "double,*,*")
5011    (set_attr "amdfam10_decode" "double,*,*")
5012    (set_attr "fp_int_src" "false,true,true")])
5013
5014 (define_insn "*floatsidf2_mixed"
5015   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x,!x")
5016         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m,x")))]
5017   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5018    && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5019        || optimize_size)"
5020   "@
5021    fild%z1\t%1
5022    #
5023    cvtsi2sd\t{%1, %0|%0, %1}
5024    cvtsi2sd\t{%1, %0|%0, %1}
5025    cvtdq2pd\t{%1, %0|%0, %1}"
5026   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5027    (set_attr "mode" "DF,DF,DF,DF,V2DF")
5028    (set_attr "unit" "*,i387,*,*,*")
5029    (set_attr "athlon_decode" "*,*,double,direct,double")
5030    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5031    (set_attr "fp_int_src" "true,true,true,true,false")])
5032
5033 (define_insn "*floatsidf2_mixed_memory"
5034   [(set (match_operand:DF 0 "register_operand" "=f,x")
5035         (float:DF (match_operand:SI 1 "memory_operand" "m,m")))]
5036   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5037    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5038   "@
5039    fild%z1\t%1
5040    cvtsi2sd\t{%1, %0|%0, %1}"
5041   [(set_attr "type" "fmov,sseicvt")
5042    (set_attr "mode" "DF")
5043    (set_attr "athlon_decode" "*,direct")
5044    (set_attr "amdfam10_decode" "*,double")
5045    (set_attr "fp_int_src" "true")])
5046
5047 (define_insn "*floatsidf2_sse_vector"
5048   [(set (match_operand:DF 0 "register_operand" "=x")
5049         (float:DF (match_operand:SI 1 "register_operand" "x")))]
5050   "TARGET_SSE2 && TARGET_SSE_MATH
5051    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5052   "cvtdq2pd\t{%1, %0|%0, %1}"
5053   [(set_attr "type" "sseicvt")
5054    (set_attr "mode" "V2DF")
5055    (set_attr "athlon_decode" "double")
5056    (set_attr "amdfam10_decode" "double")
5057    (set_attr "fp_int_src" "true")])
5058
5059 (define_split
5060   [(set (match_operand:DF 0 "register_operand" "")
5061         (float:DF (match_operand:SI 1 "memory_operand" "")))]
5062   "TARGET_USE_VECTOR_CONVERTS && reload_completed
5063    && SSE_REG_P (operands[0])"
5064   [(set (match_dup 0)
5065         (float:V2DF
5066           (vec_select:V2SI
5067             (match_dup 2)
5068             (parallel [(const_int 0) (const_int 1)]))))]
5069 {
5070   operands[2] = simplify_gen_subreg (V4SImode, operands[0], DFmode, 0);
5071   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
5072   emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
5073 })
5074
5075 (define_insn "*floatsidf2_sse"
5076   [(set (match_operand:DF 0 "register_operand" "=x,x,!x")
5077         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,m,x")))]
5078   "TARGET_SSE2 && TARGET_SSE_MATH
5079    && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5080        || optimize_size)"
5081   "@
5082    cvtsi2sd\t{%1, %0|%0, %1}
5083    cvtsi2sd\t{%1, %0|%0, %1}
5084    cvtdq2pd\t{%1, %0|%0, %1}"
5085   [(set_attr "type" "sseicvt")
5086    (set_attr "mode" "DF,DF,V2DF")
5087    (set_attr "athlon_decode" "double,direct,double")
5088    (set_attr "amdfam10_decode" "vector,double,double")
5089    (set_attr "fp_int_src" "true")])
5090
5091 (define_insn "*floatsidf2_memory"
5092   [(set (match_operand:DF 0 "register_operand" "=x")
5093         (float:DF (match_operand:SI 1 "memory_operand" "x")))]
5094   "TARGET_SSE2 && TARGET_SSE_MATH
5095    && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5096        || optimize_size)"
5097   "cvtsi2sd\t{%1, %0|%0, %1}"
5098   [(set_attr "type" "sseicvt")
5099    (set_attr "mode" "DF")
5100    (set_attr "athlon_decode" "direct")
5101    (set_attr "amdfam10_decode" "double")
5102    (set_attr "fp_int_src" "true")])
5103
5104 (define_insn "*floatsi<mode>2_i387"
5105   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5106         (float:MODEF
5107           (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
5108   "TARGET_80387
5109    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5110   "@
5111    fild%z1\t%1
5112    #"
5113   [(set_attr "type" "fmov,multi")
5114    (set_attr "mode" "<MODE>")
5115    (set_attr "unit" "*,i387")
5116    (set_attr "fp_int_src" "true")])
5117
5118 (define_expand "floatdisf2"
5119   [(set (match_operand:SF 0 "register_operand" "")
5120         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
5121   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
5122 {
5123   if (!TARGET_INTER_UNIT_CONVERSIONS && TARGET_64BIT
5124       && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (SFmode)
5125       && !optimize_size
5126       && !MEM_P (operands[1]))
5127     {
5128       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5129       rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
5130       emit_move_insn (tmp, operands[1]);
5131       operands[1] = tmp;
5132     }
5133 })
5134
5135 (define_insn "*floatdisf2_mixed"
5136   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
5137         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5138   "TARGET_64BIT && TARGET_MIX_SSE_I387
5139    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5140   "@
5141    fild%z1\t%1
5142    #
5143    cvtsi2ss{q}\t{%1, %0|%0, %1}
5144    cvtsi2ss{q}\t{%1, %0|%0, %1}"
5145   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5146    (set_attr "mode" "SF")
5147    (set_attr "unit" "*,i387,*,*")
5148    (set_attr "athlon_decode" "*,*,vector,double")
5149    (set_attr "amdfam10_decode" "*,*,vector,double")
5150    (set_attr "fp_int_src" "true")])
5151
5152 (define_insn "*floatdisf2_mixed"
5153   [(set (match_operand:SF 0 "register_operand" "=f,x")
5154         (float:SF (match_operand:DI 1 "memory_operand" "m,m")))]
5155   "TARGET_64BIT && TARGET_MIX_SSE_I387
5156    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5157   "@
5158    fild%z1\t%1
5159    cvtsi2ss{q}\t{%1, %0|%0, %1}"
5160   [(set_attr "type" "fmov,sseicvt")
5161    (set_attr "mode" "SF")
5162    (set_attr "athlon_decode" "*,double")
5163    (set_attr "amdfam10_decode" "*,double")
5164    (set_attr "fp_int_src" "true")])
5165
5166 (define_insn "*floatdisf2_sse"
5167   [(set (match_operand:SF 0 "register_operand" "=x,x")
5168         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5169   "TARGET_64BIT && TARGET_SSE_MATH
5170    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5171   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5172   [(set_attr "type" "sseicvt")
5173    (set_attr "mode" "SF")
5174    (set_attr "athlon_decode" "vector,double")
5175    (set_attr "amdfam10_decode" "vector,double")
5176    (set_attr "fp_int_src" "true")])
5177
5178 (define_insn "*floatdisf2_memory"
5179   [(set (match_operand:SF 0 "register_operand" "=x")
5180         (float:SF (match_operand:DI 1 "memory_operand" "m")))]
5181   "TARGET_64BIT && TARGET_SSE_MATH
5182    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5183   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5184   [(set_attr "type" "sseicvt")
5185    (set_attr "mode" "SF")
5186    (set_attr "athlon_decode" "double")
5187    (set_attr "amdfam10_decode" "double")
5188    (set_attr "fp_int_src" "true")])
5189
5190 (define_expand "floatdidf2"
5191   [(set (match_operand:DF 0 "register_operand" "")
5192         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5193   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5194 {
5195   if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
5196     {
5197       ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
5198       DONE;
5199     }
5200   if (!TARGET_INTER_UNIT_CONVERSIONS && TARGET_64BIT
5201       && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (DFmode)
5202       && !optimize_size
5203       && !MEM_P (operands[1]))
5204     {
5205       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5206       rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
5207       emit_move_insn (tmp, operands[1]);
5208       operands[1] = tmp;
5209     }
5210 })
5211
5212 (define_insn "*floatdidf2_mixed"
5213   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
5214         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5215   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387
5216    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5217   "@
5218    fild%z1\t%1
5219    #
5220    cvtsi2sd{q}\t{%1, %0|%0, %1}
5221    cvtsi2sd{q}\t{%1, %0|%0, %1}"
5222   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5223    (set_attr "mode" "DF")
5224    (set_attr "unit" "*,i387,*,*")
5225    (set_attr "athlon_decode" "*,*,double,direct")
5226    (set_attr "amdfam10_decode" "*,*,vector,double")
5227    (set_attr "fp_int_src" "true")])
5228
5229 (define_insn "*floatdidf2_mixed_memory"
5230   [(set (match_operand:DF 0 "register_operand" "=f,x")
5231         (float:DF (match_operand:DI 1 "memory_operand" "m,m")))]
5232   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387
5233    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5234   "@
5235    fild%z1\t%1
5236    cvtsi2sd{q}\t{%1, %0|%0, %1}"
5237   [(set_attr "type" "fmov,sseicvt")
5238    (set_attr "mode" "DF")
5239    (set_attr "athlon_decode" "*,direct")
5240    (set_attr "amdfam10_decode" "*,double")
5241    (set_attr "fp_int_src" "true")])
5242
5243 (define_insn "*floatdidf2_sse"
5244   [(set (match_operand:DF 0 "register_operand" "=x,x")
5245         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5246   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5247    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5248   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5249   [(set_attr "type" "sseicvt")
5250    (set_attr "mode" "DF")
5251    (set_attr "athlon_decode" "double,direct")
5252    (set_attr "amdfam10_decode" "vector,double")
5253    (set_attr "fp_int_src" "true")])
5254
5255 (define_insn "*floatdidf2_sse_memory"
5256   [(set (match_operand:DF 0 "register_operand" "=x")
5257         (float:DF (match_operand:DI 1 "memory_operand" "m")))]
5258   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5259    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5260   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5261   [(set_attr "type" "sseicvt")
5262    (set_attr "mode" "DF")
5263    (set_attr "athlon_decode" "direct")
5264    (set_attr "amdfam10_decode" "double")
5265    (set_attr "fp_int_src" "true")])
5266
5267 (define_insn "*floatdi<mode>2_i387"
5268   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5269         (float:MODEF
5270           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
5271   "TARGET_80387
5272    && (!TARGET_SSE_MATH || !TARGET_64BIT
5273        || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5274   "@
5275    fild%z1\t%1
5276    #"
5277   [(set_attr "type" "fmov,multi")
5278    (set_attr "mode" "<MODE>")
5279    (set_attr "unit" "*,i387")
5280    (set_attr "fp_int_src" "true")])
5281
5282 (define_insn "float<mode>xf2"
5283   [(set (match_operand:XF 0 "register_operand" "=f,f")
5284         (float:XF (match_operand:X87MODEI 1 "nonimmediate_operand" "m,?r")))]
5285   "TARGET_80387"
5286   "@
5287    fild%z1\t%1
5288    #"
5289   [(set_attr "type" "fmov,multi")
5290    (set_attr "mode" "XF")
5291    (set_attr "unit" "*,i387")
5292    (set_attr "fp_int_src" "true")])
5293
5294 ;; %%% Kill these when reload knows how to do it.
5295 (define_split
5296   [(set (match_operand 0 "fp_register_operand" "")
5297         (float (match_operand 1 "register_operand" "")))]
5298   "reload_completed
5299    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
5300   [(const_int 0)]
5301 {
5302   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5303   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5304   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5305   ix86_free_from_memory (GET_MODE (operands[1]));
5306   DONE;
5307 })
5308
5309 (define_expand "floatunssi<mode>2"
5310   [(use (match_operand:MODEF 0 "register_operand" ""))
5311    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5312   "!TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5313 {
5314   ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5315   DONE;
5316 })
5317
5318 (define_expand "floatunsdisf2"
5319   [(use (match_operand:SF 0 "register_operand" ""))
5320    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5321   "TARGET_64BIT && TARGET_SSE_MATH"
5322   "x86_emit_floatuns (operands); DONE;")
5323
5324 (define_expand "floatunsdidf2"
5325   [(use (match_operand:DF 0 "register_operand" ""))
5326    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5327   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5328    && TARGET_SSE2 && TARGET_SSE_MATH"
5329 {
5330   if (TARGET_64BIT)
5331     x86_emit_floatuns (operands);
5332   else
5333     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5334   DONE;
5335 })
5336 \f
5337 ;; Add instructions
5338
5339 ;; %%% splits for addditi3
5340
5341 (define_expand "addti3"
5342   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5343         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5344                  (match_operand:TI 2 "x86_64_general_operand" "")))
5345    (clobber (reg:CC FLAGS_REG))]
5346   "TARGET_64BIT"
5347   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5348
5349 (define_insn "*addti3_1"
5350   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5351         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5352                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5353    (clobber (reg:CC FLAGS_REG))]
5354   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5355   "#")
5356
5357 (define_split
5358   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5359         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5360                  (match_operand:TI 2 "x86_64_general_operand" "")))
5361    (clobber (reg:CC FLAGS_REG))]
5362   "TARGET_64BIT && reload_completed"
5363   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5364                                           UNSPEC_ADD_CARRY))
5365               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5366    (parallel [(set (match_dup 3)
5367                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5368                                      (match_dup 4))
5369                             (match_dup 5)))
5370               (clobber (reg:CC FLAGS_REG))])]
5371   "split_ti (operands+0, 1, operands+0, operands+3);
5372    split_ti (operands+1, 1, operands+1, operands+4);
5373    split_ti (operands+2, 1, operands+2, operands+5);")
5374
5375 ;; %%% splits for addsidi3
5376 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5377 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5378 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5379
5380 (define_expand "adddi3"
5381   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5382         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5383                  (match_operand:DI 2 "x86_64_general_operand" "")))
5384    (clobber (reg:CC FLAGS_REG))]
5385   ""
5386   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5387
5388 (define_insn "*adddi3_1"
5389   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5390         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5391                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5392    (clobber (reg:CC FLAGS_REG))]
5393   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5394   "#")
5395
5396 (define_split
5397   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5398         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5399                  (match_operand:DI 2 "general_operand" "")))
5400    (clobber (reg:CC FLAGS_REG))]
5401   "!TARGET_64BIT && reload_completed"
5402   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5403                                           UNSPEC_ADD_CARRY))
5404               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5405    (parallel [(set (match_dup 3)
5406                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5407                                      (match_dup 4))
5408                             (match_dup 5)))
5409               (clobber (reg:CC FLAGS_REG))])]
5410   "split_di (operands+0, 1, operands+0, operands+3);
5411    split_di (operands+1, 1, operands+1, operands+4);
5412    split_di (operands+2, 1, operands+2, operands+5);")
5413
5414 (define_insn "adddi3_carry_rex64"
5415   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5416           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5417                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5418                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5419    (clobber (reg:CC FLAGS_REG))]
5420   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5421   "adc{q}\t{%2, %0|%0, %2}"
5422   [(set_attr "type" "alu")
5423    (set_attr "pent_pair" "pu")
5424    (set_attr "mode" "DI")])
5425
5426 (define_insn "*adddi3_cc_rex64"
5427   [(set (reg:CC FLAGS_REG)
5428         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5429                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5430                    UNSPEC_ADD_CARRY))
5431    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5432         (plus:DI (match_dup 1) (match_dup 2)))]
5433   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5434   "add{q}\t{%2, %0|%0, %2}"
5435   [(set_attr "type" "alu")
5436    (set_attr "mode" "DI")])
5437
5438 (define_insn "*<addsub><mode>3_cc_overflow"
5439   [(set (reg:CCC FLAGS_REG)
5440         (compare:CCC
5441             (plusminus:SWI
5442                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5443                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5444             (match_dup 1)))
5445    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5446         (plusminus:SWI (match_dup 1) (match_dup 2)))]
5447   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5448   "<addsub>{<imodesuffix>}\t{%2, %0|%0, %2}"
5449   [(set_attr "type" "alu")
5450    (set_attr "mode" "<MODE>")])
5451
5452 (define_insn "*add<mode>3_cconly_overflow"
5453   [(set (reg:CCC FLAGS_REG)
5454         (compare:CCC
5455                 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5456                           (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5457                 (match_dup 1)))
5458    (clobber (match_scratch:SWI 0 "=<r>"))]
5459   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5460   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5461   [(set_attr "type" "alu")
5462    (set_attr "mode" "<MODE>")])
5463
5464 (define_insn "*sub<mode>3_cconly_overflow"
5465   [(set (reg:CCC FLAGS_REG)
5466         (compare:CCC
5467              (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5468                         (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5469              (match_dup 0)))]
5470   ""
5471   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5472   [(set_attr "type" "icmp")
5473    (set_attr "mode" "<MODE>")])
5474
5475 (define_insn "*<addsub>si3_zext_cc_overflow"
5476   [(set (reg:CCC FLAGS_REG)
5477         (compare:CCC
5478             (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5479                           (match_operand:SI 2 "general_operand" "g"))
5480             (match_dup 1)))
5481    (set (match_operand:DI 0 "register_operand" "=r")
5482         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5483   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5484   "<addsub>{l}\t{%2, %k0|%k0, %2}"
5485   [(set_attr "type" "alu")
5486    (set_attr "mode" "SI")])
5487
5488 (define_insn "addqi3_carry"
5489   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5490           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5491                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5492                    (match_operand:QI 2 "general_operand" "qi,qm")))
5493    (clobber (reg:CC FLAGS_REG))]
5494   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5495   "adc{b}\t{%2, %0|%0, %2}"
5496   [(set_attr "type" "alu")
5497    (set_attr "pent_pair" "pu")
5498    (set_attr "mode" "QI")])
5499
5500 (define_insn "addhi3_carry"
5501   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5502           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5503                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5504                    (match_operand:HI 2 "general_operand" "ri,rm")))
5505    (clobber (reg:CC FLAGS_REG))]
5506   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5507   "adc{w}\t{%2, %0|%0, %2}"
5508   [(set_attr "type" "alu")
5509    (set_attr "pent_pair" "pu")
5510    (set_attr "mode" "HI")])
5511
5512 (define_insn "addsi3_carry"
5513   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5514           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5515                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5516                    (match_operand:SI 2 "general_operand" "ri,rm")))
5517    (clobber (reg:CC FLAGS_REG))]
5518   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5519   "adc{l}\t{%2, %0|%0, %2}"
5520   [(set_attr "type" "alu")
5521    (set_attr "pent_pair" "pu")
5522    (set_attr "mode" "SI")])
5523
5524 (define_insn "*addsi3_carry_zext"
5525   [(set (match_operand:DI 0 "register_operand" "=r")
5526           (zero_extend:DI
5527             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5528                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5529                      (match_operand:SI 2 "general_operand" "g"))))
5530    (clobber (reg:CC FLAGS_REG))]
5531   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5532   "adc{l}\t{%2, %k0|%k0, %2}"
5533   [(set_attr "type" "alu")
5534    (set_attr "pent_pair" "pu")
5535    (set_attr "mode" "SI")])
5536
5537 (define_insn "*addsi3_cc"
5538   [(set (reg:CC FLAGS_REG)
5539         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5540                     (match_operand:SI 2 "general_operand" "ri,rm")]
5541                    UNSPEC_ADD_CARRY))
5542    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5543         (plus:SI (match_dup 1) (match_dup 2)))]
5544   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5545   "add{l}\t{%2, %0|%0, %2}"
5546   [(set_attr "type" "alu")
5547    (set_attr "mode" "SI")])
5548
5549 (define_insn "addqi3_cc"
5550   [(set (reg:CC FLAGS_REG)
5551         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5552                     (match_operand:QI 2 "general_operand" "qi,qm")]
5553                    UNSPEC_ADD_CARRY))
5554    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5555         (plus:QI (match_dup 1) (match_dup 2)))]
5556   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5557   "add{b}\t{%2, %0|%0, %2}"
5558   [(set_attr "type" "alu")
5559    (set_attr "mode" "QI")])
5560
5561 (define_expand "addsi3"
5562   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5563                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5564                             (match_operand:SI 2 "general_operand" "")))
5565               (clobber (reg:CC FLAGS_REG))])]
5566   ""
5567   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5568
5569 (define_insn "*lea_1"
5570   [(set (match_operand:SI 0 "register_operand" "=r")
5571         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5572   "!TARGET_64BIT"
5573   "lea{l}\t{%a1, %0|%0, %a1}"
5574   [(set_attr "type" "lea")
5575    (set_attr "mode" "SI")])
5576
5577 (define_insn "*lea_1_rex64"
5578   [(set (match_operand:SI 0 "register_operand" "=r")
5579         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5580   "TARGET_64BIT"
5581   "lea{l}\t{%a1, %0|%0, %a1}"
5582   [(set_attr "type" "lea")
5583    (set_attr "mode" "SI")])
5584
5585 (define_insn "*lea_1_zext"
5586   [(set (match_operand:DI 0 "register_operand" "=r")
5587         (zero_extend:DI
5588          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5589   "TARGET_64BIT"
5590   "lea{l}\t{%a1, %k0|%k0, %a1}"
5591   [(set_attr "type" "lea")
5592    (set_attr "mode" "SI")])
5593
5594 (define_insn "*lea_2_rex64"
5595   [(set (match_operand:DI 0 "register_operand" "=r")
5596         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5597   "TARGET_64BIT"
5598   "lea{q}\t{%a1, %0|%0, %a1}"
5599   [(set_attr "type" "lea")
5600    (set_attr "mode" "DI")])
5601
5602 ;; The lea patterns for non-Pmodes needs to be matched by several
5603 ;; insns converted to real lea by splitters.
5604
5605 (define_insn_and_split "*lea_general_1"
5606   [(set (match_operand 0 "register_operand" "=r")
5607         (plus (plus (match_operand 1 "index_register_operand" "l")
5608                     (match_operand 2 "register_operand" "r"))
5609               (match_operand 3 "immediate_operand" "i")))]
5610   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5611     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5612    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5613    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5614    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5615    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5616        || GET_MODE (operands[3]) == VOIDmode)"
5617   "#"
5618   "&& reload_completed"
5619   [(const_int 0)]
5620 {
5621   rtx pat;
5622   operands[0] = gen_lowpart (SImode, operands[0]);
5623   operands[1] = gen_lowpart (Pmode, operands[1]);
5624   operands[2] = gen_lowpart (Pmode, operands[2]);
5625   operands[3] = gen_lowpart (Pmode, operands[3]);
5626   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5627                       operands[3]);
5628   if (Pmode != SImode)
5629     pat = gen_rtx_SUBREG (SImode, pat, 0);
5630   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5631   DONE;
5632 }
5633   [(set_attr "type" "lea")
5634    (set_attr "mode" "SI")])
5635
5636 (define_insn_and_split "*lea_general_1_zext"
5637   [(set (match_operand:DI 0 "register_operand" "=r")
5638         (zero_extend:DI
5639           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5640                             (match_operand:SI 2 "register_operand" "r"))
5641                    (match_operand:SI 3 "immediate_operand" "i"))))]
5642   "TARGET_64BIT"
5643   "#"
5644   "&& reload_completed"
5645   [(set (match_dup 0)
5646         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5647                                                      (match_dup 2))
5648                                             (match_dup 3)) 0)))]
5649 {
5650   operands[1] = gen_lowpart (Pmode, operands[1]);
5651   operands[2] = gen_lowpart (Pmode, operands[2]);
5652   operands[3] = gen_lowpart (Pmode, operands[3]);
5653 }
5654   [(set_attr "type" "lea")
5655    (set_attr "mode" "SI")])
5656
5657 (define_insn_and_split "*lea_general_2"
5658   [(set (match_operand 0 "register_operand" "=r")
5659         (plus (mult (match_operand 1 "index_register_operand" "l")
5660                     (match_operand 2 "const248_operand" "i"))
5661               (match_operand 3 "nonmemory_operand" "ri")))]
5662   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5663     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5664    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5665    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5666    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5667        || GET_MODE (operands[3]) == VOIDmode)"
5668   "#"
5669   "&& reload_completed"
5670   [(const_int 0)]
5671 {
5672   rtx pat;
5673   operands[0] = gen_lowpart (SImode, operands[0]);
5674   operands[1] = gen_lowpart (Pmode, operands[1]);
5675   operands[3] = gen_lowpart (Pmode, operands[3]);
5676   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5677                       operands[3]);
5678   if (Pmode != SImode)
5679     pat = gen_rtx_SUBREG (SImode, pat, 0);
5680   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5681   DONE;
5682 }
5683   [(set_attr "type" "lea")
5684    (set_attr "mode" "SI")])
5685
5686 (define_insn_and_split "*lea_general_2_zext"
5687   [(set (match_operand:DI 0 "register_operand" "=r")
5688         (zero_extend:DI
5689           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5690                             (match_operand:SI 2 "const248_operand" "n"))
5691                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5692   "TARGET_64BIT"
5693   "#"
5694   "&& reload_completed"
5695   [(set (match_dup 0)
5696         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5697                                                      (match_dup 2))
5698                                             (match_dup 3)) 0)))]
5699 {
5700   operands[1] = gen_lowpart (Pmode, operands[1]);
5701   operands[3] = gen_lowpart (Pmode, operands[3]);
5702 }
5703   [(set_attr "type" "lea")
5704    (set_attr "mode" "SI")])
5705
5706 (define_insn_and_split "*lea_general_3"
5707   [(set (match_operand 0 "register_operand" "=r")
5708         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5709                           (match_operand 2 "const248_operand" "i"))
5710                     (match_operand 3 "register_operand" "r"))
5711               (match_operand 4 "immediate_operand" "i")))]
5712   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5713     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5714    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5715    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5716    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5717   "#"
5718   "&& reload_completed"
5719   [(const_int 0)]
5720 {
5721   rtx pat;
5722   operands[0] = gen_lowpart (SImode, operands[0]);
5723   operands[1] = gen_lowpart (Pmode, operands[1]);
5724   operands[3] = gen_lowpart (Pmode, operands[3]);
5725   operands[4] = gen_lowpart (Pmode, operands[4]);
5726   pat = gen_rtx_PLUS (Pmode,
5727                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5728                                                          operands[2]),
5729                                     operands[3]),
5730                       operands[4]);
5731   if (Pmode != SImode)
5732     pat = gen_rtx_SUBREG (SImode, pat, 0);
5733   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5734   DONE;
5735 }
5736   [(set_attr "type" "lea")
5737    (set_attr "mode" "SI")])
5738
5739 (define_insn_and_split "*lea_general_3_zext"
5740   [(set (match_operand:DI 0 "register_operand" "=r")
5741         (zero_extend:DI
5742           (plus:SI (plus:SI (mult:SI
5743                               (match_operand:SI 1 "index_register_operand" "l")
5744                               (match_operand:SI 2 "const248_operand" "n"))
5745                             (match_operand:SI 3 "register_operand" "r"))
5746                    (match_operand:SI 4 "immediate_operand" "i"))))]
5747   "TARGET_64BIT"
5748   "#"
5749   "&& reload_completed"
5750   [(set (match_dup 0)
5751         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5752                                                               (match_dup 2))
5753                                                      (match_dup 3))
5754                                             (match_dup 4)) 0)))]
5755 {
5756   operands[1] = gen_lowpart (Pmode, operands[1]);
5757   operands[3] = gen_lowpart (Pmode, operands[3]);
5758   operands[4] = gen_lowpart (Pmode, operands[4]);
5759 }
5760   [(set_attr "type" "lea")
5761    (set_attr "mode" "SI")])
5762
5763 (define_insn "*adddi_1_rex64"
5764   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5765         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5766                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5767    (clobber (reg:CC FLAGS_REG))]
5768   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5769 {
5770   switch (get_attr_type (insn))
5771     {
5772     case TYPE_LEA:
5773       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5774       return "lea{q}\t{%a2, %0|%0, %a2}";
5775
5776     case TYPE_INCDEC:
5777       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5778       if (operands[2] == const1_rtx)
5779         return "inc{q}\t%0";
5780       else
5781         {
5782           gcc_assert (operands[2] == constm1_rtx);
5783           return "dec{q}\t%0";
5784         }
5785
5786     default:
5787       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5788
5789       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5790          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5791       if (CONST_INT_P (operands[2])
5792           /* Avoid overflows.  */
5793           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5794           && (INTVAL (operands[2]) == 128
5795               || (INTVAL (operands[2]) < 0
5796                   && INTVAL (operands[2]) != -128)))
5797         {
5798           operands[2] = GEN_INT (-INTVAL (operands[2]));
5799           return "sub{q}\t{%2, %0|%0, %2}";
5800         }
5801       return "add{q}\t{%2, %0|%0, %2}";
5802     }
5803 }
5804   [(set (attr "type")
5805      (cond [(eq_attr "alternative" "2")
5806               (const_string "lea")
5807             ; Current assemblers are broken and do not allow @GOTOFF in
5808             ; ought but a memory context.
5809             (match_operand:DI 2 "pic_symbolic_operand" "")
5810               (const_string "lea")
5811             (match_operand:DI 2 "incdec_operand" "")
5812               (const_string "incdec")
5813            ]
5814            (const_string "alu")))
5815    (set_attr "mode" "DI")])
5816
5817 ;; Convert lea to the lea pattern to avoid flags dependency.
5818 (define_split
5819   [(set (match_operand:DI 0 "register_operand" "")
5820         (plus:DI (match_operand:DI 1 "register_operand" "")
5821                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5822    (clobber (reg:CC FLAGS_REG))]
5823   "TARGET_64BIT && reload_completed
5824    && true_regnum (operands[0]) != true_regnum (operands[1])"
5825   [(set (match_dup 0)
5826         (plus:DI (match_dup 1)
5827                  (match_dup 2)))]
5828   "")
5829
5830 (define_insn "*adddi_2_rex64"
5831   [(set (reg FLAGS_REG)
5832         (compare
5833           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5834                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5835           (const_int 0)))
5836    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5837         (plus:DI (match_dup 1) (match_dup 2)))]
5838   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5839    && ix86_binary_operator_ok (PLUS, DImode, operands)
5840    /* Current assemblers are broken and do not allow @GOTOFF in
5841       ought but a memory context.  */
5842    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5843 {
5844   switch (get_attr_type (insn))
5845     {
5846     case TYPE_INCDEC:
5847       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5848       if (operands[2] == const1_rtx)
5849         return "inc{q}\t%0";
5850       else
5851         {
5852           gcc_assert (operands[2] == constm1_rtx);
5853           return "dec{q}\t%0";
5854         }
5855
5856     default:
5857       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5858       /* ???? We ought to handle there the 32bit case too
5859          - do we need new constraint?  */
5860       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5861          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5862       if (CONST_INT_P (operands[2])
5863           /* Avoid overflows.  */
5864           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5865           && (INTVAL (operands[2]) == 128
5866               || (INTVAL (operands[2]) < 0
5867                   && INTVAL (operands[2]) != -128)))
5868         {
5869           operands[2] = GEN_INT (-INTVAL (operands[2]));
5870           return "sub{q}\t{%2, %0|%0, %2}";
5871         }
5872       return "add{q}\t{%2, %0|%0, %2}";
5873     }
5874 }
5875   [(set (attr "type")
5876      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5877         (const_string "incdec")
5878         (const_string "alu")))
5879    (set_attr "mode" "DI")])
5880
5881 (define_insn "*adddi_3_rex64"
5882   [(set (reg FLAGS_REG)
5883         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5884                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5885    (clobber (match_scratch:DI 0 "=r"))]
5886   "TARGET_64BIT
5887    && ix86_match_ccmode (insn, CCZmode)
5888    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5889    /* Current assemblers are broken and do not allow @GOTOFF in
5890       ought but a memory context.  */
5891    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5892 {
5893   switch (get_attr_type (insn))
5894     {
5895     case TYPE_INCDEC:
5896       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5897       if (operands[2] == const1_rtx)
5898         return "inc{q}\t%0";
5899       else
5900         {
5901           gcc_assert (operands[2] == constm1_rtx);
5902           return "dec{q}\t%0";
5903         }
5904
5905     default:
5906       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5907       /* ???? We ought to handle there the 32bit case too
5908          - do we need new constraint?  */
5909       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5910          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5911       if (CONST_INT_P (operands[2])
5912           /* Avoid overflows.  */
5913           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5914           && (INTVAL (operands[2]) == 128
5915               || (INTVAL (operands[2]) < 0
5916                   && INTVAL (operands[2]) != -128)))
5917         {
5918           operands[2] = GEN_INT (-INTVAL (operands[2]));
5919           return "sub{q}\t{%2, %0|%0, %2}";
5920         }
5921       return "add{q}\t{%2, %0|%0, %2}";
5922     }
5923 }
5924   [(set (attr "type")
5925      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5926         (const_string "incdec")
5927         (const_string "alu")))
5928    (set_attr "mode" "DI")])
5929
5930 ; For comparisons against 1, -1 and 128, we may generate better code
5931 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5932 ; is matched then.  We can't accept general immediate, because for
5933 ; case of overflows,  the result is messed up.
5934 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5935 ; when negated.
5936 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5937 ; only for comparisons not depending on it.
5938 (define_insn "*adddi_4_rex64"
5939   [(set (reg FLAGS_REG)
5940         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5941                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5942    (clobber (match_scratch:DI 0 "=rm"))]
5943   "TARGET_64BIT
5944    &&  ix86_match_ccmode (insn, CCGCmode)"
5945 {
5946   switch (get_attr_type (insn))
5947     {
5948     case TYPE_INCDEC:
5949       if (operands[2] == constm1_rtx)
5950         return "inc{q}\t%0";
5951       else
5952         {
5953           gcc_assert (operands[2] == const1_rtx);
5954           return "dec{q}\t%0";
5955         }
5956
5957     default:
5958       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5959       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5960          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5961       if ((INTVAL (operands[2]) == -128
5962            || (INTVAL (operands[2]) > 0
5963                && INTVAL (operands[2]) != 128))
5964           /* Avoid overflows.  */
5965           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5966         return "sub{q}\t{%2, %0|%0, %2}";
5967       operands[2] = GEN_INT (-INTVAL (operands[2]));
5968       return "add{q}\t{%2, %0|%0, %2}";
5969     }
5970 }
5971   [(set (attr "type")
5972      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5973         (const_string "incdec")
5974         (const_string "alu")))
5975    (set_attr "mode" "DI")])
5976
5977 (define_insn "*adddi_5_rex64"
5978   [(set (reg FLAGS_REG)
5979         (compare
5980           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5981                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5982           (const_int 0)))
5983    (clobber (match_scratch:DI 0 "=r"))]
5984   "TARGET_64BIT
5985    && ix86_match_ccmode (insn, CCGOCmode)
5986    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5987    /* Current assemblers are broken and do not allow @GOTOFF in
5988       ought but a memory context.  */
5989    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5990 {
5991   switch (get_attr_type (insn))
5992     {
5993     case TYPE_INCDEC:
5994       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5995       if (operands[2] == const1_rtx)
5996         return "inc{q}\t%0";
5997       else
5998         {
5999           gcc_assert (operands[2] == constm1_rtx);
6000           return "dec{q}\t%0";
6001         }
6002
6003     default:
6004       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6005       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6006          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6007       if (CONST_INT_P (operands[2])
6008           /* Avoid overflows.  */
6009           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6010           && (INTVAL (operands[2]) == 128
6011               || (INTVAL (operands[2]) < 0
6012                   && INTVAL (operands[2]) != -128)))
6013         {
6014           operands[2] = GEN_INT (-INTVAL (operands[2]));
6015           return "sub{q}\t{%2, %0|%0, %2}";
6016         }
6017       return "add{q}\t{%2, %0|%0, %2}";
6018     }
6019 }
6020   [(set (attr "type")
6021      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6022         (const_string "incdec")
6023         (const_string "alu")))
6024    (set_attr "mode" "DI")])
6025
6026
6027 (define_insn "*addsi_1"
6028   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6029         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6030                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
6031    (clobber (reg:CC FLAGS_REG))]
6032   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6033 {
6034   switch (get_attr_type (insn))
6035     {
6036     case TYPE_LEA:
6037       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6038       return "lea{l}\t{%a2, %0|%0, %a2}";
6039
6040     case TYPE_INCDEC:
6041       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6042       if (operands[2] == const1_rtx)
6043         return "inc{l}\t%0";
6044       else
6045         {
6046           gcc_assert (operands[2] == constm1_rtx);
6047           return "dec{l}\t%0";
6048         }
6049
6050     default:
6051       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6052
6053       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6054          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6055       if (CONST_INT_P (operands[2])
6056           && (INTVAL (operands[2]) == 128
6057               || (INTVAL (operands[2]) < 0
6058                   && INTVAL (operands[2]) != -128)))
6059         {
6060           operands[2] = GEN_INT (-INTVAL (operands[2]));
6061           return "sub{l}\t{%2, %0|%0, %2}";
6062         }
6063       return "add{l}\t{%2, %0|%0, %2}";
6064     }
6065 }
6066   [(set (attr "type")
6067      (cond [(eq_attr "alternative" "2")
6068               (const_string "lea")
6069             ; Current assemblers are broken and do not allow @GOTOFF in
6070             ; ought but a memory context.
6071             (match_operand:SI 2 "pic_symbolic_operand" "")
6072               (const_string "lea")
6073             (match_operand:SI 2 "incdec_operand" "")
6074               (const_string "incdec")
6075            ]
6076            (const_string "alu")))
6077    (set_attr "mode" "SI")])
6078
6079 ;; Convert lea to the lea pattern to avoid flags dependency.
6080 (define_split
6081   [(set (match_operand 0 "register_operand" "")
6082         (plus (match_operand 1 "register_operand" "")
6083               (match_operand 2 "nonmemory_operand" "")))
6084    (clobber (reg:CC FLAGS_REG))]
6085   "reload_completed
6086    && true_regnum (operands[0]) != true_regnum (operands[1])"
6087   [(const_int 0)]
6088 {
6089   rtx pat;
6090   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6091      may confuse gen_lowpart.  */
6092   if (GET_MODE (operands[0]) != Pmode)
6093     {
6094       operands[1] = gen_lowpart (Pmode, operands[1]);
6095       operands[2] = gen_lowpart (Pmode, operands[2]);
6096     }
6097   operands[0] = gen_lowpart (SImode, operands[0]);
6098   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6099   if (Pmode != SImode)
6100     pat = gen_rtx_SUBREG (SImode, pat, 0);
6101   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6102   DONE;
6103 })
6104
6105 ;; It may seem that nonimmediate operand is proper one for operand 1.
6106 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6107 ;; we take care in ix86_binary_operator_ok to not allow two memory
6108 ;; operands so proper swapping will be done in reload.  This allow
6109 ;; patterns constructed from addsi_1 to match.
6110 (define_insn "addsi_1_zext"
6111   [(set (match_operand:DI 0 "register_operand" "=r,r")
6112         (zero_extend:DI
6113           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6114                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
6115    (clobber (reg:CC FLAGS_REG))]
6116   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6117 {
6118   switch (get_attr_type (insn))
6119     {
6120     case TYPE_LEA:
6121       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6122       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6123
6124     case TYPE_INCDEC:
6125       if (operands[2] == const1_rtx)
6126         return "inc{l}\t%k0";
6127       else
6128         {
6129           gcc_assert (operands[2] == constm1_rtx);
6130           return "dec{l}\t%k0";
6131         }
6132
6133     default:
6134       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6135          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6136       if (CONST_INT_P (operands[2])
6137           && (INTVAL (operands[2]) == 128
6138               || (INTVAL (operands[2]) < 0
6139                   && INTVAL (operands[2]) != -128)))
6140         {
6141           operands[2] = GEN_INT (-INTVAL (operands[2]));
6142           return "sub{l}\t{%2, %k0|%k0, %2}";
6143         }
6144       return "add{l}\t{%2, %k0|%k0, %2}";
6145     }
6146 }
6147   [(set (attr "type")
6148      (cond [(eq_attr "alternative" "1")
6149               (const_string "lea")
6150             ; Current assemblers are broken and do not allow @GOTOFF in
6151             ; ought but a memory context.
6152             (match_operand:SI 2 "pic_symbolic_operand" "")
6153               (const_string "lea")
6154             (match_operand:SI 2 "incdec_operand" "")
6155               (const_string "incdec")
6156            ]
6157            (const_string "alu")))
6158    (set_attr "mode" "SI")])
6159
6160 ;; Convert lea to the lea pattern to avoid flags dependency.
6161 (define_split
6162   [(set (match_operand:DI 0 "register_operand" "")
6163         (zero_extend:DI
6164           (plus:SI (match_operand:SI 1 "register_operand" "")
6165                    (match_operand:SI 2 "nonmemory_operand" ""))))
6166    (clobber (reg:CC FLAGS_REG))]
6167   "TARGET_64BIT && reload_completed
6168    && true_regnum (operands[0]) != true_regnum (operands[1])"
6169   [(set (match_dup 0)
6170         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6171 {
6172   operands[1] = gen_lowpart (Pmode, operands[1]);
6173   operands[2] = gen_lowpart (Pmode, operands[2]);
6174 })
6175
6176 (define_insn "*addsi_2"
6177   [(set (reg FLAGS_REG)
6178         (compare
6179           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6180                    (match_operand:SI 2 "general_operand" "rmni,rni"))
6181           (const_int 0)))
6182    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6183         (plus:SI (match_dup 1) (match_dup 2)))]
6184   "ix86_match_ccmode (insn, CCGOCmode)
6185    && ix86_binary_operator_ok (PLUS, SImode, operands)
6186    /* Current assemblers are broken and do not allow @GOTOFF in
6187       ought but a memory context.  */
6188    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6189 {
6190   switch (get_attr_type (insn))
6191     {
6192     case TYPE_INCDEC:
6193       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6194       if (operands[2] == const1_rtx)
6195         return "inc{l}\t%0";
6196       else
6197         {
6198           gcc_assert (operands[2] == constm1_rtx);
6199           return "dec{l}\t%0";
6200         }
6201
6202     default:
6203       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6204       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6205          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6206       if (CONST_INT_P (operands[2])
6207           && (INTVAL (operands[2]) == 128
6208               || (INTVAL (operands[2]) < 0
6209                   && INTVAL (operands[2]) != -128)))
6210         {
6211           operands[2] = GEN_INT (-INTVAL (operands[2]));
6212           return "sub{l}\t{%2, %0|%0, %2}";
6213         }
6214       return "add{l}\t{%2, %0|%0, %2}";
6215     }
6216 }
6217   [(set (attr "type")
6218      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6219         (const_string "incdec")
6220         (const_string "alu")))
6221    (set_attr "mode" "SI")])
6222
6223 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6224 (define_insn "*addsi_2_zext"
6225   [(set (reg FLAGS_REG)
6226         (compare
6227           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6228                    (match_operand:SI 2 "general_operand" "rmni"))
6229           (const_int 0)))
6230    (set (match_operand:DI 0 "register_operand" "=r")
6231         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6232   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6233    && ix86_binary_operator_ok (PLUS, SImode, operands)
6234    /* Current assemblers are broken and do not allow @GOTOFF in
6235       ought but a memory context.  */
6236    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6237 {
6238   switch (get_attr_type (insn))
6239     {
6240     case TYPE_INCDEC:
6241       if (operands[2] == const1_rtx)
6242         return "inc{l}\t%k0";
6243       else
6244         {
6245           gcc_assert (operands[2] == constm1_rtx);
6246           return "dec{l}\t%k0";
6247         }
6248
6249     default:
6250       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6251          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6252       if (CONST_INT_P (operands[2])
6253           && (INTVAL (operands[2]) == 128
6254               || (INTVAL (operands[2]) < 0
6255                   && INTVAL (operands[2]) != -128)))
6256         {
6257           operands[2] = GEN_INT (-INTVAL (operands[2]));
6258           return "sub{l}\t{%2, %k0|%k0, %2}";
6259         }
6260       return "add{l}\t{%2, %k0|%k0, %2}";
6261     }
6262 }
6263   [(set (attr "type")
6264      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6265         (const_string "incdec")
6266         (const_string "alu")))
6267    (set_attr "mode" "SI")])
6268
6269 (define_insn "*addsi_3"
6270   [(set (reg FLAGS_REG)
6271         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6272                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6273    (clobber (match_scratch:SI 0 "=r"))]
6274   "ix86_match_ccmode (insn, CCZmode)
6275    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6276    /* Current assemblers are broken and do not allow @GOTOFF in
6277       ought but a memory context.  */
6278    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6279 {
6280   switch (get_attr_type (insn))
6281     {
6282     case TYPE_INCDEC:
6283       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6284       if (operands[2] == const1_rtx)
6285         return "inc{l}\t%0";
6286       else
6287         {
6288           gcc_assert (operands[2] == constm1_rtx);
6289           return "dec{l}\t%0";
6290         }
6291
6292     default:
6293       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6294       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6295          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6296       if (CONST_INT_P (operands[2])
6297           && (INTVAL (operands[2]) == 128
6298               || (INTVAL (operands[2]) < 0
6299                   && INTVAL (operands[2]) != -128)))
6300         {
6301           operands[2] = GEN_INT (-INTVAL (operands[2]));
6302           return "sub{l}\t{%2, %0|%0, %2}";
6303         }
6304       return "add{l}\t{%2, %0|%0, %2}";
6305     }
6306 }
6307   [(set (attr "type")
6308      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6309         (const_string "incdec")
6310         (const_string "alu")))
6311    (set_attr "mode" "SI")])
6312
6313 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6314 (define_insn "*addsi_3_zext"
6315   [(set (reg FLAGS_REG)
6316         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6317                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6318    (set (match_operand:DI 0 "register_operand" "=r")
6319         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6320   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6321    && ix86_binary_operator_ok (PLUS, SImode, operands)
6322    /* Current assemblers are broken and do not allow @GOTOFF in
6323       ought but a memory context.  */
6324    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6325 {
6326   switch (get_attr_type (insn))
6327     {
6328     case TYPE_INCDEC:
6329       if (operands[2] == const1_rtx)
6330         return "inc{l}\t%k0";
6331       else
6332         {
6333           gcc_assert (operands[2] == constm1_rtx);
6334           return "dec{l}\t%k0";
6335         }
6336
6337     default:
6338       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6339          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6340       if (CONST_INT_P (operands[2])
6341           && (INTVAL (operands[2]) == 128
6342               || (INTVAL (operands[2]) < 0
6343                   && INTVAL (operands[2]) != -128)))
6344         {
6345           operands[2] = GEN_INT (-INTVAL (operands[2]));
6346           return "sub{l}\t{%2, %k0|%k0, %2}";
6347         }
6348       return "add{l}\t{%2, %k0|%k0, %2}";
6349     }
6350 }
6351   [(set (attr "type")
6352      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6353         (const_string "incdec")
6354         (const_string "alu")))
6355    (set_attr "mode" "SI")])
6356
6357 ; For comparisons against 1, -1 and 128, we may generate better code
6358 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6359 ; is matched then.  We can't accept general immediate, because for
6360 ; case of overflows,  the result is messed up.
6361 ; This pattern also don't hold of 0x80000000, since the value overflows
6362 ; when negated.
6363 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6364 ; only for comparisons not depending on it.
6365 (define_insn "*addsi_4"
6366   [(set (reg FLAGS_REG)
6367         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6368                  (match_operand:SI 2 "const_int_operand" "n")))
6369    (clobber (match_scratch:SI 0 "=rm"))]
6370   "ix86_match_ccmode (insn, CCGCmode)
6371    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6372 {
6373   switch (get_attr_type (insn))
6374     {
6375     case TYPE_INCDEC:
6376       if (operands[2] == constm1_rtx)
6377         return "inc{l}\t%0";
6378       else
6379         {
6380           gcc_assert (operands[2] == const1_rtx);
6381           return "dec{l}\t%0";
6382         }
6383
6384     default:
6385       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6386       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6387          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6388       if ((INTVAL (operands[2]) == -128
6389            || (INTVAL (operands[2]) > 0
6390                && INTVAL (operands[2]) != 128)))
6391         return "sub{l}\t{%2, %0|%0, %2}";
6392       operands[2] = GEN_INT (-INTVAL (operands[2]));
6393       return "add{l}\t{%2, %0|%0, %2}";
6394     }
6395 }
6396   [(set (attr "type")
6397      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6398         (const_string "incdec")
6399         (const_string "alu")))
6400    (set_attr "mode" "SI")])
6401
6402 (define_insn "*addsi_5"
6403   [(set (reg FLAGS_REG)
6404         (compare
6405           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6406                    (match_operand:SI 2 "general_operand" "rmni"))
6407           (const_int 0)))
6408    (clobber (match_scratch:SI 0 "=r"))]
6409   "ix86_match_ccmode (insn, CCGOCmode)
6410    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6411    /* Current assemblers are broken and do not allow @GOTOFF in
6412       ought but a memory context.  */
6413    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6414 {
6415   switch (get_attr_type (insn))
6416     {
6417     case TYPE_INCDEC:
6418       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6419       if (operands[2] == const1_rtx)
6420         return "inc{l}\t%0";
6421       else
6422         {
6423           gcc_assert (operands[2] == constm1_rtx);
6424           return "dec{l}\t%0";
6425         }
6426
6427     default:
6428       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6429       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6430          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6431       if (CONST_INT_P (operands[2])
6432           && (INTVAL (operands[2]) == 128
6433               || (INTVAL (operands[2]) < 0
6434                   && INTVAL (operands[2]) != -128)))
6435         {
6436           operands[2] = GEN_INT (-INTVAL (operands[2]));
6437           return "sub{l}\t{%2, %0|%0, %2}";
6438         }
6439       return "add{l}\t{%2, %0|%0, %2}";
6440     }
6441 }
6442   [(set (attr "type")
6443      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6444         (const_string "incdec")
6445         (const_string "alu")))
6446    (set_attr "mode" "SI")])
6447
6448 (define_expand "addhi3"
6449   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6450                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6451                             (match_operand:HI 2 "general_operand" "")))
6452               (clobber (reg:CC FLAGS_REG))])]
6453   "TARGET_HIMODE_MATH"
6454   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6455
6456 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6457 ;; type optimizations enabled by define-splits.  This is not important
6458 ;; for PII, and in fact harmful because of partial register stalls.
6459
6460 (define_insn "*addhi_1_lea"
6461   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6462         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6463                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6464    (clobber (reg:CC FLAGS_REG))]
6465   "!TARGET_PARTIAL_REG_STALL
6466    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6467 {
6468   switch (get_attr_type (insn))
6469     {
6470     case TYPE_LEA:
6471       return "#";
6472     case TYPE_INCDEC:
6473       if (operands[2] == const1_rtx)
6474         return "inc{w}\t%0";
6475       else
6476         {
6477           gcc_assert (operands[2] == constm1_rtx);
6478           return "dec{w}\t%0";
6479         }
6480
6481     default:
6482       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6483          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6484       if (CONST_INT_P (operands[2])
6485           && (INTVAL (operands[2]) == 128
6486               || (INTVAL (operands[2]) < 0
6487                   && INTVAL (operands[2]) != -128)))
6488         {
6489           operands[2] = GEN_INT (-INTVAL (operands[2]));
6490           return "sub{w}\t{%2, %0|%0, %2}";
6491         }
6492       return "add{w}\t{%2, %0|%0, %2}";
6493     }
6494 }
6495   [(set (attr "type")
6496      (if_then_else (eq_attr "alternative" "2")
6497         (const_string "lea")
6498         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6499            (const_string "incdec")
6500            (const_string "alu"))))
6501    (set_attr "mode" "HI,HI,SI")])
6502
6503 (define_insn "*addhi_1"
6504   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6505         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6506                  (match_operand:HI 2 "general_operand" "ri,rm")))
6507    (clobber (reg:CC FLAGS_REG))]
6508   "TARGET_PARTIAL_REG_STALL
6509    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6510 {
6511   switch (get_attr_type (insn))
6512     {
6513     case TYPE_INCDEC:
6514       if (operands[2] == const1_rtx)
6515         return "inc{w}\t%0";
6516       else
6517         {
6518           gcc_assert (operands[2] == constm1_rtx);
6519           return "dec{w}\t%0";
6520         }
6521
6522     default:
6523       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6524          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6525       if (CONST_INT_P (operands[2])
6526           && (INTVAL (operands[2]) == 128
6527               || (INTVAL (operands[2]) < 0
6528                   && INTVAL (operands[2]) != -128)))
6529         {
6530           operands[2] = GEN_INT (-INTVAL (operands[2]));
6531           return "sub{w}\t{%2, %0|%0, %2}";
6532         }
6533       return "add{w}\t{%2, %0|%0, %2}";
6534     }
6535 }
6536   [(set (attr "type")
6537      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6538         (const_string "incdec")
6539         (const_string "alu")))
6540    (set_attr "mode" "HI")])
6541
6542 (define_insn "*addhi_2"
6543   [(set (reg FLAGS_REG)
6544         (compare
6545           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6546                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6547           (const_int 0)))
6548    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6549         (plus:HI (match_dup 1) (match_dup 2)))]
6550   "ix86_match_ccmode (insn, CCGOCmode)
6551    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6552 {
6553   switch (get_attr_type (insn))
6554     {
6555     case TYPE_INCDEC:
6556       if (operands[2] == const1_rtx)
6557         return "inc{w}\t%0";
6558       else
6559         {
6560           gcc_assert (operands[2] == constm1_rtx);
6561           return "dec{w}\t%0";
6562         }
6563
6564     default:
6565       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6566          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6567       if (CONST_INT_P (operands[2])
6568           && (INTVAL (operands[2]) == 128
6569               || (INTVAL (operands[2]) < 0
6570                   && INTVAL (operands[2]) != -128)))
6571         {
6572           operands[2] = GEN_INT (-INTVAL (operands[2]));
6573           return "sub{w}\t{%2, %0|%0, %2}";
6574         }
6575       return "add{w}\t{%2, %0|%0, %2}";
6576     }
6577 }
6578   [(set (attr "type")
6579      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6580         (const_string "incdec")
6581         (const_string "alu")))
6582    (set_attr "mode" "HI")])
6583
6584 (define_insn "*addhi_3"
6585   [(set (reg FLAGS_REG)
6586         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6587                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6588    (clobber (match_scratch:HI 0 "=r"))]
6589   "ix86_match_ccmode (insn, CCZmode)
6590    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6591 {
6592   switch (get_attr_type (insn))
6593     {
6594     case TYPE_INCDEC:
6595       if (operands[2] == const1_rtx)
6596         return "inc{w}\t%0";
6597       else
6598         {
6599           gcc_assert (operands[2] == constm1_rtx);
6600           return "dec{w}\t%0";
6601         }
6602
6603     default:
6604       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6605          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6606       if (CONST_INT_P (operands[2])
6607           && (INTVAL (operands[2]) == 128
6608               || (INTVAL (operands[2]) < 0
6609                   && INTVAL (operands[2]) != -128)))
6610         {
6611           operands[2] = GEN_INT (-INTVAL (operands[2]));
6612           return "sub{w}\t{%2, %0|%0, %2}";
6613         }
6614       return "add{w}\t{%2, %0|%0, %2}";
6615     }
6616 }
6617   [(set (attr "type")
6618      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6619         (const_string "incdec")
6620         (const_string "alu")))
6621    (set_attr "mode" "HI")])
6622
6623 ; See comments above addsi_4 for details.
6624 (define_insn "*addhi_4"
6625   [(set (reg FLAGS_REG)
6626         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6627                  (match_operand:HI 2 "const_int_operand" "n")))
6628    (clobber (match_scratch:HI 0 "=rm"))]
6629   "ix86_match_ccmode (insn, CCGCmode)
6630    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6631 {
6632   switch (get_attr_type (insn))
6633     {
6634     case TYPE_INCDEC:
6635       if (operands[2] == constm1_rtx)
6636         return "inc{w}\t%0";
6637       else
6638         {
6639           gcc_assert (operands[2] == const1_rtx);
6640           return "dec{w}\t%0";
6641         }
6642
6643     default:
6644       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6645       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6646          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6647       if ((INTVAL (operands[2]) == -128
6648            || (INTVAL (operands[2]) > 0
6649                && INTVAL (operands[2]) != 128)))
6650         return "sub{w}\t{%2, %0|%0, %2}";
6651       operands[2] = GEN_INT (-INTVAL (operands[2]));
6652       return "add{w}\t{%2, %0|%0, %2}";
6653     }
6654 }
6655   [(set (attr "type")
6656      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6657         (const_string "incdec")
6658         (const_string "alu")))
6659    (set_attr "mode" "SI")])
6660
6661
6662 (define_insn "*addhi_5"
6663   [(set (reg FLAGS_REG)
6664         (compare
6665           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6666                    (match_operand:HI 2 "general_operand" "rmni"))
6667           (const_int 0)))
6668    (clobber (match_scratch:HI 0 "=r"))]
6669   "ix86_match_ccmode (insn, CCGOCmode)
6670    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6671 {
6672   switch (get_attr_type (insn))
6673     {
6674     case TYPE_INCDEC:
6675       if (operands[2] == const1_rtx)
6676         return "inc{w}\t%0";
6677       else
6678         {
6679           gcc_assert (operands[2] == constm1_rtx);
6680           return "dec{w}\t%0";
6681         }
6682
6683     default:
6684       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6685          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6686       if (CONST_INT_P (operands[2])
6687           && (INTVAL (operands[2]) == 128
6688               || (INTVAL (operands[2]) < 0
6689                   && INTVAL (operands[2]) != -128)))
6690         {
6691           operands[2] = GEN_INT (-INTVAL (operands[2]));
6692           return "sub{w}\t{%2, %0|%0, %2}";
6693         }
6694       return "add{w}\t{%2, %0|%0, %2}";
6695     }
6696 }
6697   [(set (attr "type")
6698      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6699         (const_string "incdec")
6700         (const_string "alu")))
6701    (set_attr "mode" "HI")])
6702
6703 (define_expand "addqi3"
6704   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6705                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6706                             (match_operand:QI 2 "general_operand" "")))
6707               (clobber (reg:CC FLAGS_REG))])]
6708   "TARGET_QIMODE_MATH"
6709   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6710
6711 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6712 (define_insn "*addqi_1_lea"
6713   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6714         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6715                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6716    (clobber (reg:CC FLAGS_REG))]
6717   "!TARGET_PARTIAL_REG_STALL
6718    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6719 {
6720   int widen = (which_alternative == 2);
6721   switch (get_attr_type (insn))
6722     {
6723     case TYPE_LEA:
6724       return "#";
6725     case TYPE_INCDEC:
6726       if (operands[2] == const1_rtx)
6727         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6728       else
6729         {
6730           gcc_assert (operands[2] == constm1_rtx);
6731           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6732         }
6733
6734     default:
6735       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6736          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6737       if (CONST_INT_P (operands[2])
6738           && (INTVAL (operands[2]) == 128
6739               || (INTVAL (operands[2]) < 0
6740                   && INTVAL (operands[2]) != -128)))
6741         {
6742           operands[2] = GEN_INT (-INTVAL (operands[2]));
6743           if (widen)
6744             return "sub{l}\t{%2, %k0|%k0, %2}";
6745           else
6746             return "sub{b}\t{%2, %0|%0, %2}";
6747         }
6748       if (widen)
6749         return "add{l}\t{%k2, %k0|%k0, %k2}";
6750       else
6751         return "add{b}\t{%2, %0|%0, %2}";
6752     }
6753 }
6754   [(set (attr "type")
6755      (if_then_else (eq_attr "alternative" "3")
6756         (const_string "lea")
6757         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6758            (const_string "incdec")
6759            (const_string "alu"))))
6760    (set_attr "mode" "QI,QI,SI,SI")])
6761
6762 (define_insn "*addqi_1"
6763   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6764         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6765                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6766    (clobber (reg:CC FLAGS_REG))]
6767   "TARGET_PARTIAL_REG_STALL
6768    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6769 {
6770   int widen = (which_alternative == 2);
6771   switch (get_attr_type (insn))
6772     {
6773     case TYPE_INCDEC:
6774       if (operands[2] == const1_rtx)
6775         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6776       else
6777         {
6778           gcc_assert (operands[2] == constm1_rtx);
6779           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6780         }
6781
6782     default:
6783       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6784          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6785       if (CONST_INT_P (operands[2])
6786           && (INTVAL (operands[2]) == 128
6787               || (INTVAL (operands[2]) < 0
6788                   && INTVAL (operands[2]) != -128)))
6789         {
6790           operands[2] = GEN_INT (-INTVAL (operands[2]));
6791           if (widen)
6792             return "sub{l}\t{%2, %k0|%k0, %2}";
6793           else
6794             return "sub{b}\t{%2, %0|%0, %2}";
6795         }
6796       if (widen)
6797         return "add{l}\t{%k2, %k0|%k0, %k2}";
6798       else
6799         return "add{b}\t{%2, %0|%0, %2}";
6800     }
6801 }
6802   [(set (attr "type")
6803      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6804         (const_string "incdec")
6805         (const_string "alu")))
6806    (set_attr "mode" "QI,QI,SI")])
6807
6808 (define_insn "*addqi_1_slp"
6809   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6810         (plus:QI (match_dup 0)
6811                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6812    (clobber (reg:CC FLAGS_REG))]
6813   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6814    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6815 {
6816   switch (get_attr_type (insn))
6817     {
6818     case TYPE_INCDEC:
6819       if (operands[1] == const1_rtx)
6820         return "inc{b}\t%0";
6821       else
6822         {
6823           gcc_assert (operands[1] == constm1_rtx);
6824           return "dec{b}\t%0";
6825         }
6826
6827     default:
6828       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6829       if (CONST_INT_P (operands[1])
6830           && INTVAL (operands[1]) < 0)
6831         {
6832           operands[1] = GEN_INT (-INTVAL (operands[1]));
6833           return "sub{b}\t{%1, %0|%0, %1}";
6834         }
6835       return "add{b}\t{%1, %0|%0, %1}";
6836     }
6837 }
6838   [(set (attr "type")
6839      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6840         (const_string "incdec")
6841         (const_string "alu1")))
6842    (set (attr "memory")
6843      (if_then_else (match_operand 1 "memory_operand" "")
6844         (const_string "load")
6845         (const_string "none")))
6846    (set_attr "mode" "QI")])
6847
6848 (define_insn "*addqi_2"
6849   [(set (reg FLAGS_REG)
6850         (compare
6851           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6852                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6853           (const_int 0)))
6854    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6855         (plus:QI (match_dup 1) (match_dup 2)))]
6856   "ix86_match_ccmode (insn, CCGOCmode)
6857    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6858 {
6859   switch (get_attr_type (insn))
6860     {
6861     case TYPE_INCDEC:
6862       if (operands[2] == const1_rtx)
6863         return "inc{b}\t%0";
6864       else
6865         {
6866           gcc_assert (operands[2] == constm1_rtx
6867                       || (CONST_INT_P (operands[2])
6868                           && INTVAL (operands[2]) == 255));
6869           return "dec{b}\t%0";
6870         }
6871
6872     default:
6873       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6874       if (CONST_INT_P (operands[2])
6875           && INTVAL (operands[2]) < 0)
6876         {
6877           operands[2] = GEN_INT (-INTVAL (operands[2]));
6878           return "sub{b}\t{%2, %0|%0, %2}";
6879         }
6880       return "add{b}\t{%2, %0|%0, %2}";
6881     }
6882 }
6883   [(set (attr "type")
6884      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6885         (const_string "incdec")
6886         (const_string "alu")))
6887    (set_attr "mode" "QI")])
6888
6889 (define_insn "*addqi_3"
6890   [(set (reg FLAGS_REG)
6891         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6892                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6893    (clobber (match_scratch:QI 0 "=q"))]
6894   "ix86_match_ccmode (insn, CCZmode)
6895    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6896 {
6897   switch (get_attr_type (insn))
6898     {
6899     case TYPE_INCDEC:
6900       if (operands[2] == const1_rtx)
6901         return "inc{b}\t%0";
6902       else
6903         {
6904           gcc_assert (operands[2] == constm1_rtx
6905                       || (CONST_INT_P (operands[2])
6906                           && INTVAL (operands[2]) == 255));
6907           return "dec{b}\t%0";
6908         }
6909
6910     default:
6911       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6912       if (CONST_INT_P (operands[2])
6913           && INTVAL (operands[2]) < 0)
6914         {
6915           operands[2] = GEN_INT (-INTVAL (operands[2]));
6916           return "sub{b}\t{%2, %0|%0, %2}";
6917         }
6918       return "add{b}\t{%2, %0|%0, %2}";
6919     }
6920 }
6921   [(set (attr "type")
6922      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6923         (const_string "incdec")
6924         (const_string "alu")))
6925    (set_attr "mode" "QI")])
6926
6927 ; See comments above addsi_4 for details.
6928 (define_insn "*addqi_4"
6929   [(set (reg FLAGS_REG)
6930         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6931                  (match_operand:QI 2 "const_int_operand" "n")))
6932    (clobber (match_scratch:QI 0 "=qm"))]
6933   "ix86_match_ccmode (insn, CCGCmode)
6934    && (INTVAL (operands[2]) & 0xff) != 0x80"
6935 {
6936   switch (get_attr_type (insn))
6937     {
6938     case TYPE_INCDEC:
6939       if (operands[2] == constm1_rtx
6940           || (CONST_INT_P (operands[2])
6941               && INTVAL (operands[2]) == 255))
6942         return "inc{b}\t%0";
6943       else
6944         {
6945           gcc_assert (operands[2] == const1_rtx);
6946           return "dec{b}\t%0";
6947         }
6948
6949     default:
6950       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6951       if (INTVAL (operands[2]) < 0)
6952         {
6953           operands[2] = GEN_INT (-INTVAL (operands[2]));
6954           return "add{b}\t{%2, %0|%0, %2}";
6955         }
6956       return "sub{b}\t{%2, %0|%0, %2}";
6957     }
6958 }
6959   [(set (attr "type")
6960      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6961         (const_string "incdec")
6962         (const_string "alu")))
6963    (set_attr "mode" "QI")])
6964
6965
6966 (define_insn "*addqi_5"
6967   [(set (reg FLAGS_REG)
6968         (compare
6969           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6970                    (match_operand:QI 2 "general_operand" "qmni"))
6971           (const_int 0)))
6972    (clobber (match_scratch:QI 0 "=q"))]
6973   "ix86_match_ccmode (insn, CCGOCmode)
6974    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6975 {
6976   switch (get_attr_type (insn))
6977     {
6978     case TYPE_INCDEC:
6979       if (operands[2] == const1_rtx)
6980         return "inc{b}\t%0";
6981       else
6982         {
6983           gcc_assert (operands[2] == constm1_rtx
6984                       || (CONST_INT_P (operands[2])
6985                           && INTVAL (operands[2]) == 255));
6986           return "dec{b}\t%0";
6987         }
6988
6989     default:
6990       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6991       if (CONST_INT_P (operands[2])
6992           && INTVAL (operands[2]) < 0)
6993         {
6994           operands[2] = GEN_INT (-INTVAL (operands[2]));
6995           return "sub{b}\t{%2, %0|%0, %2}";
6996         }
6997       return "add{b}\t{%2, %0|%0, %2}";
6998     }
6999 }
7000   [(set (attr "type")
7001      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7002         (const_string "incdec")
7003         (const_string "alu")))
7004    (set_attr "mode" "QI")])
7005
7006
7007 (define_insn "addqi_ext_1"
7008   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7009                          (const_int 8)
7010                          (const_int 8))
7011         (plus:SI
7012           (zero_extract:SI
7013             (match_operand 1 "ext_register_operand" "0")
7014             (const_int 8)
7015             (const_int 8))
7016           (match_operand:QI 2 "general_operand" "Qmn")))
7017    (clobber (reg:CC FLAGS_REG))]
7018   "!TARGET_64BIT"
7019 {
7020   switch (get_attr_type (insn))
7021     {
7022     case TYPE_INCDEC:
7023       if (operands[2] == const1_rtx)
7024         return "inc{b}\t%h0";
7025       else
7026         {
7027           gcc_assert (operands[2] == constm1_rtx
7028                       || (CONST_INT_P (operands[2])
7029                           && INTVAL (operands[2]) == 255));
7030           return "dec{b}\t%h0";
7031         }
7032
7033     default:
7034       return "add{b}\t{%2, %h0|%h0, %2}";
7035     }
7036 }
7037   [(set (attr "type")
7038      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7039         (const_string "incdec")
7040         (const_string "alu")))
7041    (set_attr "mode" "QI")])
7042
7043 (define_insn "*addqi_ext_1_rex64"
7044   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7045                          (const_int 8)
7046                          (const_int 8))
7047         (plus:SI
7048           (zero_extract:SI
7049             (match_operand 1 "ext_register_operand" "0")
7050             (const_int 8)
7051             (const_int 8))
7052           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7053    (clobber (reg:CC FLAGS_REG))]
7054   "TARGET_64BIT"
7055 {
7056   switch (get_attr_type (insn))
7057     {
7058     case TYPE_INCDEC:
7059       if (operands[2] == const1_rtx)
7060         return "inc{b}\t%h0";
7061       else
7062         {
7063           gcc_assert (operands[2] == constm1_rtx
7064                       || (CONST_INT_P (operands[2])
7065                           && INTVAL (operands[2]) == 255));
7066           return "dec{b}\t%h0";
7067         }
7068
7069     default:
7070       return "add{b}\t{%2, %h0|%h0, %2}";
7071     }
7072 }
7073   [(set (attr "type")
7074      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7075         (const_string "incdec")
7076         (const_string "alu")))
7077    (set_attr "mode" "QI")])
7078
7079 (define_insn "*addqi_ext_2"
7080   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7081                          (const_int 8)
7082                          (const_int 8))
7083         (plus:SI
7084           (zero_extract:SI
7085             (match_operand 1 "ext_register_operand" "%0")
7086             (const_int 8)
7087             (const_int 8))
7088           (zero_extract:SI
7089             (match_operand 2 "ext_register_operand" "Q")
7090             (const_int 8)
7091             (const_int 8))))
7092    (clobber (reg:CC FLAGS_REG))]
7093   ""
7094   "add{b}\t{%h2, %h0|%h0, %h2}"
7095   [(set_attr "type" "alu")
7096    (set_attr "mode" "QI")])
7097
7098 ;; The patterns that match these are at the end of this file.
7099
7100 (define_expand "addxf3"
7101   [(set (match_operand:XF 0 "register_operand" "")
7102         (plus:XF (match_operand:XF 1 "register_operand" "")
7103                  (match_operand:XF 2 "register_operand" "")))]
7104   "TARGET_80387"
7105   "")
7106
7107 (define_expand "add<mode>3"
7108   [(set (match_operand:MODEF 0 "register_operand" "")
7109         (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7110                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7111   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7112   "")
7113 \f
7114 ;; Subtract instructions
7115
7116 ;; %%% splits for subditi3
7117
7118 (define_expand "subti3"
7119   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
7120                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7121                              (match_operand:TI 2 "x86_64_general_operand" "")))
7122               (clobber (reg:CC FLAGS_REG))])]
7123   "TARGET_64BIT"
7124   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7125
7126 (define_insn "*subti3_1"
7127   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7128         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7129                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7130    (clobber (reg:CC FLAGS_REG))]
7131   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7132   "#")
7133
7134 (define_split
7135   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7136         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7137                   (match_operand:TI 2 "x86_64_general_operand" "")))
7138    (clobber (reg:CC FLAGS_REG))]
7139   "TARGET_64BIT && reload_completed"
7140   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7141               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7142    (parallel [(set (match_dup 3)
7143                    (minus:DI (match_dup 4)
7144                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7145                                       (match_dup 5))))
7146               (clobber (reg:CC FLAGS_REG))])]
7147   "split_ti (operands+0, 1, operands+0, operands+3);
7148    split_ti (operands+1, 1, operands+1, operands+4);
7149    split_ti (operands+2, 1, operands+2, operands+5);")
7150
7151 ;; %%% splits for subsidi3
7152
7153 (define_expand "subdi3"
7154   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
7155                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7156                              (match_operand:DI 2 "x86_64_general_operand" "")))
7157               (clobber (reg:CC FLAGS_REG))])]
7158   ""
7159   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7160
7161 (define_insn "*subdi3_1"
7162   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7163         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7164                   (match_operand:DI 2 "general_operand" "roiF,riF")))
7165    (clobber (reg:CC FLAGS_REG))]
7166   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7167   "#")
7168
7169 (define_split
7170   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7171         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7172                   (match_operand:DI 2 "general_operand" "")))
7173    (clobber (reg:CC FLAGS_REG))]
7174   "!TARGET_64BIT && reload_completed"
7175   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7176               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7177    (parallel [(set (match_dup 3)
7178                    (minus:SI (match_dup 4)
7179                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7180                                       (match_dup 5))))
7181               (clobber (reg:CC FLAGS_REG))])]
7182   "split_di (operands+0, 1, operands+0, operands+3);
7183    split_di (operands+1, 1, operands+1, operands+4);
7184    split_di (operands+2, 1, operands+2, operands+5);")
7185
7186 (define_insn "subdi3_carry_rex64"
7187   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7188           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7189             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7190                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7191    (clobber (reg:CC FLAGS_REG))]
7192   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7193   "sbb{q}\t{%2, %0|%0, %2}"
7194   [(set_attr "type" "alu")
7195    (set_attr "pent_pair" "pu")
7196    (set_attr "mode" "DI")])
7197
7198 (define_insn "*subdi_1_rex64"
7199   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7200         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7201                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7202    (clobber (reg:CC FLAGS_REG))]
7203   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7204   "sub{q}\t{%2, %0|%0, %2}"
7205   [(set_attr "type" "alu")
7206    (set_attr "mode" "DI")])
7207
7208 (define_insn "*subdi_2_rex64"
7209   [(set (reg FLAGS_REG)
7210         (compare
7211           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7212                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7213           (const_int 0)))
7214    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7215         (minus:DI (match_dup 1) (match_dup 2)))]
7216   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7217    && ix86_binary_operator_ok (MINUS, DImode, operands)"
7218   "sub{q}\t{%2, %0|%0, %2}"
7219   [(set_attr "type" "alu")
7220    (set_attr "mode" "DI")])
7221
7222 (define_insn "*subdi_3_rex63"
7223   [(set (reg FLAGS_REG)
7224         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7225                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7226    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7227         (minus:DI (match_dup 1) (match_dup 2)))]
7228   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7229    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7230   "sub{q}\t{%2, %0|%0, %2}"
7231   [(set_attr "type" "alu")
7232    (set_attr "mode" "DI")])
7233
7234 (define_insn "subqi3_carry"
7235   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7236           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7237             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7238                (match_operand:QI 2 "general_operand" "qi,qm"))))
7239    (clobber (reg:CC FLAGS_REG))]
7240   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7241   "sbb{b}\t{%2, %0|%0, %2}"
7242   [(set_attr "type" "alu")
7243    (set_attr "pent_pair" "pu")
7244    (set_attr "mode" "QI")])
7245
7246 (define_insn "subhi3_carry"
7247   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7248           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7249             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7250                (match_operand:HI 2 "general_operand" "ri,rm"))))
7251    (clobber (reg:CC FLAGS_REG))]
7252   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7253   "sbb{w}\t{%2, %0|%0, %2}"
7254   [(set_attr "type" "alu")
7255    (set_attr "pent_pair" "pu")
7256    (set_attr "mode" "HI")])
7257
7258 (define_insn "subsi3_carry"
7259   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7260           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7261             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7262                (match_operand:SI 2 "general_operand" "ri,rm"))))
7263    (clobber (reg:CC FLAGS_REG))]
7264   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7265   "sbb{l}\t{%2, %0|%0, %2}"
7266   [(set_attr "type" "alu")
7267    (set_attr "pent_pair" "pu")
7268    (set_attr "mode" "SI")])
7269
7270 (define_insn "subsi3_carry_zext"
7271   [(set (match_operand:DI 0 "register_operand" "=r")
7272           (zero_extend:DI
7273             (minus:SI (match_operand:SI 1 "register_operand" "0")
7274               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7275                  (match_operand:SI 2 "general_operand" "g")))))
7276    (clobber (reg:CC FLAGS_REG))]
7277   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7278   "sbb{l}\t{%2, %k0|%k0, %2}"
7279   [(set_attr "type" "alu")
7280    (set_attr "pent_pair" "pu")
7281    (set_attr "mode" "SI")])
7282
7283 (define_expand "subsi3"
7284   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7285                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7286                              (match_operand:SI 2 "general_operand" "")))
7287               (clobber (reg:CC FLAGS_REG))])]
7288   ""
7289   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7290
7291 (define_insn "*subsi_1"
7292   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7293         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7294                   (match_operand:SI 2 "general_operand" "ri,rm")))
7295    (clobber (reg:CC FLAGS_REG))]
7296   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7297   "sub{l}\t{%2, %0|%0, %2}"
7298   [(set_attr "type" "alu")
7299    (set_attr "mode" "SI")])
7300
7301 (define_insn "*subsi_1_zext"
7302   [(set (match_operand:DI 0 "register_operand" "=r")
7303         (zero_extend:DI
7304           (minus:SI (match_operand:SI 1 "register_operand" "0")
7305                     (match_operand:SI 2 "general_operand" "g"))))
7306    (clobber (reg:CC FLAGS_REG))]
7307   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7308   "sub{l}\t{%2, %k0|%k0, %2}"
7309   [(set_attr "type" "alu")
7310    (set_attr "mode" "SI")])
7311
7312 (define_insn "*subsi_2"
7313   [(set (reg FLAGS_REG)
7314         (compare
7315           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7316                     (match_operand:SI 2 "general_operand" "ri,rm"))
7317           (const_int 0)))
7318    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7319         (minus:SI (match_dup 1) (match_dup 2)))]
7320   "ix86_match_ccmode (insn, CCGOCmode)
7321    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7322   "sub{l}\t{%2, %0|%0, %2}"
7323   [(set_attr "type" "alu")
7324    (set_attr "mode" "SI")])
7325
7326 (define_insn "*subsi_2_zext"
7327   [(set (reg FLAGS_REG)
7328         (compare
7329           (minus:SI (match_operand:SI 1 "register_operand" "0")
7330                     (match_operand:SI 2 "general_operand" "g"))
7331           (const_int 0)))
7332    (set (match_operand:DI 0 "register_operand" "=r")
7333         (zero_extend:DI
7334           (minus:SI (match_dup 1)
7335                     (match_dup 2))))]
7336   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7337    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7338   "sub{l}\t{%2, %k0|%k0, %2}"
7339   [(set_attr "type" "alu")
7340    (set_attr "mode" "SI")])
7341
7342 (define_insn "*subsi_3"
7343   [(set (reg FLAGS_REG)
7344         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7345                  (match_operand:SI 2 "general_operand" "ri,rm")))
7346    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7347         (minus:SI (match_dup 1) (match_dup 2)))]
7348   "ix86_match_ccmode (insn, CCmode)
7349    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7350   "sub{l}\t{%2, %0|%0, %2}"
7351   [(set_attr "type" "alu")
7352    (set_attr "mode" "SI")])
7353
7354 (define_insn "*subsi_3_zext"
7355   [(set (reg FLAGS_REG)
7356         (compare (match_operand:SI 1 "register_operand" "0")
7357                  (match_operand:SI 2 "general_operand" "g")))
7358    (set (match_operand:DI 0 "register_operand" "=r")
7359         (zero_extend:DI
7360           (minus:SI (match_dup 1)
7361                     (match_dup 2))))]
7362   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7363    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7364   "sub{l}\t{%2, %1|%1, %2}"
7365   [(set_attr "type" "alu")
7366    (set_attr "mode" "DI")])
7367
7368 (define_expand "subhi3"
7369   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7370                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7371                              (match_operand:HI 2 "general_operand" "")))
7372               (clobber (reg:CC FLAGS_REG))])]
7373   "TARGET_HIMODE_MATH"
7374   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7375
7376 (define_insn "*subhi_1"
7377   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7378         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7379                   (match_operand:HI 2 "general_operand" "ri,rm")))
7380    (clobber (reg:CC FLAGS_REG))]
7381   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7382   "sub{w}\t{%2, %0|%0, %2}"
7383   [(set_attr "type" "alu")
7384    (set_attr "mode" "HI")])
7385
7386 (define_insn "*subhi_2"
7387   [(set (reg FLAGS_REG)
7388         (compare
7389           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7390                     (match_operand:HI 2 "general_operand" "ri,rm"))
7391           (const_int 0)))
7392    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7393         (minus:HI (match_dup 1) (match_dup 2)))]
7394   "ix86_match_ccmode (insn, CCGOCmode)
7395    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7396   "sub{w}\t{%2, %0|%0, %2}"
7397   [(set_attr "type" "alu")
7398    (set_attr "mode" "HI")])
7399
7400 (define_insn "*subhi_3"
7401   [(set (reg FLAGS_REG)
7402         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7403                  (match_operand:HI 2 "general_operand" "ri,rm")))
7404    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7405         (minus:HI (match_dup 1) (match_dup 2)))]
7406   "ix86_match_ccmode (insn, CCmode)
7407    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7408   "sub{w}\t{%2, %0|%0, %2}"
7409   [(set_attr "type" "alu")
7410    (set_attr "mode" "HI")])
7411
7412 (define_expand "subqi3"
7413   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7414                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7415                              (match_operand:QI 2 "general_operand" "")))
7416               (clobber (reg:CC FLAGS_REG))])]
7417   "TARGET_QIMODE_MATH"
7418   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7419
7420 (define_insn "*subqi_1"
7421   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7422         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7423                   (match_operand:QI 2 "general_operand" "qn,qmn")))
7424    (clobber (reg:CC FLAGS_REG))]
7425   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7426   "sub{b}\t{%2, %0|%0, %2}"
7427   [(set_attr "type" "alu")
7428    (set_attr "mode" "QI")])
7429
7430 (define_insn "*subqi_1_slp"
7431   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7432         (minus:QI (match_dup 0)
7433                   (match_operand:QI 1 "general_operand" "qn,qmn")))
7434    (clobber (reg:CC FLAGS_REG))]
7435   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7436    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7437   "sub{b}\t{%1, %0|%0, %1}"
7438   [(set_attr "type" "alu1")
7439    (set_attr "mode" "QI")])
7440
7441 (define_insn "*subqi_2"
7442   [(set (reg FLAGS_REG)
7443         (compare
7444           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7445                     (match_operand:QI 2 "general_operand" "qi,qm"))
7446           (const_int 0)))
7447    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7448         (minus:HI (match_dup 1) (match_dup 2)))]
7449   "ix86_match_ccmode (insn, CCGOCmode)
7450    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7451   "sub{b}\t{%2, %0|%0, %2}"
7452   [(set_attr "type" "alu")
7453    (set_attr "mode" "QI")])
7454
7455 (define_insn "*subqi_3"
7456   [(set (reg FLAGS_REG)
7457         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7458                  (match_operand:QI 2 "general_operand" "qi,qm")))
7459    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7460         (minus:HI (match_dup 1) (match_dup 2)))]
7461   "ix86_match_ccmode (insn, CCmode)
7462    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7463   "sub{b}\t{%2, %0|%0, %2}"
7464   [(set_attr "type" "alu")
7465    (set_attr "mode" "QI")])
7466
7467 ;; The patterns that match these are at the end of this file.
7468
7469 (define_expand "subxf3"
7470   [(set (match_operand:XF 0 "register_operand" "")
7471         (minus:XF (match_operand:XF 1 "register_operand" "")
7472                   (match_operand:XF 2 "register_operand" "")))]
7473   "TARGET_80387"
7474   "")
7475
7476 (define_expand "sub<mode>3"
7477   [(set (match_operand:MODEF 0 "register_operand" "")
7478         (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7479                      (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7480   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7481   "")
7482 \f
7483 ;; Multiply instructions
7484
7485 (define_expand "muldi3"
7486   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7487                    (mult:DI (match_operand:DI 1 "register_operand" "")
7488                             (match_operand:DI 2 "x86_64_general_operand" "")))
7489               (clobber (reg:CC FLAGS_REG))])]
7490   "TARGET_64BIT"
7491   "")
7492
7493 ;; On AMDFAM10
7494 ;; IMUL reg64, reg64, imm8      Direct
7495 ;; IMUL reg64, mem64, imm8      VectorPath
7496 ;; IMUL reg64, reg64, imm32     Direct
7497 ;; IMUL reg64, mem64, imm32     VectorPath
7498 ;; IMUL reg64, reg64            Direct
7499 ;; IMUL reg64, mem64            Direct
7500
7501 (define_insn "*muldi3_1_rex64"
7502   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7503         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7504                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7505    (clobber (reg:CC FLAGS_REG))]
7506   "TARGET_64BIT
7507    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7508   "@
7509    imul{q}\t{%2, %1, %0|%0, %1, %2}
7510    imul{q}\t{%2, %1, %0|%0, %1, %2}
7511    imul{q}\t{%2, %0|%0, %2}"
7512   [(set_attr "type" "imul")
7513    (set_attr "prefix_0f" "0,0,1")
7514    (set (attr "athlon_decode")
7515         (cond [(eq_attr "cpu" "athlon")
7516                   (const_string "vector")
7517                (eq_attr "alternative" "1")
7518                   (const_string "vector")
7519                (and (eq_attr "alternative" "2")
7520                     (match_operand 1 "memory_operand" ""))
7521                   (const_string "vector")]
7522               (const_string "direct")))
7523    (set (attr "amdfam10_decode")
7524         (cond [(and (eq_attr "alternative" "0,1")
7525                     (match_operand 1 "memory_operand" ""))
7526                   (const_string "vector")]
7527               (const_string "direct")))
7528    (set_attr "mode" "DI")])
7529
7530 (define_expand "mulsi3"
7531   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7532                    (mult:SI (match_operand:SI 1 "register_operand" "")
7533                             (match_operand:SI 2 "general_operand" "")))
7534               (clobber (reg:CC FLAGS_REG))])]
7535   ""
7536   "")
7537
7538 ;; On AMDFAM10
7539 ;; IMUL reg32, reg32, imm8      Direct
7540 ;; IMUL reg32, mem32, imm8      VectorPath
7541 ;; IMUL reg32, reg32, imm32     Direct
7542 ;; IMUL reg32, mem32, imm32     VectorPath
7543 ;; IMUL reg32, reg32            Direct
7544 ;; IMUL reg32, mem32            Direct
7545
7546 (define_insn "*mulsi3_1"
7547   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7548         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7549                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7550    (clobber (reg:CC FLAGS_REG))]
7551   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7552   "@
7553    imul{l}\t{%2, %1, %0|%0, %1, %2}
7554    imul{l}\t{%2, %1, %0|%0, %1, %2}
7555    imul{l}\t{%2, %0|%0, %2}"
7556   [(set_attr "type" "imul")
7557    (set_attr "prefix_0f" "0,0,1")
7558    (set (attr "athlon_decode")
7559         (cond [(eq_attr "cpu" "athlon")
7560                   (const_string "vector")
7561                (eq_attr "alternative" "1")
7562                   (const_string "vector")
7563                (and (eq_attr "alternative" "2")
7564                     (match_operand 1 "memory_operand" ""))
7565                   (const_string "vector")]
7566               (const_string "direct")))
7567    (set (attr "amdfam10_decode")
7568         (cond [(and (eq_attr "alternative" "0,1")
7569                     (match_operand 1 "memory_operand" ""))
7570                   (const_string "vector")]
7571               (const_string "direct")))
7572    (set_attr "mode" "SI")])
7573
7574 (define_insn "*mulsi3_1_zext"
7575   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7576         (zero_extend:DI
7577           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7578                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7579    (clobber (reg:CC FLAGS_REG))]
7580   "TARGET_64BIT
7581    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7582   "@
7583    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7584    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7585    imul{l}\t{%2, %k0|%k0, %2}"
7586   [(set_attr "type" "imul")
7587    (set_attr "prefix_0f" "0,0,1")
7588    (set (attr "athlon_decode")
7589         (cond [(eq_attr "cpu" "athlon")
7590                   (const_string "vector")
7591                (eq_attr "alternative" "1")
7592                   (const_string "vector")
7593                (and (eq_attr "alternative" "2")
7594                     (match_operand 1 "memory_operand" ""))
7595                   (const_string "vector")]
7596               (const_string "direct")))
7597    (set (attr "amdfam10_decode")
7598         (cond [(and (eq_attr "alternative" "0,1")
7599                     (match_operand 1 "memory_operand" ""))
7600                   (const_string "vector")]
7601               (const_string "direct")))
7602    (set_attr "mode" "SI")])
7603
7604 (define_expand "mulhi3"
7605   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7606                    (mult:HI (match_operand:HI 1 "register_operand" "")
7607                             (match_operand:HI 2 "general_operand" "")))
7608               (clobber (reg:CC FLAGS_REG))])]
7609   "TARGET_HIMODE_MATH"
7610   "")
7611
7612 ;; On AMDFAM10
7613 ;; IMUL reg16, reg16, imm8      VectorPath
7614 ;; IMUL reg16, mem16, imm8      VectorPath
7615 ;; IMUL reg16, reg16, imm16     VectorPath
7616 ;; IMUL reg16, mem16, imm16     VectorPath
7617 ;; IMUL reg16, reg16            Direct
7618 ;; IMUL reg16, mem16            Direct
7619 (define_insn "*mulhi3_1"
7620   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7621         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7622                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7623    (clobber (reg:CC FLAGS_REG))]
7624   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7625   "@
7626    imul{w}\t{%2, %1, %0|%0, %1, %2}
7627    imul{w}\t{%2, %1, %0|%0, %1, %2}
7628    imul{w}\t{%2, %0|%0, %2}"
7629   [(set_attr "type" "imul")
7630    (set_attr "prefix_0f" "0,0,1")
7631    (set (attr "athlon_decode")
7632         (cond [(eq_attr "cpu" "athlon")
7633                   (const_string "vector")
7634                (eq_attr "alternative" "1,2")
7635                   (const_string "vector")]
7636               (const_string "direct")))
7637    (set (attr "amdfam10_decode")
7638         (cond [(eq_attr "alternative" "0,1")
7639                   (const_string "vector")]
7640               (const_string "direct")))
7641    (set_attr "mode" "HI")])
7642
7643 (define_expand "mulqi3"
7644   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7645                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7646                             (match_operand:QI 2 "register_operand" "")))
7647               (clobber (reg:CC FLAGS_REG))])]
7648   "TARGET_QIMODE_MATH"
7649   "")
7650
7651 ;;On AMDFAM10
7652 ;; MUL reg8     Direct
7653 ;; MUL mem8     Direct
7654
7655 (define_insn "*mulqi3_1"
7656   [(set (match_operand:QI 0 "register_operand" "=a")
7657         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7658                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7659    (clobber (reg:CC FLAGS_REG))]
7660   "TARGET_QIMODE_MATH
7661    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7662   "mul{b}\t%2"
7663   [(set_attr "type" "imul")
7664    (set_attr "length_immediate" "0")
7665    (set (attr "athlon_decode")
7666      (if_then_else (eq_attr "cpu" "athlon")
7667         (const_string "vector")
7668         (const_string "direct")))
7669    (set_attr "amdfam10_decode" "direct")
7670    (set_attr "mode" "QI")])
7671
7672 (define_expand "umulqihi3"
7673   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7674                    (mult:HI (zero_extend:HI
7675                               (match_operand:QI 1 "nonimmediate_operand" ""))
7676                             (zero_extend:HI
7677                               (match_operand:QI 2 "register_operand" ""))))
7678               (clobber (reg:CC FLAGS_REG))])]
7679   "TARGET_QIMODE_MATH"
7680   "")
7681
7682 (define_insn "*umulqihi3_1"
7683   [(set (match_operand:HI 0 "register_operand" "=a")
7684         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7685                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7686    (clobber (reg:CC FLAGS_REG))]
7687   "TARGET_QIMODE_MATH
7688    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7689   "mul{b}\t%2"
7690   [(set_attr "type" "imul")
7691    (set_attr "length_immediate" "0")
7692    (set (attr "athlon_decode")
7693      (if_then_else (eq_attr "cpu" "athlon")
7694         (const_string "vector")
7695         (const_string "direct")))
7696    (set_attr "amdfam10_decode" "direct")
7697    (set_attr "mode" "QI")])
7698
7699 (define_expand "mulqihi3"
7700   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7701                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7702                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7703               (clobber (reg:CC FLAGS_REG))])]
7704   "TARGET_QIMODE_MATH"
7705   "")
7706
7707 (define_insn "*mulqihi3_insn"
7708   [(set (match_operand:HI 0 "register_operand" "=a")
7709         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7710                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7711    (clobber (reg:CC FLAGS_REG))]
7712   "TARGET_QIMODE_MATH
7713    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7714   "imul{b}\t%2"
7715   [(set_attr "type" "imul")
7716    (set_attr "length_immediate" "0")
7717    (set (attr "athlon_decode")
7718      (if_then_else (eq_attr "cpu" "athlon")
7719         (const_string "vector")
7720         (const_string "direct")))
7721    (set_attr "amdfam10_decode" "direct")
7722    (set_attr "mode" "QI")])
7723
7724 (define_expand "umulditi3"
7725   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7726                    (mult:TI (zero_extend:TI
7727                               (match_operand:DI 1 "nonimmediate_operand" ""))
7728                             (zero_extend:TI
7729                               (match_operand:DI 2 "register_operand" ""))))
7730               (clobber (reg:CC FLAGS_REG))])]
7731   "TARGET_64BIT"
7732   "")
7733
7734 (define_insn "*umulditi3_insn"
7735   [(set (match_operand:TI 0 "register_operand" "=A")
7736         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7737                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7738    (clobber (reg:CC FLAGS_REG))]
7739   "TARGET_64BIT
7740    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7741   "mul{q}\t%2"
7742   [(set_attr "type" "imul")
7743    (set_attr "length_immediate" "0")
7744    (set (attr "athlon_decode")
7745      (if_then_else (eq_attr "cpu" "athlon")
7746         (const_string "vector")
7747         (const_string "double")))
7748    (set_attr "amdfam10_decode" "double")
7749    (set_attr "mode" "DI")])
7750
7751 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7752 (define_expand "umulsidi3"
7753   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7754                    (mult:DI (zero_extend:DI
7755                               (match_operand:SI 1 "nonimmediate_operand" ""))
7756                             (zero_extend:DI
7757                               (match_operand:SI 2 "register_operand" ""))))
7758               (clobber (reg:CC FLAGS_REG))])]
7759   "!TARGET_64BIT"
7760   "")
7761
7762 (define_insn "*umulsidi3_insn"
7763   [(set (match_operand:DI 0 "register_operand" "=A")
7764         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7765                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7766    (clobber (reg:CC FLAGS_REG))]
7767   "!TARGET_64BIT
7768    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7769   "mul{l}\t%2"
7770   [(set_attr "type" "imul")
7771    (set_attr "length_immediate" "0")
7772    (set (attr "athlon_decode")
7773      (if_then_else (eq_attr "cpu" "athlon")
7774         (const_string "vector")
7775         (const_string "double")))
7776    (set_attr "amdfam10_decode" "double")
7777    (set_attr "mode" "SI")])
7778
7779 (define_expand "mulditi3"
7780   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7781                    (mult:TI (sign_extend:TI
7782                               (match_operand:DI 1 "nonimmediate_operand" ""))
7783                             (sign_extend:TI
7784                               (match_operand:DI 2 "register_operand" ""))))
7785               (clobber (reg:CC FLAGS_REG))])]
7786   "TARGET_64BIT"
7787   "")
7788
7789 (define_insn "*mulditi3_insn"
7790   [(set (match_operand:TI 0 "register_operand" "=A")
7791         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7792                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7793    (clobber (reg:CC FLAGS_REG))]
7794   "TARGET_64BIT
7795    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7796   "imul{q}\t%2"
7797   [(set_attr "type" "imul")
7798    (set_attr "length_immediate" "0")
7799    (set (attr "athlon_decode")
7800      (if_then_else (eq_attr "cpu" "athlon")
7801         (const_string "vector")
7802         (const_string "double")))
7803    (set_attr "amdfam10_decode" "double")
7804    (set_attr "mode" "DI")])
7805
7806 (define_expand "mulsidi3"
7807   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7808                    (mult:DI (sign_extend:DI
7809                               (match_operand:SI 1 "nonimmediate_operand" ""))
7810                             (sign_extend:DI
7811                               (match_operand:SI 2 "register_operand" ""))))
7812               (clobber (reg:CC FLAGS_REG))])]
7813   "!TARGET_64BIT"
7814   "")
7815
7816 (define_insn "*mulsidi3_insn"
7817   [(set (match_operand:DI 0 "register_operand" "=A")
7818         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7819                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7820    (clobber (reg:CC FLAGS_REG))]
7821   "!TARGET_64BIT
7822    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7823   "imul{l}\t%2"
7824   [(set_attr "type" "imul")
7825    (set_attr "length_immediate" "0")
7826    (set (attr "athlon_decode")
7827      (if_then_else (eq_attr "cpu" "athlon")
7828         (const_string "vector")
7829         (const_string "double")))
7830    (set_attr "amdfam10_decode" "double")
7831    (set_attr "mode" "SI")])
7832
7833 (define_expand "umuldi3_highpart"
7834   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7835                    (truncate:DI
7836                      (lshiftrt:TI
7837                        (mult:TI (zero_extend:TI
7838                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7839                                 (zero_extend:TI
7840                                   (match_operand:DI 2 "register_operand" "")))
7841                        (const_int 64))))
7842               (clobber (match_scratch:DI 3 ""))
7843               (clobber (reg:CC FLAGS_REG))])]
7844   "TARGET_64BIT"
7845   "")
7846
7847 (define_insn "*umuldi3_highpart_rex64"
7848   [(set (match_operand:DI 0 "register_operand" "=d")
7849         (truncate:DI
7850           (lshiftrt:TI
7851             (mult:TI (zero_extend:TI
7852                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7853                      (zero_extend:TI
7854                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7855             (const_int 64))))
7856    (clobber (match_scratch:DI 3 "=1"))
7857    (clobber (reg:CC FLAGS_REG))]
7858   "TARGET_64BIT
7859    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7860   "mul{q}\t%2"
7861   [(set_attr "type" "imul")
7862    (set_attr "length_immediate" "0")
7863    (set (attr "athlon_decode")
7864      (if_then_else (eq_attr "cpu" "athlon")
7865         (const_string "vector")
7866         (const_string "double")))
7867    (set_attr "amdfam10_decode" "double")
7868    (set_attr "mode" "DI")])
7869
7870 (define_expand "umulsi3_highpart"
7871   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7872                    (truncate:SI
7873                      (lshiftrt:DI
7874                        (mult:DI (zero_extend:DI
7875                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7876                                 (zero_extend:DI
7877                                   (match_operand:SI 2 "register_operand" "")))
7878                        (const_int 32))))
7879               (clobber (match_scratch:SI 3 ""))
7880               (clobber (reg:CC FLAGS_REG))])]
7881   ""
7882   "")
7883
7884 (define_insn "*umulsi3_highpart_insn"
7885   [(set (match_operand:SI 0 "register_operand" "=d")
7886         (truncate:SI
7887           (lshiftrt:DI
7888             (mult:DI (zero_extend:DI
7889                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7890                      (zero_extend:DI
7891                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7892             (const_int 32))))
7893    (clobber (match_scratch:SI 3 "=1"))
7894    (clobber (reg:CC FLAGS_REG))]
7895   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7896   "mul{l}\t%2"
7897   [(set_attr "type" "imul")
7898    (set_attr "length_immediate" "0")
7899    (set (attr "athlon_decode")
7900      (if_then_else (eq_attr "cpu" "athlon")
7901         (const_string "vector")
7902         (const_string "double")))
7903    (set_attr "amdfam10_decode" "double")
7904    (set_attr "mode" "SI")])
7905
7906 (define_insn "*umulsi3_highpart_zext"
7907   [(set (match_operand:DI 0 "register_operand" "=d")
7908         (zero_extend:DI (truncate:SI
7909           (lshiftrt:DI
7910             (mult:DI (zero_extend:DI
7911                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7912                      (zero_extend:DI
7913                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7914             (const_int 32)))))
7915    (clobber (match_scratch:SI 3 "=1"))
7916    (clobber (reg:CC FLAGS_REG))]
7917   "TARGET_64BIT
7918    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7919   "mul{l}\t%2"
7920   [(set_attr "type" "imul")
7921    (set_attr "length_immediate" "0")
7922    (set (attr "athlon_decode")
7923      (if_then_else (eq_attr "cpu" "athlon")
7924         (const_string "vector")
7925         (const_string "double")))
7926    (set_attr "amdfam10_decode" "double")
7927    (set_attr "mode" "SI")])
7928
7929 (define_expand "smuldi3_highpart"
7930   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7931                    (truncate:DI
7932                      (lshiftrt:TI
7933                        (mult:TI (sign_extend:TI
7934                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7935                                 (sign_extend:TI
7936                                   (match_operand:DI 2 "register_operand" "")))
7937                        (const_int 64))))
7938               (clobber (match_scratch:DI 3 ""))
7939               (clobber (reg:CC FLAGS_REG))])]
7940   "TARGET_64BIT"
7941   "")
7942
7943 (define_insn "*smuldi3_highpart_rex64"
7944   [(set (match_operand:DI 0 "register_operand" "=d")
7945         (truncate:DI
7946           (lshiftrt:TI
7947             (mult:TI (sign_extend:TI
7948                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7949                      (sign_extend:TI
7950                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7951             (const_int 64))))
7952    (clobber (match_scratch:DI 3 "=1"))
7953    (clobber (reg:CC FLAGS_REG))]
7954   "TARGET_64BIT
7955    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7956   "imul{q}\t%2"
7957   [(set_attr "type" "imul")
7958    (set (attr "athlon_decode")
7959      (if_then_else (eq_attr "cpu" "athlon")
7960         (const_string "vector")
7961         (const_string "double")))
7962    (set_attr "amdfam10_decode" "double")
7963    (set_attr "mode" "DI")])
7964
7965 (define_expand "smulsi3_highpart"
7966   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7967                    (truncate:SI
7968                      (lshiftrt:DI
7969                        (mult:DI (sign_extend:DI
7970                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7971                                 (sign_extend:DI
7972                                   (match_operand:SI 2 "register_operand" "")))
7973                        (const_int 32))))
7974               (clobber (match_scratch:SI 3 ""))
7975               (clobber (reg:CC FLAGS_REG))])]
7976   ""
7977   "")
7978
7979 (define_insn "*smulsi3_highpart_insn"
7980   [(set (match_operand:SI 0 "register_operand" "=d")
7981         (truncate:SI
7982           (lshiftrt:DI
7983             (mult:DI (sign_extend:DI
7984                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7985                      (sign_extend:DI
7986                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7987             (const_int 32))))
7988    (clobber (match_scratch:SI 3 "=1"))
7989    (clobber (reg:CC FLAGS_REG))]
7990   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7991   "imul{l}\t%2"
7992   [(set_attr "type" "imul")
7993    (set (attr "athlon_decode")
7994      (if_then_else (eq_attr "cpu" "athlon")
7995         (const_string "vector")
7996         (const_string "double")))
7997    (set_attr "amdfam10_decode" "double")
7998    (set_attr "mode" "SI")])
7999
8000 (define_insn "*smulsi3_highpart_zext"
8001   [(set (match_operand:DI 0 "register_operand" "=d")
8002         (zero_extend:DI (truncate:SI
8003           (lshiftrt:DI
8004             (mult:DI (sign_extend:DI
8005                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8006                      (sign_extend:DI
8007                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8008             (const_int 32)))))
8009    (clobber (match_scratch:SI 3 "=1"))
8010    (clobber (reg:CC FLAGS_REG))]
8011   "TARGET_64BIT
8012    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8013   "imul{l}\t%2"
8014   [(set_attr "type" "imul")
8015    (set (attr "athlon_decode")
8016      (if_then_else (eq_attr "cpu" "athlon")
8017         (const_string "vector")
8018         (const_string "double")))
8019    (set_attr "amdfam10_decode" "double")
8020    (set_attr "mode" "SI")])
8021
8022 ;; The patterns that match these are at the end of this file.
8023
8024 (define_expand "mulxf3"
8025   [(set (match_operand:XF 0 "register_operand" "")
8026         (mult:XF (match_operand:XF 1 "register_operand" "")
8027                  (match_operand:XF 2 "register_operand" "")))]
8028   "TARGET_80387"
8029   "")
8030
8031 (define_expand "mul<mode>3"
8032   [(set (match_operand:MODEF 0 "register_operand" "")
8033         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8034                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8035   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8036   "")
8037
8038 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8039
8040 \f
8041 ;; Divide instructions
8042
8043 (define_insn "divqi3"
8044   [(set (match_operand:QI 0 "register_operand" "=a")
8045         (div:QI (match_operand:HI 1 "register_operand" "0")
8046                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8047    (clobber (reg:CC FLAGS_REG))]
8048   "TARGET_QIMODE_MATH"
8049   "idiv{b}\t%2"
8050   [(set_attr "type" "idiv")
8051    (set_attr "mode" "QI")])
8052
8053 (define_insn "udivqi3"
8054   [(set (match_operand:QI 0 "register_operand" "=a")
8055         (udiv:QI (match_operand:HI 1 "register_operand" "0")
8056                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8057    (clobber (reg:CC FLAGS_REG))]
8058   "TARGET_QIMODE_MATH"
8059   "div{b}\t%2"
8060   [(set_attr "type" "idiv")
8061    (set_attr "mode" "QI")])
8062
8063 ;; The patterns that match these are at the end of this file.
8064
8065 (define_expand "divxf3"
8066   [(set (match_operand:XF 0 "register_operand" "")
8067         (div:XF (match_operand:XF 1 "register_operand" "")
8068                 (match_operand:XF 2 "register_operand" "")))]
8069   "TARGET_80387"
8070   "")
8071
8072 (define_expand "divdf3"
8073   [(set (match_operand:DF 0 "register_operand" "")
8074         (div:DF (match_operand:DF 1 "register_operand" "")
8075                 (match_operand:DF 2 "nonimmediate_operand" "")))]
8076    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8077    "")
8078
8079 (define_expand "divsf3"
8080   [(set (match_operand:SF 0 "register_operand" "")
8081         (div:SF (match_operand:SF 1 "register_operand" "")
8082                 (match_operand:SF 2 "nonimmediate_operand" "")))]
8083   "TARGET_80387 || TARGET_SSE_MATH"
8084 {
8085   if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8086       && flag_finite_math_only && !flag_trapping_math
8087       && flag_unsafe_math_optimizations)
8088     {
8089       ix86_emit_swdivsf (operands[0], operands[1],
8090                          operands[2], SFmode);
8091       DONE;
8092     }
8093 })
8094 \f
8095 ;; Remainder instructions.
8096
8097 (define_expand "divmoddi4"
8098   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8099                    (div:DI (match_operand:DI 1 "register_operand" "")
8100                            (match_operand:DI 2 "nonimmediate_operand" "")))
8101               (set (match_operand:DI 3 "register_operand" "")
8102                    (mod:DI (match_dup 1) (match_dup 2)))
8103               (clobber (reg:CC FLAGS_REG))])]
8104   "TARGET_64BIT"
8105   "")
8106
8107 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8108 ;; Penalize eax case slightly because it results in worse scheduling
8109 ;; of code.
8110 (define_insn "*divmoddi4_nocltd_rex64"
8111   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8112         (div:DI (match_operand:DI 2 "register_operand" "1,0")
8113                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8114    (set (match_operand:DI 1 "register_operand" "=&d,&d")
8115         (mod:DI (match_dup 2) (match_dup 3)))
8116    (clobber (reg:CC FLAGS_REG))]
8117   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8118   "#"
8119   [(set_attr "type" "multi")])
8120
8121 (define_insn "*divmoddi4_cltd_rex64"
8122   [(set (match_operand:DI 0 "register_operand" "=a")
8123         (div:DI (match_operand:DI 2 "register_operand" "a")
8124                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8125    (set (match_operand:DI 1 "register_operand" "=&d")
8126         (mod:DI (match_dup 2) (match_dup 3)))
8127    (clobber (reg:CC FLAGS_REG))]
8128   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8129   "#"
8130   [(set_attr "type" "multi")])
8131
8132 (define_insn "*divmoddi_noext_rex64"
8133   [(set (match_operand:DI 0 "register_operand" "=a")
8134         (div:DI (match_operand:DI 1 "register_operand" "0")
8135                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8136    (set (match_operand:DI 3 "register_operand" "=d")
8137         (mod:DI (match_dup 1) (match_dup 2)))
8138    (use (match_operand:DI 4 "register_operand" "3"))
8139    (clobber (reg:CC FLAGS_REG))]
8140   "TARGET_64BIT"
8141   "idiv{q}\t%2"
8142   [(set_attr "type" "idiv")
8143    (set_attr "mode" "DI")])
8144
8145 (define_split
8146   [(set (match_operand:DI 0 "register_operand" "")
8147         (div:DI (match_operand:DI 1 "register_operand" "")
8148                 (match_operand:DI 2 "nonimmediate_operand" "")))
8149    (set (match_operand:DI 3 "register_operand" "")
8150         (mod:DI (match_dup 1) (match_dup 2)))
8151    (clobber (reg:CC FLAGS_REG))]
8152   "TARGET_64BIT && reload_completed"
8153   [(parallel [(set (match_dup 3)
8154                    (ashiftrt:DI (match_dup 4) (const_int 63)))
8155               (clobber (reg:CC FLAGS_REG))])
8156    (parallel [(set (match_dup 0)
8157                    (div:DI (reg:DI 0) (match_dup 2)))
8158               (set (match_dup 3)
8159                    (mod:DI (reg:DI 0) (match_dup 2)))
8160               (use (match_dup 3))
8161               (clobber (reg:CC FLAGS_REG))])]
8162 {
8163   /* Avoid use of cltd in favor of a mov+shift.  */
8164   if (!TARGET_USE_CLTD && !optimize_size)
8165     {
8166       if (true_regnum (operands[1]))
8167         emit_move_insn (operands[0], operands[1]);
8168       else
8169         emit_move_insn (operands[3], operands[1]);
8170       operands[4] = operands[3];
8171     }
8172   else
8173     {
8174       gcc_assert (!true_regnum (operands[1]));
8175       operands[4] = operands[1];
8176     }
8177 })
8178
8179
8180 (define_expand "divmodsi4"
8181   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8182                    (div:SI (match_operand:SI 1 "register_operand" "")
8183                            (match_operand:SI 2 "nonimmediate_operand" "")))
8184               (set (match_operand:SI 3 "register_operand" "")
8185                    (mod:SI (match_dup 1) (match_dup 2)))
8186               (clobber (reg:CC FLAGS_REG))])]
8187   ""
8188   "")
8189
8190 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8191 ;; Penalize eax case slightly because it results in worse scheduling
8192 ;; of code.
8193 (define_insn "*divmodsi4_nocltd"
8194   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8195         (div:SI (match_operand:SI 2 "register_operand" "1,0")
8196                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8197    (set (match_operand:SI 1 "register_operand" "=&d,&d")
8198         (mod:SI (match_dup 2) (match_dup 3)))
8199    (clobber (reg:CC FLAGS_REG))]
8200   "!optimize_size && !TARGET_USE_CLTD"
8201   "#"
8202   [(set_attr "type" "multi")])
8203
8204 (define_insn "*divmodsi4_cltd"
8205   [(set (match_operand:SI 0 "register_operand" "=a")
8206         (div:SI (match_operand:SI 2 "register_operand" "a")
8207                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8208    (set (match_operand:SI 1 "register_operand" "=&d")
8209         (mod:SI (match_dup 2) (match_dup 3)))
8210    (clobber (reg:CC FLAGS_REG))]
8211   "optimize_size || TARGET_USE_CLTD"
8212   "#"
8213   [(set_attr "type" "multi")])
8214
8215 (define_insn "*divmodsi_noext"
8216   [(set (match_operand:SI 0 "register_operand" "=a")
8217         (div:SI (match_operand:SI 1 "register_operand" "0")
8218                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8219    (set (match_operand:SI 3 "register_operand" "=d")
8220         (mod:SI (match_dup 1) (match_dup 2)))
8221    (use (match_operand:SI 4 "register_operand" "3"))
8222    (clobber (reg:CC FLAGS_REG))]
8223   ""
8224   "idiv{l}\t%2"
8225   [(set_attr "type" "idiv")
8226    (set_attr "mode" "SI")])
8227
8228 (define_split
8229   [(set (match_operand:SI 0 "register_operand" "")
8230         (div:SI (match_operand:SI 1 "register_operand" "")
8231                 (match_operand:SI 2 "nonimmediate_operand" "")))
8232    (set (match_operand:SI 3 "register_operand" "")
8233         (mod:SI (match_dup 1) (match_dup 2)))
8234    (clobber (reg:CC FLAGS_REG))]
8235   "reload_completed"
8236   [(parallel [(set (match_dup 3)
8237                    (ashiftrt:SI (match_dup 4) (const_int 31)))
8238               (clobber (reg:CC FLAGS_REG))])
8239    (parallel [(set (match_dup 0)
8240                    (div:SI (reg:SI 0) (match_dup 2)))
8241               (set (match_dup 3)
8242                    (mod:SI (reg:SI 0) (match_dup 2)))
8243               (use (match_dup 3))
8244               (clobber (reg:CC FLAGS_REG))])]
8245 {
8246   /* Avoid use of cltd in favor of a mov+shift.  */
8247   if (!TARGET_USE_CLTD && !optimize_size)
8248     {
8249       if (true_regnum (operands[1]))
8250         emit_move_insn (operands[0], operands[1]);
8251       else
8252         emit_move_insn (operands[3], operands[1]);
8253       operands[4] = operands[3];
8254     }
8255   else
8256     {
8257       gcc_assert (!true_regnum (operands[1]));
8258       operands[4] = operands[1];
8259     }
8260 })
8261 ;; %%% Split me.
8262 (define_insn "divmodhi4"
8263   [(set (match_operand:HI 0 "register_operand" "=a")
8264         (div:HI (match_operand:HI 1 "register_operand" "0")
8265                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8266    (set (match_operand:HI 3 "register_operand" "=&d")
8267         (mod:HI (match_dup 1) (match_dup 2)))
8268    (clobber (reg:CC FLAGS_REG))]
8269   "TARGET_HIMODE_MATH"
8270   "cwtd\;idiv{w}\t%2"
8271   [(set_attr "type" "multi")
8272    (set_attr "length_immediate" "0")
8273    (set_attr "mode" "SI")])
8274
8275 (define_insn "udivmoddi4"
8276   [(set (match_operand:DI 0 "register_operand" "=a")
8277         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8278                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8279    (set (match_operand:DI 3 "register_operand" "=&d")
8280         (umod:DI (match_dup 1) (match_dup 2)))
8281    (clobber (reg:CC FLAGS_REG))]
8282   "TARGET_64BIT"
8283   "xor{q}\t%3, %3\;div{q}\t%2"
8284   [(set_attr "type" "multi")
8285    (set_attr "length_immediate" "0")
8286    (set_attr "mode" "DI")])
8287
8288 (define_insn "*udivmoddi4_noext"
8289   [(set (match_operand:DI 0 "register_operand" "=a")
8290         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8291                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8292    (set (match_operand:DI 3 "register_operand" "=d")
8293         (umod:DI (match_dup 1) (match_dup 2)))
8294    (use (match_dup 3))
8295    (clobber (reg:CC FLAGS_REG))]
8296   "TARGET_64BIT"
8297   "div{q}\t%2"
8298   [(set_attr "type" "idiv")
8299    (set_attr "mode" "DI")])
8300
8301 (define_split
8302   [(set (match_operand:DI 0 "register_operand" "")
8303         (udiv:DI (match_operand:DI 1 "register_operand" "")
8304                  (match_operand:DI 2 "nonimmediate_operand" "")))
8305    (set (match_operand:DI 3 "register_operand" "")
8306         (umod:DI (match_dup 1) (match_dup 2)))
8307    (clobber (reg:CC FLAGS_REG))]
8308   "TARGET_64BIT && reload_completed"
8309   [(set (match_dup 3) (const_int 0))
8310    (parallel [(set (match_dup 0)
8311                    (udiv:DI (match_dup 1) (match_dup 2)))
8312               (set (match_dup 3)
8313                    (umod:DI (match_dup 1) (match_dup 2)))
8314               (use (match_dup 3))
8315               (clobber (reg:CC FLAGS_REG))])]
8316   "")
8317
8318 (define_insn "udivmodsi4"
8319   [(set (match_operand:SI 0 "register_operand" "=a")
8320         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8321                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8322    (set (match_operand:SI 3 "register_operand" "=&d")
8323         (umod:SI (match_dup 1) (match_dup 2)))
8324    (clobber (reg:CC FLAGS_REG))]
8325   ""
8326   "xor{l}\t%3, %3\;div{l}\t%2"
8327   [(set_attr "type" "multi")
8328    (set_attr "length_immediate" "0")
8329    (set_attr "mode" "SI")])
8330
8331 (define_insn "*udivmodsi4_noext"
8332   [(set (match_operand:SI 0 "register_operand" "=a")
8333         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8334                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8335    (set (match_operand:SI 3 "register_operand" "=d")
8336         (umod:SI (match_dup 1) (match_dup 2)))
8337    (use (match_dup 3))
8338    (clobber (reg:CC FLAGS_REG))]
8339   ""
8340   "div{l}\t%2"
8341   [(set_attr "type" "idiv")
8342    (set_attr "mode" "SI")])
8343
8344 (define_split
8345   [(set (match_operand:SI 0 "register_operand" "")
8346         (udiv:SI (match_operand:SI 1 "register_operand" "")
8347                  (match_operand:SI 2 "nonimmediate_operand" "")))
8348    (set (match_operand:SI 3 "register_operand" "")
8349         (umod:SI (match_dup 1) (match_dup 2)))
8350    (clobber (reg:CC FLAGS_REG))]
8351   "reload_completed"
8352   [(set (match_dup 3) (const_int 0))
8353    (parallel [(set (match_dup 0)
8354                    (udiv:SI (match_dup 1) (match_dup 2)))
8355               (set (match_dup 3)
8356                    (umod:SI (match_dup 1) (match_dup 2)))
8357               (use (match_dup 3))
8358               (clobber (reg:CC FLAGS_REG))])]
8359   "")
8360
8361 (define_expand "udivmodhi4"
8362   [(set (match_dup 4) (const_int 0))
8363    (parallel [(set (match_operand:HI 0 "register_operand" "")
8364                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8365                             (match_operand:HI 2 "nonimmediate_operand" "")))
8366               (set (match_operand:HI 3 "register_operand" "")
8367                    (umod:HI (match_dup 1) (match_dup 2)))
8368               (use (match_dup 4))
8369               (clobber (reg:CC FLAGS_REG))])]
8370   "TARGET_HIMODE_MATH"
8371   "operands[4] = gen_reg_rtx (HImode);")
8372
8373 (define_insn "*udivmodhi_noext"
8374   [(set (match_operand:HI 0 "register_operand" "=a")
8375         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8376                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8377    (set (match_operand:HI 3 "register_operand" "=d")
8378         (umod:HI (match_dup 1) (match_dup 2)))
8379    (use (match_operand:HI 4 "register_operand" "3"))
8380    (clobber (reg:CC FLAGS_REG))]
8381   ""
8382   "div{w}\t%2"
8383   [(set_attr "type" "idiv")
8384    (set_attr "mode" "HI")])
8385
8386 ;; We cannot use div/idiv for double division, because it causes
8387 ;; "division by zero" on the overflow and that's not what we expect
8388 ;; from truncate.  Because true (non truncating) double division is
8389 ;; never generated, we can't create this insn anyway.
8390 ;
8391 ;(define_insn ""
8392 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8393 ;       (truncate:SI
8394 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8395 ;                  (zero_extend:DI
8396 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8397 ;   (set (match_operand:SI 3 "register_operand" "=d")
8398 ;       (truncate:SI
8399 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8400 ;   (clobber (reg:CC FLAGS_REG))]
8401 ;  ""
8402 ;  "div{l}\t{%2, %0|%0, %2}"
8403 ;  [(set_attr "type" "idiv")])
8404 \f
8405 ;;- Logical AND instructions
8406
8407 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8408 ;; Note that this excludes ah.
8409
8410 (define_insn "*testdi_1_rex64"
8411   [(set (reg FLAGS_REG)
8412         (compare
8413           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8414                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8415           (const_int 0)))]
8416   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8417    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8418   "@
8419    test{l}\t{%k1, %k0|%k0, %k1}
8420    test{l}\t{%k1, %k0|%k0, %k1}
8421    test{q}\t{%1, %0|%0, %1}
8422    test{q}\t{%1, %0|%0, %1}
8423    test{q}\t{%1, %0|%0, %1}"
8424   [(set_attr "type" "test")
8425    (set_attr "modrm" "0,1,0,1,1")
8426    (set_attr "mode" "SI,SI,DI,DI,DI")
8427    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8428
8429 (define_insn "testsi_1"
8430   [(set (reg FLAGS_REG)
8431         (compare
8432           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8433                   (match_operand:SI 1 "general_operand" "in,in,rin"))
8434           (const_int 0)))]
8435   "ix86_match_ccmode (insn, CCNOmode)
8436    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8437   "test{l}\t{%1, %0|%0, %1}"
8438   [(set_attr "type" "test")
8439    (set_attr "modrm" "0,1,1")
8440    (set_attr "mode" "SI")
8441    (set_attr "pent_pair" "uv,np,uv")])
8442
8443 (define_expand "testsi_ccno_1"
8444   [(set (reg:CCNO FLAGS_REG)
8445         (compare:CCNO
8446           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8447                   (match_operand:SI 1 "nonmemory_operand" ""))
8448           (const_int 0)))]
8449   ""
8450   "")
8451
8452 (define_insn "*testhi_1"
8453   [(set (reg FLAGS_REG)
8454         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8455                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8456                  (const_int 0)))]
8457   "ix86_match_ccmode (insn, CCNOmode)
8458    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8459   "test{w}\t{%1, %0|%0, %1}"
8460   [(set_attr "type" "test")
8461    (set_attr "modrm" "0,1,1")
8462    (set_attr "mode" "HI")
8463    (set_attr "pent_pair" "uv,np,uv")])
8464
8465 (define_expand "testqi_ccz_1"
8466   [(set (reg:CCZ FLAGS_REG)
8467         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8468                              (match_operand:QI 1 "nonmemory_operand" ""))
8469                  (const_int 0)))]
8470   ""
8471   "")
8472
8473 (define_insn "*testqi_1_maybe_si"
8474   [(set (reg FLAGS_REG)
8475         (compare
8476           (and:QI
8477             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8478             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8479           (const_int 0)))]
8480    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8481     && ix86_match_ccmode (insn,
8482                          CONST_INT_P (operands[1])
8483                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8484 {
8485   if (which_alternative == 3)
8486     {
8487       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8488         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8489       return "test{l}\t{%1, %k0|%k0, %1}";
8490     }
8491   return "test{b}\t{%1, %0|%0, %1}";
8492 }
8493   [(set_attr "type" "test")
8494    (set_attr "modrm" "0,1,1,1")
8495    (set_attr "mode" "QI,QI,QI,SI")
8496    (set_attr "pent_pair" "uv,np,uv,np")])
8497
8498 (define_insn "*testqi_1"
8499   [(set (reg FLAGS_REG)
8500         (compare
8501           (and:QI
8502             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8503             (match_operand:QI 1 "general_operand" "n,n,qn"))
8504           (const_int 0)))]
8505   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8506    && ix86_match_ccmode (insn, CCNOmode)"
8507   "test{b}\t{%1, %0|%0, %1}"
8508   [(set_attr "type" "test")
8509    (set_attr "modrm" "0,1,1")
8510    (set_attr "mode" "QI")
8511    (set_attr "pent_pair" "uv,np,uv")])
8512
8513 (define_expand "testqi_ext_ccno_0"
8514   [(set (reg:CCNO FLAGS_REG)
8515         (compare:CCNO
8516           (and:SI
8517             (zero_extract:SI
8518               (match_operand 0 "ext_register_operand" "")
8519               (const_int 8)
8520               (const_int 8))
8521             (match_operand 1 "const_int_operand" ""))
8522           (const_int 0)))]
8523   ""
8524   "")
8525
8526 (define_insn "*testqi_ext_0"
8527   [(set (reg FLAGS_REG)
8528         (compare
8529           (and:SI
8530             (zero_extract:SI
8531               (match_operand 0 "ext_register_operand" "Q")
8532               (const_int 8)
8533               (const_int 8))
8534             (match_operand 1 "const_int_operand" "n"))
8535           (const_int 0)))]
8536   "ix86_match_ccmode (insn, CCNOmode)"
8537   "test{b}\t{%1, %h0|%h0, %1}"
8538   [(set_attr "type" "test")
8539    (set_attr "mode" "QI")
8540    (set_attr "length_immediate" "1")
8541    (set_attr "pent_pair" "np")])
8542
8543 (define_insn "*testqi_ext_1"
8544   [(set (reg FLAGS_REG)
8545         (compare
8546           (and:SI
8547             (zero_extract:SI
8548               (match_operand 0 "ext_register_operand" "Q")
8549               (const_int 8)
8550               (const_int 8))
8551             (zero_extend:SI
8552               (match_operand:QI 1 "general_operand" "Qm")))
8553           (const_int 0)))]
8554   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8555    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8556   "test{b}\t{%1, %h0|%h0, %1}"
8557   [(set_attr "type" "test")
8558    (set_attr "mode" "QI")])
8559
8560 (define_insn "*testqi_ext_1_rex64"
8561   [(set (reg FLAGS_REG)
8562         (compare
8563           (and:SI
8564             (zero_extract:SI
8565               (match_operand 0 "ext_register_operand" "Q")
8566               (const_int 8)
8567               (const_int 8))
8568             (zero_extend:SI
8569               (match_operand:QI 1 "register_operand" "Q")))
8570           (const_int 0)))]
8571   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8572   "test{b}\t{%1, %h0|%h0, %1}"
8573   [(set_attr "type" "test")
8574    (set_attr "mode" "QI")])
8575
8576 (define_insn "*testqi_ext_2"
8577   [(set (reg FLAGS_REG)
8578         (compare
8579           (and:SI
8580             (zero_extract:SI
8581               (match_operand 0 "ext_register_operand" "Q")
8582               (const_int 8)
8583               (const_int 8))
8584             (zero_extract:SI
8585               (match_operand 1 "ext_register_operand" "Q")
8586               (const_int 8)
8587               (const_int 8)))
8588           (const_int 0)))]
8589   "ix86_match_ccmode (insn, CCNOmode)"
8590   "test{b}\t{%h1, %h0|%h0, %h1}"
8591   [(set_attr "type" "test")
8592    (set_attr "mode" "QI")])
8593
8594 ;; Combine likes to form bit extractions for some tests.  Humor it.
8595 (define_insn "*testqi_ext_3"
8596   [(set (reg FLAGS_REG)
8597         (compare (zero_extract:SI
8598                    (match_operand 0 "nonimmediate_operand" "rm")
8599                    (match_operand:SI 1 "const_int_operand" "")
8600                    (match_operand:SI 2 "const_int_operand" ""))
8601                  (const_int 0)))]
8602   "ix86_match_ccmode (insn, CCNOmode)
8603    && INTVAL (operands[1]) > 0
8604    && INTVAL (operands[2]) >= 0
8605    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8606    && (GET_MODE (operands[0]) == SImode
8607        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8608        || GET_MODE (operands[0]) == HImode
8609        || GET_MODE (operands[0]) == QImode)"
8610   "#")
8611
8612 (define_insn "*testqi_ext_3_rex64"
8613   [(set (reg FLAGS_REG)
8614         (compare (zero_extract:DI
8615                    (match_operand 0 "nonimmediate_operand" "rm")
8616                    (match_operand:DI 1 "const_int_operand" "")
8617                    (match_operand:DI 2 "const_int_operand" ""))
8618                  (const_int 0)))]
8619   "TARGET_64BIT
8620    && ix86_match_ccmode (insn, CCNOmode)
8621    && INTVAL (operands[1]) > 0
8622    && INTVAL (operands[2]) >= 0
8623    /* Ensure that resulting mask is zero or sign extended operand.  */
8624    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8625        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8626            && INTVAL (operands[1]) > 32))
8627    && (GET_MODE (operands[0]) == SImode
8628        || GET_MODE (operands[0]) == DImode
8629        || GET_MODE (operands[0]) == HImode
8630        || GET_MODE (operands[0]) == QImode)"
8631   "#")
8632
8633 (define_split
8634   [(set (match_operand 0 "flags_reg_operand" "")
8635         (match_operator 1 "compare_operator"
8636           [(zero_extract
8637              (match_operand 2 "nonimmediate_operand" "")
8638              (match_operand 3 "const_int_operand" "")
8639              (match_operand 4 "const_int_operand" ""))
8640            (const_int 0)]))]
8641   "ix86_match_ccmode (insn, CCNOmode)"
8642   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8643 {
8644   rtx val = operands[2];
8645   HOST_WIDE_INT len = INTVAL (operands[3]);
8646   HOST_WIDE_INT pos = INTVAL (operands[4]);
8647   HOST_WIDE_INT mask;
8648   enum machine_mode mode, submode;
8649
8650   mode = GET_MODE (val);
8651   if (MEM_P (val))
8652     {
8653       /* ??? Combine likes to put non-volatile mem extractions in QImode
8654          no matter the size of the test.  So find a mode that works.  */
8655       if (! MEM_VOLATILE_P (val))
8656         {
8657           mode = smallest_mode_for_size (pos + len, MODE_INT);
8658           val = adjust_address (val, mode, 0);
8659         }
8660     }
8661   else if (GET_CODE (val) == SUBREG
8662            && (submode = GET_MODE (SUBREG_REG (val)),
8663                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8664            && pos + len <= GET_MODE_BITSIZE (submode))
8665     {
8666       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8667       mode = submode;
8668       val = SUBREG_REG (val);
8669     }
8670   else if (mode == HImode && pos + len <= 8)
8671     {
8672       /* Small HImode tests can be converted to QImode.  */
8673       mode = QImode;
8674       val = gen_lowpart (QImode, val);
8675     }
8676
8677   if (len == HOST_BITS_PER_WIDE_INT)
8678     mask = -1;
8679   else
8680     mask = ((HOST_WIDE_INT)1 << len) - 1;
8681   mask <<= pos;
8682
8683   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8684 })
8685
8686 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8687 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8688 ;; this is relatively important trick.
8689 ;; Do the conversion only post-reload to avoid limiting of the register class
8690 ;; to QI regs.
8691 (define_split
8692   [(set (match_operand 0 "flags_reg_operand" "")
8693         (match_operator 1 "compare_operator"
8694           [(and (match_operand 2 "register_operand" "")
8695                 (match_operand 3 "const_int_operand" ""))
8696            (const_int 0)]))]
8697    "reload_completed
8698     && QI_REG_P (operands[2])
8699     && GET_MODE (operands[2]) != QImode
8700     && ((ix86_match_ccmode (insn, CCZmode)
8701          && !(INTVAL (operands[3]) & ~(255 << 8)))
8702         || (ix86_match_ccmode (insn, CCNOmode)
8703             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8704   [(set (match_dup 0)
8705         (match_op_dup 1
8706           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8707                    (match_dup 3))
8708            (const_int 0)]))]
8709   "operands[2] = gen_lowpart (SImode, operands[2]);
8710    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8711
8712 (define_split
8713   [(set (match_operand 0 "flags_reg_operand" "")
8714         (match_operator 1 "compare_operator"
8715           [(and (match_operand 2 "nonimmediate_operand" "")
8716                 (match_operand 3 "const_int_operand" ""))
8717            (const_int 0)]))]
8718    "reload_completed
8719     && GET_MODE (operands[2]) != QImode
8720     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8721     && ((ix86_match_ccmode (insn, CCZmode)
8722          && !(INTVAL (operands[3]) & ~255))
8723         || (ix86_match_ccmode (insn, CCNOmode)
8724             && !(INTVAL (operands[3]) & ~127)))"
8725   [(set (match_dup 0)
8726         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8727                          (const_int 0)]))]
8728   "operands[2] = gen_lowpart (QImode, operands[2]);
8729    operands[3] = gen_lowpart (QImode, operands[3]);")
8730
8731
8732 ;; %%% This used to optimize known byte-wide and operations to memory,
8733 ;; and sometimes to QImode registers.  If this is considered useful,
8734 ;; it should be done with splitters.
8735
8736 (define_expand "anddi3"
8737   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8738         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8739                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8740    (clobber (reg:CC FLAGS_REG))]
8741   "TARGET_64BIT"
8742   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8743
8744 (define_insn "*anddi_1_rex64"
8745   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8746         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8747                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8748    (clobber (reg:CC FLAGS_REG))]
8749   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8750 {
8751   switch (get_attr_type (insn))
8752     {
8753     case TYPE_IMOVX:
8754       {
8755         enum machine_mode mode;
8756
8757         gcc_assert (CONST_INT_P (operands[2]));
8758         if (INTVAL (operands[2]) == 0xff)
8759           mode = QImode;
8760         else
8761           {
8762             gcc_assert (INTVAL (operands[2]) == 0xffff);
8763             mode = HImode;
8764           }
8765
8766         operands[1] = gen_lowpart (mode, operands[1]);
8767         if (mode == QImode)
8768           return "movz{bq|x}\t{%1,%0|%0, %1}";
8769         else
8770           return "movz{wq|x}\t{%1,%0|%0, %1}";
8771       }
8772
8773     default:
8774       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8775       if (get_attr_mode (insn) == MODE_SI)
8776         return "and{l}\t{%k2, %k0|%k0, %k2}";
8777       else
8778         return "and{q}\t{%2, %0|%0, %2}";
8779     }
8780 }
8781   [(set_attr "type" "alu,alu,alu,imovx")
8782    (set_attr "length_immediate" "*,*,*,0")
8783    (set_attr "mode" "SI,DI,DI,DI")])
8784
8785 (define_insn "*anddi_2"
8786   [(set (reg FLAGS_REG)
8787         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8788                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8789                  (const_int 0)))
8790    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8791         (and:DI (match_dup 1) (match_dup 2)))]
8792   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8793    && ix86_binary_operator_ok (AND, DImode, operands)"
8794   "@
8795    and{l}\t{%k2, %k0|%k0, %k2}
8796    and{q}\t{%2, %0|%0, %2}
8797    and{q}\t{%2, %0|%0, %2}"
8798   [(set_attr "type" "alu")
8799    (set_attr "mode" "SI,DI,DI")])
8800
8801 (define_expand "andsi3"
8802   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8803         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8804                 (match_operand:SI 2 "general_operand" "")))
8805    (clobber (reg:CC FLAGS_REG))]
8806   ""
8807   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8808
8809 (define_insn "*andsi_1"
8810   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8811         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8812                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8813    (clobber (reg:CC FLAGS_REG))]
8814   "ix86_binary_operator_ok (AND, SImode, operands)"
8815 {
8816   switch (get_attr_type (insn))
8817     {
8818     case TYPE_IMOVX:
8819       {
8820         enum machine_mode mode;
8821
8822         gcc_assert (CONST_INT_P (operands[2]));
8823         if (INTVAL (operands[2]) == 0xff)
8824           mode = QImode;
8825         else
8826           {
8827             gcc_assert (INTVAL (operands[2]) == 0xffff);
8828             mode = HImode;
8829           }
8830
8831         operands[1] = gen_lowpart (mode, operands[1]);
8832         if (mode == QImode)
8833           return "movz{bl|x}\t{%1,%0|%0, %1}";
8834         else
8835           return "movz{wl|x}\t{%1,%0|%0, %1}";
8836       }
8837
8838     default:
8839       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8840       return "and{l}\t{%2, %0|%0, %2}";
8841     }
8842 }
8843   [(set_attr "type" "alu,alu,imovx")
8844    (set_attr "length_immediate" "*,*,0")
8845    (set_attr "mode" "SI")])
8846
8847 (define_split
8848   [(set (match_operand 0 "register_operand" "")
8849         (and (match_dup 0)
8850              (const_int -65536)))
8851    (clobber (reg:CC FLAGS_REG))]
8852   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8853   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8854   "operands[1] = gen_lowpart (HImode, operands[0]);")
8855
8856 (define_split
8857   [(set (match_operand 0 "ext_register_operand" "")
8858         (and (match_dup 0)
8859              (const_int -256)))
8860    (clobber (reg:CC FLAGS_REG))]
8861   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8862   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8863   "operands[1] = gen_lowpart (QImode, operands[0]);")
8864
8865 (define_split
8866   [(set (match_operand 0 "ext_register_operand" "")
8867         (and (match_dup 0)
8868              (const_int -65281)))
8869    (clobber (reg:CC FLAGS_REG))]
8870   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8871   [(parallel [(set (zero_extract:SI (match_dup 0)
8872                                     (const_int 8)
8873                                     (const_int 8))
8874                    (xor:SI
8875                      (zero_extract:SI (match_dup 0)
8876                                       (const_int 8)
8877                                       (const_int 8))
8878                      (zero_extract:SI (match_dup 0)
8879                                       (const_int 8)
8880                                       (const_int 8))))
8881               (clobber (reg:CC FLAGS_REG))])]
8882   "operands[0] = gen_lowpart (SImode, operands[0]);")
8883
8884 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8885 (define_insn "*andsi_1_zext"
8886   [(set (match_operand:DI 0 "register_operand" "=r")
8887         (zero_extend:DI
8888           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8889                   (match_operand:SI 2 "general_operand" "g"))))
8890    (clobber (reg:CC FLAGS_REG))]
8891   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8892   "and{l}\t{%2, %k0|%k0, %2}"
8893   [(set_attr "type" "alu")
8894    (set_attr "mode" "SI")])
8895
8896 (define_insn "*andsi_2"
8897   [(set (reg FLAGS_REG)
8898         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8899                          (match_operand:SI 2 "general_operand" "g,ri"))
8900                  (const_int 0)))
8901    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8902         (and:SI (match_dup 1) (match_dup 2)))]
8903   "ix86_match_ccmode (insn, CCNOmode)
8904    && ix86_binary_operator_ok (AND, SImode, operands)"
8905   "and{l}\t{%2, %0|%0, %2}"
8906   [(set_attr "type" "alu")
8907    (set_attr "mode" "SI")])
8908
8909 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8910 (define_insn "*andsi_2_zext"
8911   [(set (reg FLAGS_REG)
8912         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8913                          (match_operand:SI 2 "general_operand" "g"))
8914                  (const_int 0)))
8915    (set (match_operand:DI 0 "register_operand" "=r")
8916         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8917   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8918    && ix86_binary_operator_ok (AND, SImode, operands)"
8919   "and{l}\t{%2, %k0|%k0, %2}"
8920   [(set_attr "type" "alu")
8921    (set_attr "mode" "SI")])
8922
8923 (define_expand "andhi3"
8924   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8925         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8926                 (match_operand:HI 2 "general_operand" "")))
8927    (clobber (reg:CC FLAGS_REG))]
8928   "TARGET_HIMODE_MATH"
8929   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8930
8931 (define_insn "*andhi_1"
8932   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8933         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8934                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8935    (clobber (reg:CC FLAGS_REG))]
8936   "ix86_binary_operator_ok (AND, HImode, operands)"
8937 {
8938   switch (get_attr_type (insn))
8939     {
8940     case TYPE_IMOVX:
8941       gcc_assert (CONST_INT_P (operands[2]));
8942       gcc_assert (INTVAL (operands[2]) == 0xff);
8943       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8944
8945     default:
8946       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8947
8948       return "and{w}\t{%2, %0|%0, %2}";
8949     }
8950 }
8951   [(set_attr "type" "alu,alu,imovx")
8952    (set_attr "length_immediate" "*,*,0")
8953    (set_attr "mode" "HI,HI,SI")])
8954
8955 (define_insn "*andhi_2"
8956   [(set (reg FLAGS_REG)
8957         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8958                          (match_operand:HI 2 "general_operand" "g,ri"))
8959                  (const_int 0)))
8960    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8961         (and:HI (match_dup 1) (match_dup 2)))]
8962   "ix86_match_ccmode (insn, CCNOmode)
8963    && ix86_binary_operator_ok (AND, HImode, operands)"
8964   "and{w}\t{%2, %0|%0, %2}"
8965   [(set_attr "type" "alu")
8966    (set_attr "mode" "HI")])
8967
8968 (define_expand "andqi3"
8969   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8970         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8971                 (match_operand:QI 2 "general_operand" "")))
8972    (clobber (reg:CC FLAGS_REG))]
8973   "TARGET_QIMODE_MATH"
8974   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8975
8976 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8977 (define_insn "*andqi_1"
8978   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8979         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8980                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8981    (clobber (reg:CC FLAGS_REG))]
8982   "ix86_binary_operator_ok (AND, QImode, operands)"
8983   "@
8984    and{b}\t{%2, %0|%0, %2}
8985    and{b}\t{%2, %0|%0, %2}
8986    and{l}\t{%k2, %k0|%k0, %k2}"
8987   [(set_attr "type" "alu")
8988    (set_attr "mode" "QI,QI,SI")])
8989
8990 (define_insn "*andqi_1_slp"
8991   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8992         (and:QI (match_dup 0)
8993                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8994    (clobber (reg:CC FLAGS_REG))]
8995   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8996    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8997   "and{b}\t{%1, %0|%0, %1}"
8998   [(set_attr "type" "alu1")
8999    (set_attr "mode" "QI")])
9000
9001 (define_insn "*andqi_2_maybe_si"
9002   [(set (reg FLAGS_REG)
9003         (compare (and:QI
9004                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9005                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
9006                  (const_int 0)))
9007    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9008         (and:QI (match_dup 1) (match_dup 2)))]
9009   "ix86_binary_operator_ok (AND, QImode, operands)
9010    && ix86_match_ccmode (insn,
9011                          CONST_INT_P (operands[2])
9012                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9013 {
9014   if (which_alternative == 2)
9015     {
9016       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9017         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9018       return "and{l}\t{%2, %k0|%k0, %2}";
9019     }
9020   return "and{b}\t{%2, %0|%0, %2}";
9021 }
9022   [(set_attr "type" "alu")
9023    (set_attr "mode" "QI,QI,SI")])
9024
9025 (define_insn "*andqi_2"
9026   [(set (reg FLAGS_REG)
9027         (compare (and:QI
9028                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9029                    (match_operand:QI 2 "general_operand" "qim,qi"))
9030                  (const_int 0)))
9031    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9032         (and:QI (match_dup 1) (match_dup 2)))]
9033   "ix86_match_ccmode (insn, CCNOmode)
9034    && ix86_binary_operator_ok (AND, QImode, operands)"
9035   "and{b}\t{%2, %0|%0, %2}"
9036   [(set_attr "type" "alu")
9037    (set_attr "mode" "QI")])
9038
9039 (define_insn "*andqi_2_slp"
9040   [(set (reg FLAGS_REG)
9041         (compare (and:QI
9042                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9043                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
9044                  (const_int 0)))
9045    (set (strict_low_part (match_dup 0))
9046         (and:QI (match_dup 0) (match_dup 1)))]
9047   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9048    && ix86_match_ccmode (insn, CCNOmode)
9049    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9050   "and{b}\t{%1, %0|%0, %1}"
9051   [(set_attr "type" "alu1")
9052    (set_attr "mode" "QI")])
9053
9054 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9055 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
9056 ;; for a QImode operand, which of course failed.
9057
9058 (define_insn "andqi_ext_0"
9059   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9060                          (const_int 8)
9061                          (const_int 8))
9062         (and:SI
9063           (zero_extract:SI
9064             (match_operand 1 "ext_register_operand" "0")
9065             (const_int 8)
9066             (const_int 8))
9067           (match_operand 2 "const_int_operand" "n")))
9068    (clobber (reg:CC FLAGS_REG))]
9069   ""
9070   "and{b}\t{%2, %h0|%h0, %2}"
9071   [(set_attr "type" "alu")
9072    (set_attr "length_immediate" "1")
9073    (set_attr "mode" "QI")])
9074
9075 ;; Generated by peephole translating test to and.  This shows up
9076 ;; often in fp comparisons.
9077
9078 (define_insn "*andqi_ext_0_cc"
9079   [(set (reg FLAGS_REG)
9080         (compare
9081           (and:SI
9082             (zero_extract:SI
9083               (match_operand 1 "ext_register_operand" "0")
9084               (const_int 8)
9085               (const_int 8))
9086             (match_operand 2 "const_int_operand" "n"))
9087           (const_int 0)))
9088    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9089                          (const_int 8)
9090                          (const_int 8))
9091         (and:SI
9092           (zero_extract:SI
9093             (match_dup 1)
9094             (const_int 8)
9095             (const_int 8))
9096           (match_dup 2)))]
9097   "ix86_match_ccmode (insn, CCNOmode)"
9098   "and{b}\t{%2, %h0|%h0, %2}"
9099   [(set_attr "type" "alu")
9100    (set_attr "length_immediate" "1")
9101    (set_attr "mode" "QI")])
9102
9103 (define_insn "*andqi_ext_1"
9104   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9105                          (const_int 8)
9106                          (const_int 8))
9107         (and:SI
9108           (zero_extract:SI
9109             (match_operand 1 "ext_register_operand" "0")
9110             (const_int 8)
9111             (const_int 8))
9112           (zero_extend:SI
9113             (match_operand:QI 2 "general_operand" "Qm"))))
9114    (clobber (reg:CC FLAGS_REG))]
9115   "!TARGET_64BIT"
9116   "and{b}\t{%2, %h0|%h0, %2}"
9117   [(set_attr "type" "alu")
9118    (set_attr "length_immediate" "0")
9119    (set_attr "mode" "QI")])
9120
9121 (define_insn "*andqi_ext_1_rex64"
9122   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9123                          (const_int 8)
9124                          (const_int 8))
9125         (and:SI
9126           (zero_extract:SI
9127             (match_operand 1 "ext_register_operand" "0")
9128             (const_int 8)
9129             (const_int 8))
9130           (zero_extend:SI
9131             (match_operand 2 "ext_register_operand" "Q"))))
9132    (clobber (reg:CC FLAGS_REG))]
9133   "TARGET_64BIT"
9134   "and{b}\t{%2, %h0|%h0, %2}"
9135   [(set_attr "type" "alu")
9136    (set_attr "length_immediate" "0")
9137    (set_attr "mode" "QI")])
9138
9139 (define_insn "*andqi_ext_2"
9140   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9141                          (const_int 8)
9142                          (const_int 8))
9143         (and:SI
9144           (zero_extract:SI
9145             (match_operand 1 "ext_register_operand" "%0")
9146             (const_int 8)
9147             (const_int 8))
9148           (zero_extract:SI
9149             (match_operand 2 "ext_register_operand" "Q")
9150             (const_int 8)
9151             (const_int 8))))
9152    (clobber (reg:CC FLAGS_REG))]
9153   ""
9154   "and{b}\t{%h2, %h0|%h0, %h2}"
9155   [(set_attr "type" "alu")
9156    (set_attr "length_immediate" "0")
9157    (set_attr "mode" "QI")])
9158
9159 ;; Convert wide AND instructions with immediate operand to shorter QImode
9160 ;; equivalents when possible.
9161 ;; Don't do the splitting with memory operands, since it introduces risk
9162 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9163 ;; for size, but that can (should?) be handled by generic code instead.
9164 (define_split
9165   [(set (match_operand 0 "register_operand" "")
9166         (and (match_operand 1 "register_operand" "")
9167              (match_operand 2 "const_int_operand" "")))
9168    (clobber (reg:CC FLAGS_REG))]
9169    "reload_completed
9170     && QI_REG_P (operands[0])
9171     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9172     && !(~INTVAL (operands[2]) & ~(255 << 8))
9173     && GET_MODE (operands[0]) != QImode"
9174   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9175                    (and:SI (zero_extract:SI (match_dup 1)
9176                                             (const_int 8) (const_int 8))
9177                            (match_dup 2)))
9178               (clobber (reg:CC FLAGS_REG))])]
9179   "operands[0] = gen_lowpart (SImode, operands[0]);
9180    operands[1] = gen_lowpart (SImode, operands[1]);
9181    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9182
9183 ;; Since AND can be encoded with sign extended immediate, this is only
9184 ;; profitable when 7th bit is not set.
9185 (define_split
9186   [(set (match_operand 0 "register_operand" "")
9187         (and (match_operand 1 "general_operand" "")
9188              (match_operand 2 "const_int_operand" "")))
9189    (clobber (reg:CC FLAGS_REG))]
9190    "reload_completed
9191     && ANY_QI_REG_P (operands[0])
9192     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9193     && !(~INTVAL (operands[2]) & ~255)
9194     && !(INTVAL (operands[2]) & 128)
9195     && GET_MODE (operands[0]) != QImode"
9196   [(parallel [(set (strict_low_part (match_dup 0))
9197                    (and:QI (match_dup 1)
9198                            (match_dup 2)))
9199               (clobber (reg:CC FLAGS_REG))])]
9200   "operands[0] = gen_lowpart (QImode, operands[0]);
9201    operands[1] = gen_lowpart (QImode, operands[1]);
9202    operands[2] = gen_lowpart (QImode, operands[2]);")
9203 \f
9204 ;; Logical inclusive OR instructions
9205
9206 ;; %%% This used to optimize known byte-wide and operations to memory.
9207 ;; If this is considered useful, it should be done with splitters.
9208
9209 (define_expand "iordi3"
9210   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9211         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9212                 (match_operand:DI 2 "x86_64_general_operand" "")))
9213    (clobber (reg:CC FLAGS_REG))]
9214   "TARGET_64BIT"
9215   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9216
9217 (define_insn "*iordi_1_rex64"
9218   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9219         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9220                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9221    (clobber (reg:CC FLAGS_REG))]
9222   "TARGET_64BIT
9223    && ix86_binary_operator_ok (IOR, DImode, operands)"
9224   "or{q}\t{%2, %0|%0, %2}"
9225   [(set_attr "type" "alu")
9226    (set_attr "mode" "DI")])
9227
9228 (define_insn "*iordi_2_rex64"
9229   [(set (reg FLAGS_REG)
9230         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9231                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9232                  (const_int 0)))
9233    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9234         (ior:DI (match_dup 1) (match_dup 2)))]
9235   "TARGET_64BIT
9236    && ix86_match_ccmode (insn, CCNOmode)
9237    && ix86_binary_operator_ok (IOR, DImode, operands)"
9238   "or{q}\t{%2, %0|%0, %2}"
9239   [(set_attr "type" "alu")
9240    (set_attr "mode" "DI")])
9241
9242 (define_insn "*iordi_3_rex64"
9243   [(set (reg FLAGS_REG)
9244         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9245                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9246                  (const_int 0)))
9247    (clobber (match_scratch:DI 0 "=r"))]
9248   "TARGET_64BIT
9249    && ix86_match_ccmode (insn, CCNOmode)
9250    && ix86_binary_operator_ok (IOR, DImode, operands)"
9251   "or{q}\t{%2, %0|%0, %2}"
9252   [(set_attr "type" "alu")
9253    (set_attr "mode" "DI")])
9254
9255
9256 (define_expand "iorsi3"
9257   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9258         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9259                 (match_operand:SI 2 "general_operand" "")))
9260    (clobber (reg:CC FLAGS_REG))]
9261   ""
9262   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9263
9264 (define_insn "*iorsi_1"
9265   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9266         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9267                 (match_operand:SI 2 "general_operand" "ri,g")))
9268    (clobber (reg:CC FLAGS_REG))]
9269   "ix86_binary_operator_ok (IOR, SImode, operands)"
9270   "or{l}\t{%2, %0|%0, %2}"
9271   [(set_attr "type" "alu")
9272    (set_attr "mode" "SI")])
9273
9274 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9275 (define_insn "*iorsi_1_zext"
9276   [(set (match_operand:DI 0 "register_operand" "=r")
9277         (zero_extend:DI
9278           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9279                   (match_operand:SI 2 "general_operand" "g"))))
9280    (clobber (reg:CC FLAGS_REG))]
9281   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9282   "or{l}\t{%2, %k0|%k0, %2}"
9283   [(set_attr "type" "alu")
9284    (set_attr "mode" "SI")])
9285
9286 (define_insn "*iorsi_1_zext_imm"
9287   [(set (match_operand:DI 0 "register_operand" "=r")
9288         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9289                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9290    (clobber (reg:CC FLAGS_REG))]
9291   "TARGET_64BIT"
9292   "or{l}\t{%2, %k0|%k0, %2}"
9293   [(set_attr "type" "alu")
9294    (set_attr "mode" "SI")])
9295
9296 (define_insn "*iorsi_2"
9297   [(set (reg FLAGS_REG)
9298         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9299                          (match_operand:SI 2 "general_operand" "g,ri"))
9300                  (const_int 0)))
9301    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9302         (ior:SI (match_dup 1) (match_dup 2)))]
9303   "ix86_match_ccmode (insn, CCNOmode)
9304    && ix86_binary_operator_ok (IOR, SImode, operands)"
9305   "or{l}\t{%2, %0|%0, %2}"
9306   [(set_attr "type" "alu")
9307    (set_attr "mode" "SI")])
9308
9309 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9310 ;; ??? Special case for immediate operand is missing - it is tricky.
9311 (define_insn "*iorsi_2_zext"
9312   [(set (reg FLAGS_REG)
9313         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9314                          (match_operand:SI 2 "general_operand" "g"))
9315                  (const_int 0)))
9316    (set (match_operand:DI 0 "register_operand" "=r")
9317         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9318   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9319    && ix86_binary_operator_ok (IOR, SImode, operands)"
9320   "or{l}\t{%2, %k0|%k0, %2}"
9321   [(set_attr "type" "alu")
9322    (set_attr "mode" "SI")])
9323
9324 (define_insn "*iorsi_2_zext_imm"
9325   [(set (reg FLAGS_REG)
9326         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9327                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9328                  (const_int 0)))
9329    (set (match_operand:DI 0 "register_operand" "=r")
9330         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9331   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9332    && ix86_binary_operator_ok (IOR, SImode, operands)"
9333   "or{l}\t{%2, %k0|%k0, %2}"
9334   [(set_attr "type" "alu")
9335    (set_attr "mode" "SI")])
9336
9337 (define_insn "*iorsi_3"
9338   [(set (reg FLAGS_REG)
9339         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9340                          (match_operand:SI 2 "general_operand" "g"))
9341                  (const_int 0)))
9342    (clobber (match_scratch:SI 0 "=r"))]
9343   "ix86_match_ccmode (insn, CCNOmode)
9344    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9345   "or{l}\t{%2, %0|%0, %2}"
9346   [(set_attr "type" "alu")
9347    (set_attr "mode" "SI")])
9348
9349 (define_expand "iorhi3"
9350   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9351         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9352                 (match_operand:HI 2 "general_operand" "")))
9353    (clobber (reg:CC FLAGS_REG))]
9354   "TARGET_HIMODE_MATH"
9355   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9356
9357 (define_insn "*iorhi_1"
9358   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9359         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9360                 (match_operand:HI 2 "general_operand" "g,ri")))
9361    (clobber (reg:CC FLAGS_REG))]
9362   "ix86_binary_operator_ok (IOR, HImode, operands)"
9363   "or{w}\t{%2, %0|%0, %2}"
9364   [(set_attr "type" "alu")
9365    (set_attr "mode" "HI")])
9366
9367 (define_insn "*iorhi_2"
9368   [(set (reg FLAGS_REG)
9369         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9370                          (match_operand:HI 2 "general_operand" "g,ri"))
9371                  (const_int 0)))
9372    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9373         (ior:HI (match_dup 1) (match_dup 2)))]
9374   "ix86_match_ccmode (insn, CCNOmode)
9375    && ix86_binary_operator_ok (IOR, HImode, operands)"
9376   "or{w}\t{%2, %0|%0, %2}"
9377   [(set_attr "type" "alu")
9378    (set_attr "mode" "HI")])
9379
9380 (define_insn "*iorhi_3"
9381   [(set (reg FLAGS_REG)
9382         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9383                          (match_operand:HI 2 "general_operand" "g"))
9384                  (const_int 0)))
9385    (clobber (match_scratch:HI 0 "=r"))]
9386   "ix86_match_ccmode (insn, CCNOmode)
9387    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9388   "or{w}\t{%2, %0|%0, %2}"
9389   [(set_attr "type" "alu")
9390    (set_attr "mode" "HI")])
9391
9392 (define_expand "iorqi3"
9393   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9394         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9395                 (match_operand:QI 2 "general_operand" "")))
9396    (clobber (reg:CC FLAGS_REG))]
9397   "TARGET_QIMODE_MATH"
9398   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9399
9400 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9401 (define_insn "*iorqi_1"
9402   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9403         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9404                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9405    (clobber (reg:CC FLAGS_REG))]
9406   "ix86_binary_operator_ok (IOR, QImode, operands)"
9407   "@
9408    or{b}\t{%2, %0|%0, %2}
9409    or{b}\t{%2, %0|%0, %2}
9410    or{l}\t{%k2, %k0|%k0, %k2}"
9411   [(set_attr "type" "alu")
9412    (set_attr "mode" "QI,QI,SI")])
9413
9414 (define_insn "*iorqi_1_slp"
9415   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9416         (ior:QI (match_dup 0)
9417                 (match_operand:QI 1 "general_operand" "qmi,qi")))
9418    (clobber (reg:CC FLAGS_REG))]
9419   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9420    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9421   "or{b}\t{%1, %0|%0, %1}"
9422   [(set_attr "type" "alu1")
9423    (set_attr "mode" "QI")])
9424
9425 (define_insn "*iorqi_2"
9426   [(set (reg FLAGS_REG)
9427         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9428                          (match_operand:QI 2 "general_operand" "qim,qi"))
9429                  (const_int 0)))
9430    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9431         (ior:QI (match_dup 1) (match_dup 2)))]
9432   "ix86_match_ccmode (insn, CCNOmode)
9433    && ix86_binary_operator_ok (IOR, QImode, operands)"
9434   "or{b}\t{%2, %0|%0, %2}"
9435   [(set_attr "type" "alu")
9436    (set_attr "mode" "QI")])
9437
9438 (define_insn "*iorqi_2_slp"
9439   [(set (reg FLAGS_REG)
9440         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9441                          (match_operand:QI 1 "general_operand" "qim,qi"))
9442                  (const_int 0)))
9443    (set (strict_low_part (match_dup 0))
9444         (ior:QI (match_dup 0) (match_dup 1)))]
9445   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9446    && ix86_match_ccmode (insn, CCNOmode)
9447    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9448   "or{b}\t{%1, %0|%0, %1}"
9449   [(set_attr "type" "alu1")
9450    (set_attr "mode" "QI")])
9451
9452 (define_insn "*iorqi_3"
9453   [(set (reg FLAGS_REG)
9454         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9455                          (match_operand:QI 2 "general_operand" "qim"))
9456                  (const_int 0)))
9457    (clobber (match_scratch:QI 0 "=q"))]
9458   "ix86_match_ccmode (insn, CCNOmode)
9459    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9460   "or{b}\t{%2, %0|%0, %2}"
9461   [(set_attr "type" "alu")
9462    (set_attr "mode" "QI")])
9463
9464 (define_insn "iorqi_ext_0"
9465   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9466                          (const_int 8)
9467                          (const_int 8))
9468         (ior:SI
9469           (zero_extract:SI
9470             (match_operand 1 "ext_register_operand" "0")
9471             (const_int 8)
9472             (const_int 8))
9473           (match_operand 2 "const_int_operand" "n")))
9474    (clobber (reg:CC FLAGS_REG))]
9475   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9476   "or{b}\t{%2, %h0|%h0, %2}"
9477   [(set_attr "type" "alu")
9478    (set_attr "length_immediate" "1")
9479    (set_attr "mode" "QI")])
9480
9481 (define_insn "*iorqi_ext_1"
9482   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9483                          (const_int 8)
9484                          (const_int 8))
9485         (ior:SI
9486           (zero_extract:SI
9487             (match_operand 1 "ext_register_operand" "0")
9488             (const_int 8)
9489             (const_int 8))
9490           (zero_extend:SI
9491             (match_operand:QI 2 "general_operand" "Qm"))))
9492    (clobber (reg:CC FLAGS_REG))]
9493   "!TARGET_64BIT
9494    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9495   "or{b}\t{%2, %h0|%h0, %2}"
9496   [(set_attr "type" "alu")
9497    (set_attr "length_immediate" "0")
9498    (set_attr "mode" "QI")])
9499
9500 (define_insn "*iorqi_ext_1_rex64"
9501   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9502                          (const_int 8)
9503                          (const_int 8))
9504         (ior:SI
9505           (zero_extract:SI
9506             (match_operand 1 "ext_register_operand" "0")
9507             (const_int 8)
9508             (const_int 8))
9509           (zero_extend:SI
9510             (match_operand 2 "ext_register_operand" "Q"))))
9511    (clobber (reg:CC FLAGS_REG))]
9512   "TARGET_64BIT
9513    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9514   "or{b}\t{%2, %h0|%h0, %2}"
9515   [(set_attr "type" "alu")
9516    (set_attr "length_immediate" "0")
9517    (set_attr "mode" "QI")])
9518
9519 (define_insn "*iorqi_ext_2"
9520   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9521                          (const_int 8)
9522                          (const_int 8))
9523         (ior:SI
9524           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9525                            (const_int 8)
9526                            (const_int 8))
9527           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9528                            (const_int 8)
9529                            (const_int 8))))
9530    (clobber (reg:CC FLAGS_REG))]
9531   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9532   "ior{b}\t{%h2, %h0|%h0, %h2}"
9533   [(set_attr "type" "alu")
9534    (set_attr "length_immediate" "0")
9535    (set_attr "mode" "QI")])
9536
9537 (define_split
9538   [(set (match_operand 0 "register_operand" "")
9539         (ior (match_operand 1 "register_operand" "")
9540              (match_operand 2 "const_int_operand" "")))
9541    (clobber (reg:CC FLAGS_REG))]
9542    "reload_completed
9543     && QI_REG_P (operands[0])
9544     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9545     && !(INTVAL (operands[2]) & ~(255 << 8))
9546     && GET_MODE (operands[0]) != QImode"
9547   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9548                    (ior:SI (zero_extract:SI (match_dup 1)
9549                                             (const_int 8) (const_int 8))
9550                            (match_dup 2)))
9551               (clobber (reg:CC FLAGS_REG))])]
9552   "operands[0] = gen_lowpart (SImode, operands[0]);
9553    operands[1] = gen_lowpart (SImode, operands[1]);
9554    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9555
9556 ;; Since OR can be encoded with sign extended immediate, this is only
9557 ;; profitable when 7th bit is set.
9558 (define_split
9559   [(set (match_operand 0 "register_operand" "")
9560         (ior (match_operand 1 "general_operand" "")
9561              (match_operand 2 "const_int_operand" "")))
9562    (clobber (reg:CC FLAGS_REG))]
9563    "reload_completed
9564     && ANY_QI_REG_P (operands[0])
9565     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9566     && !(INTVAL (operands[2]) & ~255)
9567     && (INTVAL (operands[2]) & 128)
9568     && GET_MODE (operands[0]) != QImode"
9569   [(parallel [(set (strict_low_part (match_dup 0))
9570                    (ior:QI (match_dup 1)
9571                            (match_dup 2)))
9572               (clobber (reg:CC FLAGS_REG))])]
9573   "operands[0] = gen_lowpart (QImode, operands[0]);
9574    operands[1] = gen_lowpart (QImode, operands[1]);
9575    operands[2] = gen_lowpart (QImode, operands[2]);")
9576 \f
9577 ;; Logical XOR instructions
9578
9579 ;; %%% This used to optimize known byte-wide and operations to memory.
9580 ;; If this is considered useful, it should be done with splitters.
9581
9582 (define_expand "xordi3"
9583   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9584         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9585                 (match_operand:DI 2 "x86_64_general_operand" "")))
9586    (clobber (reg:CC FLAGS_REG))]
9587   "TARGET_64BIT"
9588   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9589
9590 (define_insn "*xordi_1_rex64"
9591   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9592         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9593                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9594    (clobber (reg:CC FLAGS_REG))]
9595   "TARGET_64BIT
9596    && ix86_binary_operator_ok (XOR, DImode, operands)"
9597   "@
9598    xor{q}\t{%2, %0|%0, %2}
9599    xor{q}\t{%2, %0|%0, %2}"
9600   [(set_attr "type" "alu")
9601    (set_attr "mode" "DI,DI")])
9602
9603 (define_insn "*xordi_2_rex64"
9604   [(set (reg FLAGS_REG)
9605         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9606                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9607                  (const_int 0)))
9608    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9609         (xor:DI (match_dup 1) (match_dup 2)))]
9610   "TARGET_64BIT
9611    && ix86_match_ccmode (insn, CCNOmode)
9612    && ix86_binary_operator_ok (XOR, DImode, operands)"
9613   "@
9614    xor{q}\t{%2, %0|%0, %2}
9615    xor{q}\t{%2, %0|%0, %2}"
9616   [(set_attr "type" "alu")
9617    (set_attr "mode" "DI,DI")])
9618
9619 (define_insn "*xordi_3_rex64"
9620   [(set (reg FLAGS_REG)
9621         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9622                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9623                  (const_int 0)))
9624    (clobber (match_scratch:DI 0 "=r"))]
9625   "TARGET_64BIT
9626    && ix86_match_ccmode (insn, CCNOmode)
9627    && ix86_binary_operator_ok (XOR, DImode, operands)"
9628   "xor{q}\t{%2, %0|%0, %2}"
9629   [(set_attr "type" "alu")
9630    (set_attr "mode" "DI")])
9631
9632 (define_expand "xorsi3"
9633   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9634         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9635                 (match_operand:SI 2 "general_operand" "")))
9636    (clobber (reg:CC FLAGS_REG))]
9637   ""
9638   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9639
9640 (define_insn "*xorsi_1"
9641   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9642         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9643                 (match_operand:SI 2 "general_operand" "ri,rm")))
9644    (clobber (reg:CC FLAGS_REG))]
9645   "ix86_binary_operator_ok (XOR, SImode, operands)"
9646   "xor{l}\t{%2, %0|%0, %2}"
9647   [(set_attr "type" "alu")
9648    (set_attr "mode" "SI")])
9649
9650 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9651 ;; Add speccase for immediates
9652 (define_insn "*xorsi_1_zext"
9653   [(set (match_operand:DI 0 "register_operand" "=r")
9654         (zero_extend:DI
9655           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9656                   (match_operand:SI 2 "general_operand" "g"))))
9657    (clobber (reg:CC FLAGS_REG))]
9658   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9659   "xor{l}\t{%2, %k0|%k0, %2}"
9660   [(set_attr "type" "alu")
9661    (set_attr "mode" "SI")])
9662
9663 (define_insn "*xorsi_1_zext_imm"
9664   [(set (match_operand:DI 0 "register_operand" "=r")
9665         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9666                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9667    (clobber (reg:CC FLAGS_REG))]
9668   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9669   "xor{l}\t{%2, %k0|%k0, %2}"
9670   [(set_attr "type" "alu")
9671    (set_attr "mode" "SI")])
9672
9673 (define_insn "*xorsi_2"
9674   [(set (reg FLAGS_REG)
9675         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9676                          (match_operand:SI 2 "general_operand" "g,ri"))
9677                  (const_int 0)))
9678    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9679         (xor:SI (match_dup 1) (match_dup 2)))]
9680   "ix86_match_ccmode (insn, CCNOmode)
9681    && ix86_binary_operator_ok (XOR, SImode, operands)"
9682   "xor{l}\t{%2, %0|%0, %2}"
9683   [(set_attr "type" "alu")
9684    (set_attr "mode" "SI")])
9685
9686 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9687 ;; ??? Special case for immediate operand is missing - it is tricky.
9688 (define_insn "*xorsi_2_zext"
9689   [(set (reg FLAGS_REG)
9690         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9691                          (match_operand:SI 2 "general_operand" "g"))
9692                  (const_int 0)))
9693    (set (match_operand:DI 0 "register_operand" "=r")
9694         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9695   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9696    && ix86_binary_operator_ok (XOR, SImode, operands)"
9697   "xor{l}\t{%2, %k0|%k0, %2}"
9698   [(set_attr "type" "alu")
9699    (set_attr "mode" "SI")])
9700
9701 (define_insn "*xorsi_2_zext_imm"
9702   [(set (reg FLAGS_REG)
9703         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9704                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9705                  (const_int 0)))
9706    (set (match_operand:DI 0 "register_operand" "=r")
9707         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9708   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9709    && ix86_binary_operator_ok (XOR, SImode, operands)"
9710   "xor{l}\t{%2, %k0|%k0, %2}"
9711   [(set_attr "type" "alu")
9712    (set_attr "mode" "SI")])
9713
9714 (define_insn "*xorsi_3"
9715   [(set (reg FLAGS_REG)
9716         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9717                          (match_operand:SI 2 "general_operand" "g"))
9718                  (const_int 0)))
9719    (clobber (match_scratch:SI 0 "=r"))]
9720   "ix86_match_ccmode (insn, CCNOmode)
9721    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9722   "xor{l}\t{%2, %0|%0, %2}"
9723   [(set_attr "type" "alu")
9724    (set_attr "mode" "SI")])
9725
9726 (define_expand "xorhi3"
9727   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9728         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9729                 (match_operand:HI 2 "general_operand" "")))
9730    (clobber (reg:CC FLAGS_REG))]
9731   "TARGET_HIMODE_MATH"
9732   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9733
9734 (define_insn "*xorhi_1"
9735   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9736         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9737                 (match_operand:HI 2 "general_operand" "g,ri")))
9738    (clobber (reg:CC FLAGS_REG))]
9739   "ix86_binary_operator_ok (XOR, HImode, operands)"
9740   "xor{w}\t{%2, %0|%0, %2}"
9741   [(set_attr "type" "alu")
9742    (set_attr "mode" "HI")])
9743
9744 (define_insn "*xorhi_2"
9745   [(set (reg FLAGS_REG)
9746         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9747                          (match_operand:HI 2 "general_operand" "g,ri"))
9748                  (const_int 0)))
9749    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9750         (xor:HI (match_dup 1) (match_dup 2)))]
9751   "ix86_match_ccmode (insn, CCNOmode)
9752    && ix86_binary_operator_ok (XOR, HImode, operands)"
9753   "xor{w}\t{%2, %0|%0, %2}"
9754   [(set_attr "type" "alu")
9755    (set_attr "mode" "HI")])
9756
9757 (define_insn "*xorhi_3"
9758   [(set (reg FLAGS_REG)
9759         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9760                          (match_operand:HI 2 "general_operand" "g"))
9761                  (const_int 0)))
9762    (clobber (match_scratch:HI 0 "=r"))]
9763   "ix86_match_ccmode (insn, CCNOmode)
9764    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9765   "xor{w}\t{%2, %0|%0, %2}"
9766   [(set_attr "type" "alu")
9767    (set_attr "mode" "HI")])
9768
9769 (define_expand "xorqi3"
9770   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9771         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9772                 (match_operand:QI 2 "general_operand" "")))
9773    (clobber (reg:CC FLAGS_REG))]
9774   "TARGET_QIMODE_MATH"
9775   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9776
9777 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9778 (define_insn "*xorqi_1"
9779   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9780         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9781                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9782    (clobber (reg:CC FLAGS_REG))]
9783   "ix86_binary_operator_ok (XOR, QImode, operands)"
9784   "@
9785    xor{b}\t{%2, %0|%0, %2}
9786    xor{b}\t{%2, %0|%0, %2}
9787    xor{l}\t{%k2, %k0|%k0, %k2}"
9788   [(set_attr "type" "alu")
9789    (set_attr "mode" "QI,QI,SI")])
9790
9791 (define_insn "*xorqi_1_slp"
9792   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9793         (xor:QI (match_dup 0)
9794                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9795    (clobber (reg:CC FLAGS_REG))]
9796   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9797    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9798   "xor{b}\t{%1, %0|%0, %1}"
9799   [(set_attr "type" "alu1")
9800    (set_attr "mode" "QI")])
9801
9802 (define_insn "xorqi_ext_0"
9803   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9804                          (const_int 8)
9805                          (const_int 8))
9806         (xor:SI
9807           (zero_extract:SI
9808             (match_operand 1 "ext_register_operand" "0")
9809             (const_int 8)
9810             (const_int 8))
9811           (match_operand 2 "const_int_operand" "n")))
9812    (clobber (reg:CC FLAGS_REG))]
9813   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9814   "xor{b}\t{%2, %h0|%h0, %2}"
9815   [(set_attr "type" "alu")
9816    (set_attr "length_immediate" "1")
9817    (set_attr "mode" "QI")])
9818
9819 (define_insn "*xorqi_ext_1"
9820   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9821                          (const_int 8)
9822                          (const_int 8))
9823         (xor:SI
9824           (zero_extract:SI
9825             (match_operand 1 "ext_register_operand" "0")
9826             (const_int 8)
9827             (const_int 8))
9828           (zero_extend:SI
9829             (match_operand:QI 2 "general_operand" "Qm"))))
9830    (clobber (reg:CC FLAGS_REG))]
9831   "!TARGET_64BIT
9832    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9833   "xor{b}\t{%2, %h0|%h0, %2}"
9834   [(set_attr "type" "alu")
9835    (set_attr "length_immediate" "0")
9836    (set_attr "mode" "QI")])
9837
9838 (define_insn "*xorqi_ext_1_rex64"
9839   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9840                          (const_int 8)
9841                          (const_int 8))
9842         (xor:SI
9843           (zero_extract:SI
9844             (match_operand 1 "ext_register_operand" "0")
9845             (const_int 8)
9846             (const_int 8))
9847           (zero_extend:SI
9848             (match_operand 2 "ext_register_operand" "Q"))))
9849    (clobber (reg:CC FLAGS_REG))]
9850   "TARGET_64BIT
9851    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9852   "xor{b}\t{%2, %h0|%h0, %2}"
9853   [(set_attr "type" "alu")
9854    (set_attr "length_immediate" "0")
9855    (set_attr "mode" "QI")])
9856
9857 (define_insn "*xorqi_ext_2"
9858   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9859                          (const_int 8)
9860                          (const_int 8))
9861         (xor:SI
9862           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9863                            (const_int 8)
9864                            (const_int 8))
9865           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9866                            (const_int 8)
9867                            (const_int 8))))
9868    (clobber (reg:CC FLAGS_REG))]
9869   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9870   "xor{b}\t{%h2, %h0|%h0, %h2}"
9871   [(set_attr "type" "alu")
9872    (set_attr "length_immediate" "0")
9873    (set_attr "mode" "QI")])
9874
9875 (define_insn "*xorqi_cc_1"
9876   [(set (reg FLAGS_REG)
9877         (compare
9878           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9879                   (match_operand:QI 2 "general_operand" "qim,qi"))
9880           (const_int 0)))
9881    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9882         (xor:QI (match_dup 1) (match_dup 2)))]
9883   "ix86_match_ccmode (insn, CCNOmode)
9884    && ix86_binary_operator_ok (XOR, QImode, operands)"
9885   "xor{b}\t{%2, %0|%0, %2}"
9886   [(set_attr "type" "alu")
9887    (set_attr "mode" "QI")])
9888
9889 (define_insn "*xorqi_2_slp"
9890   [(set (reg FLAGS_REG)
9891         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9892                          (match_operand:QI 1 "general_operand" "qim,qi"))
9893                  (const_int 0)))
9894    (set (strict_low_part (match_dup 0))
9895         (xor:QI (match_dup 0) (match_dup 1)))]
9896   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9897    && ix86_match_ccmode (insn, CCNOmode)
9898    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9899   "xor{b}\t{%1, %0|%0, %1}"
9900   [(set_attr "type" "alu1")
9901    (set_attr "mode" "QI")])
9902
9903 (define_insn "*xorqi_cc_2"
9904   [(set (reg FLAGS_REG)
9905         (compare
9906           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9907                   (match_operand:QI 2 "general_operand" "qim"))
9908           (const_int 0)))
9909    (clobber (match_scratch:QI 0 "=q"))]
9910   "ix86_match_ccmode (insn, CCNOmode)
9911    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9912   "xor{b}\t{%2, %0|%0, %2}"
9913   [(set_attr "type" "alu")
9914    (set_attr "mode" "QI")])
9915
9916 (define_insn "*xorqi_cc_ext_1"
9917   [(set (reg FLAGS_REG)
9918         (compare
9919           (xor:SI
9920             (zero_extract:SI
9921               (match_operand 1 "ext_register_operand" "0")
9922               (const_int 8)
9923               (const_int 8))
9924             (match_operand:QI 2 "general_operand" "qmn"))
9925           (const_int 0)))
9926    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9927                          (const_int 8)
9928                          (const_int 8))
9929         (xor:SI
9930           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9931           (match_dup 2)))]
9932   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9933   "xor{b}\t{%2, %h0|%h0, %2}"
9934   [(set_attr "type" "alu")
9935    (set_attr "mode" "QI")])
9936
9937 (define_insn "*xorqi_cc_ext_1_rex64"
9938   [(set (reg FLAGS_REG)
9939         (compare
9940           (xor:SI
9941             (zero_extract:SI
9942               (match_operand 1 "ext_register_operand" "0")
9943               (const_int 8)
9944               (const_int 8))
9945             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9946           (const_int 0)))
9947    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9948                          (const_int 8)
9949                          (const_int 8))
9950         (xor:SI
9951           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9952           (match_dup 2)))]
9953   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9954   "xor{b}\t{%2, %h0|%h0, %2}"
9955   [(set_attr "type" "alu")
9956    (set_attr "mode" "QI")])
9957
9958 (define_expand "xorqi_cc_ext_1"
9959   [(parallel [
9960      (set (reg:CCNO FLAGS_REG)
9961           (compare:CCNO
9962             (xor:SI
9963               (zero_extract:SI
9964                 (match_operand 1 "ext_register_operand" "")
9965                 (const_int 8)
9966                 (const_int 8))
9967               (match_operand:QI 2 "general_operand" ""))
9968             (const_int 0)))
9969      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9970                            (const_int 8)
9971                            (const_int 8))
9972           (xor:SI
9973             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9974             (match_dup 2)))])]
9975   ""
9976   "")
9977
9978 (define_split
9979   [(set (match_operand 0 "register_operand" "")
9980         (xor (match_operand 1 "register_operand" "")
9981              (match_operand 2 "const_int_operand" "")))
9982    (clobber (reg:CC FLAGS_REG))]
9983    "reload_completed
9984     && QI_REG_P (operands[0])
9985     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9986     && !(INTVAL (operands[2]) & ~(255 << 8))
9987     && GET_MODE (operands[0]) != QImode"
9988   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9989                    (xor:SI (zero_extract:SI (match_dup 1)
9990                                             (const_int 8) (const_int 8))
9991                            (match_dup 2)))
9992               (clobber (reg:CC FLAGS_REG))])]
9993   "operands[0] = gen_lowpart (SImode, operands[0]);
9994    operands[1] = gen_lowpart (SImode, operands[1]);
9995    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9996
9997 ;; Since XOR can be encoded with sign extended immediate, this is only
9998 ;; profitable when 7th bit is set.
9999 (define_split
10000   [(set (match_operand 0 "register_operand" "")
10001         (xor (match_operand 1 "general_operand" "")
10002              (match_operand 2 "const_int_operand" "")))
10003    (clobber (reg:CC FLAGS_REG))]
10004    "reload_completed
10005     && ANY_QI_REG_P (operands[0])
10006     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10007     && !(INTVAL (operands[2]) & ~255)
10008     && (INTVAL (operands[2]) & 128)
10009     && GET_MODE (operands[0]) != QImode"
10010   [(parallel [(set (strict_low_part (match_dup 0))
10011                    (xor:QI (match_dup 1)
10012                            (match_dup 2)))
10013               (clobber (reg:CC FLAGS_REG))])]
10014   "operands[0] = gen_lowpart (QImode, operands[0]);
10015    operands[1] = gen_lowpart (QImode, operands[1]);
10016    operands[2] = gen_lowpart (QImode, operands[2]);")
10017 \f
10018 ;; Negation instructions
10019
10020 (define_expand "negti2"
10021   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
10022                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10023               (clobber (reg:CC FLAGS_REG))])]
10024   "TARGET_64BIT"
10025   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10026
10027 (define_insn "*negti2_1"
10028   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10029         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10030    (clobber (reg:CC FLAGS_REG))]
10031   "TARGET_64BIT
10032    && ix86_unary_operator_ok (NEG, TImode, operands)"
10033   "#")
10034
10035 (define_split
10036   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10037         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10038    (clobber (reg:CC FLAGS_REG))]
10039   "TARGET_64BIT && reload_completed"
10040   [(parallel
10041     [(set (reg:CCZ FLAGS_REG)
10042           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
10043      (set (match_dup 0) (neg:DI (match_dup 2)))])
10044    (parallel
10045     [(set (match_dup 1)
10046           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10047                             (match_dup 3))
10048                    (const_int 0)))
10049      (clobber (reg:CC FLAGS_REG))])
10050    (parallel
10051     [(set (match_dup 1)
10052           (neg:DI (match_dup 1)))
10053      (clobber (reg:CC FLAGS_REG))])]
10054   "split_ti (operands+1, 1, operands+2, operands+3);
10055    split_ti (operands+0, 1, operands+0, operands+1);")
10056
10057 (define_expand "negdi2"
10058   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
10059                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
10060               (clobber (reg:CC FLAGS_REG))])]
10061   ""
10062   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10063
10064 (define_insn "*negdi2_1"
10065   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10066         (neg:DI (match_operand:DI 1 "general_operand" "0")))
10067    (clobber (reg:CC FLAGS_REG))]
10068   "!TARGET_64BIT
10069    && ix86_unary_operator_ok (NEG, DImode, operands)"
10070   "#")
10071
10072 (define_split
10073   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10074         (neg:DI (match_operand:DI 1 "general_operand" "")))
10075    (clobber (reg:CC FLAGS_REG))]
10076   "!TARGET_64BIT && reload_completed"
10077   [(parallel
10078     [(set (reg:CCZ FLAGS_REG)
10079           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
10080      (set (match_dup 0) (neg:SI (match_dup 2)))])
10081    (parallel
10082     [(set (match_dup 1)
10083           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10084                             (match_dup 3))
10085                    (const_int 0)))
10086      (clobber (reg:CC FLAGS_REG))])
10087    (parallel
10088     [(set (match_dup 1)
10089           (neg:SI (match_dup 1)))
10090      (clobber (reg:CC FLAGS_REG))])]
10091   "split_di (operands+1, 1, operands+2, operands+3);
10092    split_di (operands+0, 1, operands+0, operands+1);")
10093
10094 (define_insn "*negdi2_1_rex64"
10095   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10096         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10097    (clobber (reg:CC FLAGS_REG))]
10098   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10099   "neg{q}\t%0"
10100   [(set_attr "type" "negnot")
10101    (set_attr "mode" "DI")])
10102
10103 ;; The problem with neg is that it does not perform (compare x 0),
10104 ;; it really performs (compare 0 x), which leaves us with the zero
10105 ;; flag being the only useful item.
10106
10107 (define_insn "*negdi2_cmpz_rex64"
10108   [(set (reg:CCZ FLAGS_REG)
10109         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10110                      (const_int 0)))
10111    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10112         (neg:DI (match_dup 1)))]
10113   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10114   "neg{q}\t%0"
10115   [(set_attr "type" "negnot")
10116    (set_attr "mode" "DI")])
10117
10118
10119 (define_expand "negsi2"
10120   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
10121                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
10122               (clobber (reg:CC FLAGS_REG))])]
10123   ""
10124   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10125
10126 (define_insn "*negsi2_1"
10127   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10128         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10129    (clobber (reg:CC FLAGS_REG))]
10130   "ix86_unary_operator_ok (NEG, SImode, operands)"
10131   "neg{l}\t%0"
10132   [(set_attr "type" "negnot")
10133    (set_attr "mode" "SI")])
10134
10135 ;; Combine is quite creative about this pattern.
10136 (define_insn "*negsi2_1_zext"
10137   [(set (match_operand:DI 0 "register_operand" "=r")
10138         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10139                                         (const_int 32)))
10140                      (const_int 32)))
10141    (clobber (reg:CC FLAGS_REG))]
10142   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10143   "neg{l}\t%k0"
10144   [(set_attr "type" "negnot")
10145    (set_attr "mode" "SI")])
10146
10147 ;; The problem with neg is that it does not perform (compare x 0),
10148 ;; it really performs (compare 0 x), which leaves us with the zero
10149 ;; flag being the only useful item.
10150
10151 (define_insn "*negsi2_cmpz"
10152   [(set (reg:CCZ FLAGS_REG)
10153         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10154                      (const_int 0)))
10155    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10156         (neg:SI (match_dup 1)))]
10157   "ix86_unary_operator_ok (NEG, SImode, operands)"
10158   "neg{l}\t%0"
10159   [(set_attr "type" "negnot")
10160    (set_attr "mode" "SI")])
10161
10162 (define_insn "*negsi2_cmpz_zext"
10163   [(set (reg:CCZ FLAGS_REG)
10164         (compare:CCZ (lshiftrt:DI
10165                        (neg:DI (ashift:DI
10166                                  (match_operand:DI 1 "register_operand" "0")
10167                                  (const_int 32)))
10168                        (const_int 32))
10169                      (const_int 0)))
10170    (set (match_operand:DI 0 "register_operand" "=r")
10171         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10172                                         (const_int 32)))
10173                      (const_int 32)))]
10174   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10175   "neg{l}\t%k0"
10176   [(set_attr "type" "negnot")
10177    (set_attr "mode" "SI")])
10178
10179 (define_expand "neghi2"
10180   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
10181                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10182               (clobber (reg:CC FLAGS_REG))])]
10183   "TARGET_HIMODE_MATH"
10184   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10185
10186 (define_insn "*neghi2_1"
10187   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10188         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10189    (clobber (reg:CC FLAGS_REG))]
10190   "ix86_unary_operator_ok (NEG, HImode, operands)"
10191   "neg{w}\t%0"
10192   [(set_attr "type" "negnot")
10193    (set_attr "mode" "HI")])
10194
10195 (define_insn "*neghi2_cmpz"
10196   [(set (reg:CCZ FLAGS_REG)
10197         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10198                      (const_int 0)))
10199    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10200         (neg:HI (match_dup 1)))]
10201   "ix86_unary_operator_ok (NEG, HImode, operands)"
10202   "neg{w}\t%0"
10203   [(set_attr "type" "negnot")
10204    (set_attr "mode" "HI")])
10205
10206 (define_expand "negqi2"
10207   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10208                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10209               (clobber (reg:CC FLAGS_REG))])]
10210   "TARGET_QIMODE_MATH"
10211   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10212
10213 (define_insn "*negqi2_1"
10214   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10215         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10216    (clobber (reg:CC FLAGS_REG))]
10217   "ix86_unary_operator_ok (NEG, QImode, operands)"
10218   "neg{b}\t%0"
10219   [(set_attr "type" "negnot")
10220    (set_attr "mode" "QI")])
10221
10222 (define_insn "*negqi2_cmpz"
10223   [(set (reg:CCZ FLAGS_REG)
10224         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10225                      (const_int 0)))
10226    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10227         (neg:QI (match_dup 1)))]
10228   "ix86_unary_operator_ok (NEG, QImode, operands)"
10229   "neg{b}\t%0"
10230   [(set_attr "type" "negnot")
10231    (set_attr "mode" "QI")])
10232
10233 ;; Changing of sign for FP values is doable using integer unit too.
10234
10235 (define_expand "neg<mode>2"
10236   [(set (match_operand:X87MODEF 0 "register_operand" "")
10237         (neg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10238   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10239   "ix86_expand_fp_absneg_operator (NEG, <MODE>mode, operands); DONE;")
10240
10241 (define_expand "abs<mode>2"
10242   [(set (match_operand:X87MODEF 0 "register_operand" "")
10243         (abs:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10244   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10245   "ix86_expand_fp_absneg_operator (ABS, <MODE>mode, operands); DONE;")
10246
10247 (define_insn "*absneg<mode>2_mixed"
10248   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10249         (match_operator:MODEF 3 "absneg_operator"
10250           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10251    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10252    (clobber (reg:CC FLAGS_REG))]
10253   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10254   "#")
10255
10256 (define_insn "*absneg<mode>2_sse"
10257   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10258         (match_operator:MODEF 3 "absneg_operator"
10259           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10260    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10261    (clobber (reg:CC FLAGS_REG))]
10262   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10263   "#")
10264
10265 (define_insn "*absneg<mode>2_i387"
10266   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10267         (match_operator:X87MODEF 3 "absneg_operator"
10268           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10269    (use (match_operand 2 "" ""))
10270    (clobber (reg:CC FLAGS_REG))]
10271   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10272   "#")
10273
10274 (define_expand "negtf2"
10275   [(set (match_operand:TF 0 "register_operand" "")
10276         (neg:TF (match_operand:TF 1 "register_operand" "")))]
10277   "TARGET_64BIT"
10278   "ix86_expand_fp_absneg_operator (NEG, TFmode, operands); DONE;")
10279
10280 (define_expand "abstf2"
10281   [(set (match_operand:TF 0 "register_operand" "")
10282         (abs:TF (match_operand:TF 1 "register_operand" "")))]
10283   "TARGET_64BIT"
10284   "ix86_expand_fp_absneg_operator (ABS, TFmode, operands); DONE;")
10285
10286 (define_insn "*absnegtf2_sse"
10287   [(set (match_operand:TF 0 "register_operand" "=x,x")
10288         (match_operator:TF 3 "absneg_operator"
10289           [(match_operand:TF 1 "register_operand" "0,x")]))
10290    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10291    (clobber (reg:CC FLAGS_REG))]
10292   "TARGET_64BIT"
10293   "#")
10294
10295 ;; Splitters for fp abs and neg.
10296
10297 (define_split
10298   [(set (match_operand 0 "fp_register_operand" "")
10299         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10300    (use (match_operand 2 "" ""))
10301    (clobber (reg:CC FLAGS_REG))]
10302   "reload_completed"
10303   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10304
10305 (define_split
10306   [(set (match_operand 0 "register_operand" "")
10307         (match_operator 3 "absneg_operator"
10308           [(match_operand 1 "register_operand" "")]))
10309    (use (match_operand 2 "nonimmediate_operand" ""))
10310    (clobber (reg:CC FLAGS_REG))]
10311   "reload_completed && SSE_REG_P (operands[0])"
10312   [(set (match_dup 0) (match_dup 3))]
10313 {
10314   enum machine_mode mode = GET_MODE (operands[0]);
10315   enum machine_mode vmode = GET_MODE (operands[2]);
10316   rtx tmp;
10317
10318   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10319   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10320   if (operands_match_p (operands[0], operands[2]))
10321     {
10322       tmp = operands[1];
10323       operands[1] = operands[2];
10324       operands[2] = tmp;
10325     }
10326   if (GET_CODE (operands[3]) == ABS)
10327     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10328   else
10329     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10330   operands[3] = tmp;
10331 })
10332
10333 (define_split
10334   [(set (match_operand:SF 0 "register_operand" "")
10335         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10336    (use (match_operand:V4SF 2 "" ""))
10337    (clobber (reg:CC FLAGS_REG))]
10338   "reload_completed"
10339   [(parallel [(set (match_dup 0) (match_dup 1))
10340               (clobber (reg:CC FLAGS_REG))])]
10341 {
10342   rtx tmp;
10343   operands[0] = gen_lowpart (SImode, operands[0]);
10344   if (GET_CODE (operands[1]) == ABS)
10345     {
10346       tmp = gen_int_mode (0x7fffffff, SImode);
10347       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10348     }
10349   else
10350     {
10351       tmp = gen_int_mode (0x80000000, SImode);
10352       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10353     }
10354   operands[1] = tmp;
10355 })
10356
10357 (define_split
10358   [(set (match_operand:DF 0 "register_operand" "")
10359         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10360    (use (match_operand 2 "" ""))
10361    (clobber (reg:CC FLAGS_REG))]
10362   "reload_completed"
10363   [(parallel [(set (match_dup 0) (match_dup 1))
10364               (clobber (reg:CC FLAGS_REG))])]
10365 {
10366   rtx tmp;
10367   if (TARGET_64BIT)
10368     {
10369       tmp = gen_lowpart (DImode, operands[0]);
10370       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10371       operands[0] = tmp;
10372
10373       if (GET_CODE (operands[1]) == ABS)
10374         tmp = const0_rtx;
10375       else
10376         tmp = gen_rtx_NOT (DImode, tmp);
10377     }
10378   else
10379     {
10380       operands[0] = gen_highpart (SImode, operands[0]);
10381       if (GET_CODE (operands[1]) == ABS)
10382         {
10383           tmp = gen_int_mode (0x7fffffff, SImode);
10384           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10385         }
10386       else
10387         {
10388           tmp = gen_int_mode (0x80000000, SImode);
10389           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10390         }
10391     }
10392   operands[1] = tmp;
10393 })
10394
10395 (define_split
10396   [(set (match_operand:XF 0 "register_operand" "")
10397         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10398    (use (match_operand 2 "" ""))
10399    (clobber (reg:CC FLAGS_REG))]
10400   "reload_completed"
10401   [(parallel [(set (match_dup 0) (match_dup 1))
10402               (clobber (reg:CC FLAGS_REG))])]
10403 {
10404   rtx tmp;
10405   operands[0] = gen_rtx_REG (SImode,
10406                              true_regnum (operands[0])
10407                              + (TARGET_64BIT ? 1 : 2));
10408   if (GET_CODE (operands[1]) == ABS)
10409     {
10410       tmp = GEN_INT (0x7fff);
10411       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10412     }
10413   else
10414     {
10415       tmp = GEN_INT (0x8000);
10416       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10417     }
10418   operands[1] = tmp;
10419 })
10420
10421 ;; Conditionalize these after reload. If they match before reload, we
10422 ;; lose the clobber and ability to use integer instructions.
10423
10424 (define_insn "*neg<mode>2_1"
10425   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10426         (neg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10427   "TARGET_80387
10428    && (reload_completed || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10429   "fchs"
10430   [(set_attr "type" "fsgn")
10431    (set_attr "mode" "<MODE>")])
10432
10433 (define_insn "*abs<mode>2_1"
10434   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10435         (abs:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10436   "TARGET_80387
10437    && (reload_completed || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10438   "fabs"
10439   [(set_attr "type" "fsgn")
10440    (set_attr "mode" "<MODE>")])
10441
10442 (define_insn "*negextendsfdf2"
10443   [(set (match_operand:DF 0 "register_operand" "=f")
10444         (neg:DF (float_extend:DF
10445                   (match_operand:SF 1 "register_operand" "0"))))]
10446   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10447   "fchs"
10448   [(set_attr "type" "fsgn")
10449    (set_attr "mode" "DF")])
10450
10451 (define_insn "*negextenddfxf2"
10452   [(set (match_operand:XF 0 "register_operand" "=f")
10453         (neg:XF (float_extend:XF
10454                   (match_operand:DF 1 "register_operand" "0"))))]
10455   "TARGET_80387"
10456   "fchs"
10457   [(set_attr "type" "fsgn")
10458    (set_attr "mode" "XF")])
10459
10460 (define_insn "*negextendsfxf2"
10461   [(set (match_operand:XF 0 "register_operand" "=f")
10462         (neg:XF (float_extend:XF
10463                   (match_operand:SF 1 "register_operand" "0"))))]
10464   "TARGET_80387"
10465   "fchs"
10466   [(set_attr "type" "fsgn")
10467    (set_attr "mode" "XF")])
10468
10469 (define_insn "*absextendsfdf2"
10470   [(set (match_operand:DF 0 "register_operand" "=f")
10471         (abs:DF (float_extend:DF
10472                   (match_operand:SF 1 "register_operand" "0"))))]
10473   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10474   "fabs"
10475   [(set_attr "type" "fsgn")
10476    (set_attr "mode" "DF")])
10477
10478 (define_insn "*absextenddfxf2"
10479   [(set (match_operand:XF 0 "register_operand" "=f")
10480         (abs:XF (float_extend:XF
10481           (match_operand:DF 1 "register_operand" "0"))))]
10482   "TARGET_80387"
10483   "fabs"
10484   [(set_attr "type" "fsgn")
10485    (set_attr "mode" "XF")])
10486
10487 (define_insn "*absextendsfxf2"
10488   [(set (match_operand:XF 0 "register_operand" "=f")
10489         (abs:XF (float_extend:XF
10490           (match_operand:SF 1 "register_operand" "0"))))]
10491   "TARGET_80387"
10492   "fabs"
10493   [(set_attr "type" "fsgn")
10494    (set_attr "mode" "XF")])
10495
10496 ;; Copysign instructions
10497
10498 (define_mode_iterator CSGNMODE [SF DF TF])
10499 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10500
10501 (define_expand "copysign<mode>3"
10502   [(match_operand:CSGNMODE 0 "register_operand" "")
10503    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10504    (match_operand:CSGNMODE 2 "register_operand" "")]
10505   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10506    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10507 {
10508   ix86_expand_copysign (operands);
10509   DONE;
10510 })
10511
10512 (define_insn_and_split "copysign<mode>3_const"
10513   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10514         (unspec:CSGNMODE
10515           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10516            (match_operand:CSGNMODE 2 "register_operand" "0")
10517            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10518           UNSPEC_COPYSIGN))]
10519   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10520    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10521   "#"
10522   "&& reload_completed"
10523   [(const_int 0)]
10524 {
10525   ix86_split_copysign_const (operands);
10526   DONE;
10527 })
10528
10529 (define_insn "copysign<mode>3_var"
10530   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10531         (unspec:CSGNMODE
10532           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10533            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10534            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10535            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10536           UNSPEC_COPYSIGN))
10537    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10538   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10539    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10540   "#")
10541
10542 (define_split
10543   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10544         (unspec:CSGNMODE
10545           [(match_operand:CSGNMODE 2 "register_operand" "")
10546            (match_operand:CSGNMODE 3 "register_operand" "")
10547            (match_operand:<CSGNVMODE> 4 "" "")
10548            (match_operand:<CSGNVMODE> 5 "" "")]
10549           UNSPEC_COPYSIGN))
10550    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10551   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10552     || (TARGET_64BIT && (<MODE>mode == TFmode)))
10553    && reload_completed"
10554   [(const_int 0)]
10555 {
10556   ix86_split_copysign_var (operands);
10557   DONE;
10558 })
10559 \f
10560 ;; One complement instructions
10561
10562 (define_expand "one_cmpldi2"
10563   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10564         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10565   "TARGET_64BIT"
10566   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10567
10568 (define_insn "*one_cmpldi2_1_rex64"
10569   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10570         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10571   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10572   "not{q}\t%0"
10573   [(set_attr "type" "negnot")
10574    (set_attr "mode" "DI")])
10575
10576 (define_insn "*one_cmpldi2_2_rex64"
10577   [(set (reg FLAGS_REG)
10578         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10579                  (const_int 0)))
10580    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10581         (not:DI (match_dup 1)))]
10582   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10583    && ix86_unary_operator_ok (NOT, DImode, operands)"
10584   "#"
10585   [(set_attr "type" "alu1")
10586    (set_attr "mode" "DI")])
10587
10588 (define_split
10589   [(set (match_operand 0 "flags_reg_operand" "")
10590         (match_operator 2 "compare_operator"
10591           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10592            (const_int 0)]))
10593    (set (match_operand:DI 1 "nonimmediate_operand" "")
10594         (not:DI (match_dup 3)))]
10595   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10596   [(parallel [(set (match_dup 0)
10597                    (match_op_dup 2
10598                      [(xor:DI (match_dup 3) (const_int -1))
10599                       (const_int 0)]))
10600               (set (match_dup 1)
10601                    (xor:DI (match_dup 3) (const_int -1)))])]
10602   "")
10603
10604 (define_expand "one_cmplsi2"
10605   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10606         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10607   ""
10608   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10609
10610 (define_insn "*one_cmplsi2_1"
10611   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10612         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10613   "ix86_unary_operator_ok (NOT, SImode, operands)"
10614   "not{l}\t%0"
10615   [(set_attr "type" "negnot")
10616    (set_attr "mode" "SI")])
10617
10618 ;; ??? Currently never generated - xor is used instead.
10619 (define_insn "*one_cmplsi2_1_zext"
10620   [(set (match_operand:DI 0 "register_operand" "=r")
10621         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10622   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10623   "not{l}\t%k0"
10624   [(set_attr "type" "negnot")
10625    (set_attr "mode" "SI")])
10626
10627 (define_insn "*one_cmplsi2_2"
10628   [(set (reg FLAGS_REG)
10629         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10630                  (const_int 0)))
10631    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10632         (not:SI (match_dup 1)))]
10633   "ix86_match_ccmode (insn, CCNOmode)
10634    && ix86_unary_operator_ok (NOT, SImode, operands)"
10635   "#"
10636   [(set_attr "type" "alu1")
10637    (set_attr "mode" "SI")])
10638
10639 (define_split
10640   [(set (match_operand 0 "flags_reg_operand" "")
10641         (match_operator 2 "compare_operator"
10642           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10643            (const_int 0)]))
10644    (set (match_operand:SI 1 "nonimmediate_operand" "")
10645         (not:SI (match_dup 3)))]
10646   "ix86_match_ccmode (insn, CCNOmode)"
10647   [(parallel [(set (match_dup 0)
10648                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10649                                     (const_int 0)]))
10650               (set (match_dup 1)
10651                    (xor:SI (match_dup 3) (const_int -1)))])]
10652   "")
10653
10654 ;; ??? Currently never generated - xor is used instead.
10655 (define_insn "*one_cmplsi2_2_zext"
10656   [(set (reg FLAGS_REG)
10657         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10658                  (const_int 0)))
10659    (set (match_operand:DI 0 "register_operand" "=r")
10660         (zero_extend:DI (not:SI (match_dup 1))))]
10661   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10662    && ix86_unary_operator_ok (NOT, SImode, operands)"
10663   "#"
10664   [(set_attr "type" "alu1")
10665    (set_attr "mode" "SI")])
10666
10667 (define_split
10668   [(set (match_operand 0 "flags_reg_operand" "")
10669         (match_operator 2 "compare_operator"
10670           [(not:SI (match_operand:SI 3 "register_operand" ""))
10671            (const_int 0)]))
10672    (set (match_operand:DI 1 "register_operand" "")
10673         (zero_extend:DI (not:SI (match_dup 3))))]
10674   "ix86_match_ccmode (insn, CCNOmode)"
10675   [(parallel [(set (match_dup 0)
10676                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10677                                     (const_int 0)]))
10678               (set (match_dup 1)
10679                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10680   "")
10681
10682 (define_expand "one_cmplhi2"
10683   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10684         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10685   "TARGET_HIMODE_MATH"
10686   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10687
10688 (define_insn "*one_cmplhi2_1"
10689   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10690         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10691   "ix86_unary_operator_ok (NOT, HImode, operands)"
10692   "not{w}\t%0"
10693   [(set_attr "type" "negnot")
10694    (set_attr "mode" "HI")])
10695
10696 (define_insn "*one_cmplhi2_2"
10697   [(set (reg FLAGS_REG)
10698         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10699                  (const_int 0)))
10700    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10701         (not:HI (match_dup 1)))]
10702   "ix86_match_ccmode (insn, CCNOmode)
10703    && ix86_unary_operator_ok (NEG, HImode, operands)"
10704   "#"
10705   [(set_attr "type" "alu1")
10706    (set_attr "mode" "HI")])
10707
10708 (define_split
10709   [(set (match_operand 0 "flags_reg_operand" "")
10710         (match_operator 2 "compare_operator"
10711           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10712            (const_int 0)]))
10713    (set (match_operand:HI 1 "nonimmediate_operand" "")
10714         (not:HI (match_dup 3)))]
10715   "ix86_match_ccmode (insn, CCNOmode)"
10716   [(parallel [(set (match_dup 0)
10717                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10718                                     (const_int 0)]))
10719               (set (match_dup 1)
10720                    (xor:HI (match_dup 3) (const_int -1)))])]
10721   "")
10722
10723 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10724 (define_expand "one_cmplqi2"
10725   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10726         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10727   "TARGET_QIMODE_MATH"
10728   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10729
10730 (define_insn "*one_cmplqi2_1"
10731   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10732         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10733   "ix86_unary_operator_ok (NOT, QImode, operands)"
10734   "@
10735    not{b}\t%0
10736    not{l}\t%k0"
10737   [(set_attr "type" "negnot")
10738    (set_attr "mode" "QI,SI")])
10739
10740 (define_insn "*one_cmplqi2_2"
10741   [(set (reg FLAGS_REG)
10742         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10743                  (const_int 0)))
10744    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10745         (not:QI (match_dup 1)))]
10746   "ix86_match_ccmode (insn, CCNOmode)
10747    && ix86_unary_operator_ok (NOT, QImode, operands)"
10748   "#"
10749   [(set_attr "type" "alu1")
10750    (set_attr "mode" "QI")])
10751
10752 (define_split
10753   [(set (match_operand 0 "flags_reg_operand" "")
10754         (match_operator 2 "compare_operator"
10755           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10756            (const_int 0)]))
10757    (set (match_operand:QI 1 "nonimmediate_operand" "")
10758         (not:QI (match_dup 3)))]
10759   "ix86_match_ccmode (insn, CCNOmode)"
10760   [(parallel [(set (match_dup 0)
10761                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10762                                     (const_int 0)]))
10763               (set (match_dup 1)
10764                    (xor:QI (match_dup 3) (const_int -1)))])]
10765   "")
10766 \f
10767 ;; Arithmetic shift instructions
10768
10769 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10770 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10771 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10772 ;; from the assembler input.
10773 ;;
10774 ;; This instruction shifts the target reg/mem as usual, but instead of
10775 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10776 ;; is a left shift double, bits are taken from the high order bits of
10777 ;; reg, else if the insn is a shift right double, bits are taken from the
10778 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10779 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10780 ;;
10781 ;; Since sh[lr]d does not change the `reg' operand, that is done
10782 ;; separately, making all shifts emit pairs of shift double and normal
10783 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10784 ;; support a 63 bit shift, each shift where the count is in a reg expands
10785 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10786 ;;
10787 ;; If the shift count is a constant, we need never emit more than one
10788 ;; shift pair, instead using moves and sign extension for counts greater
10789 ;; than 31.
10790
10791 (define_expand "ashlti3"
10792   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10793                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10794                               (match_operand:QI 2 "nonmemory_operand" "")))
10795               (clobber (reg:CC FLAGS_REG))])]
10796   "TARGET_64BIT"
10797 {
10798   if (! immediate_operand (operands[2], QImode))
10799     {
10800       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10801       DONE;
10802     }
10803   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10804   DONE;
10805 })
10806
10807 (define_insn "ashlti3_1"
10808   [(set (match_operand:TI 0 "register_operand" "=r")
10809         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10810                    (match_operand:QI 2 "register_operand" "c")))
10811    (clobber (match_scratch:DI 3 "=&r"))
10812    (clobber (reg:CC FLAGS_REG))]
10813   "TARGET_64BIT"
10814   "#"
10815   [(set_attr "type" "multi")])
10816
10817 ;; This pattern must be defined before *ashlti3_2 to prevent
10818 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10819
10820 (define_insn "sse2_ashlti3"
10821   [(set (match_operand:TI 0 "register_operand" "=x")
10822         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10823                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10824   "TARGET_SSE2"
10825 {
10826   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10827   return "pslldq\t{%2, %0|%0, %2}";
10828 }
10829   [(set_attr "type" "sseishft")
10830    (set_attr "prefix_data16" "1")
10831    (set_attr "mode" "TI")])
10832
10833 (define_insn "*ashlti3_2"
10834   [(set (match_operand:TI 0 "register_operand" "=r")
10835         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10836                    (match_operand:QI 2 "immediate_operand" "O")))
10837    (clobber (reg:CC FLAGS_REG))]
10838   "TARGET_64BIT"
10839   "#"
10840   [(set_attr "type" "multi")])
10841
10842 (define_split
10843   [(set (match_operand:TI 0 "register_operand" "")
10844         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10845                    (match_operand:QI 2 "register_operand" "")))
10846    (clobber (match_scratch:DI 3 ""))
10847    (clobber (reg:CC FLAGS_REG))]
10848   "TARGET_64BIT && reload_completed"
10849   [(const_int 0)]
10850   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10851
10852 (define_split
10853   [(set (match_operand:TI 0 "register_operand" "")
10854         (ashift:TI (match_operand:TI 1 "register_operand" "")
10855                    (match_operand:QI 2 "immediate_operand" "")))
10856    (clobber (reg:CC FLAGS_REG))]
10857   "TARGET_64BIT && reload_completed"
10858   [(const_int 0)]
10859   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10860
10861 (define_insn "x86_64_shld"
10862   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10863         (ior:DI (ashift:DI (match_dup 0)
10864                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10865                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10866                   (minus:QI (const_int 64) (match_dup 2)))))
10867    (clobber (reg:CC FLAGS_REG))]
10868   "TARGET_64BIT"
10869   "@
10870    shld{q}\t{%2, %1, %0|%0, %1, %2}
10871    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10872   [(set_attr "type" "ishift")
10873    (set_attr "prefix_0f" "1")
10874    (set_attr "mode" "DI")
10875    (set_attr "athlon_decode" "vector")
10876    (set_attr "amdfam10_decode" "vector")])
10877
10878 (define_expand "x86_64_shift_adj"
10879   [(set (reg:CCZ FLAGS_REG)
10880         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10881                              (const_int 64))
10882                      (const_int 0)))
10883    (set (match_operand:DI 0 "register_operand" "")
10884         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10885                          (match_operand:DI 1 "register_operand" "")
10886                          (match_dup 0)))
10887    (set (match_dup 1)
10888         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10889                          (match_operand:DI 3 "register_operand" "r")
10890                          (match_dup 1)))]
10891   "TARGET_64BIT"
10892   "")
10893
10894 (define_expand "ashldi3"
10895   [(set (match_operand:DI 0 "shiftdi_operand" "")
10896         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10897                    (match_operand:QI 2 "nonmemory_operand" "")))]
10898   ""
10899   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10900
10901 (define_insn "*ashldi3_1_rex64"
10902   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10903         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10904                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10905    (clobber (reg:CC FLAGS_REG))]
10906   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10907 {
10908   switch (get_attr_type (insn))
10909     {
10910     case TYPE_ALU:
10911       gcc_assert (operands[2] == const1_rtx);
10912       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10913       return "add{q}\t%0, %0";
10914
10915     case TYPE_LEA:
10916       gcc_assert (CONST_INT_P (operands[2]));
10917       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10918       operands[1] = gen_rtx_MULT (DImode, operands[1],
10919                                   GEN_INT (1 << INTVAL (operands[2])));
10920       return "lea{q}\t{%a1, %0|%0, %a1}";
10921
10922     default:
10923       if (REG_P (operands[2]))
10924         return "sal{q}\t{%b2, %0|%0, %b2}";
10925       else if (operands[2] == const1_rtx
10926                && (TARGET_SHIFT1 || optimize_size))
10927         return "sal{q}\t%0";
10928       else
10929         return "sal{q}\t{%2, %0|%0, %2}";
10930     }
10931 }
10932   [(set (attr "type")
10933      (cond [(eq_attr "alternative" "1")
10934               (const_string "lea")
10935             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10936                           (const_int 0))
10937                       (match_operand 0 "register_operand" ""))
10938                  (match_operand 2 "const1_operand" ""))
10939               (const_string "alu")
10940            ]
10941            (const_string "ishift")))
10942    (set_attr "mode" "DI")])
10943
10944 ;; Convert lea to the lea pattern to avoid flags dependency.
10945 (define_split
10946   [(set (match_operand:DI 0 "register_operand" "")
10947         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10948                    (match_operand:QI 2 "immediate_operand" "")))
10949    (clobber (reg:CC FLAGS_REG))]
10950   "TARGET_64BIT && reload_completed
10951    && true_regnum (operands[0]) != true_regnum (operands[1])"
10952   [(set (match_dup 0)
10953         (mult:DI (match_dup 1)
10954                  (match_dup 2)))]
10955   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10956
10957 ;; This pattern can't accept a variable shift count, since shifts by
10958 ;; zero don't affect the flags.  We assume that shifts by constant
10959 ;; zero are optimized away.
10960 (define_insn "*ashldi3_cmp_rex64"
10961   [(set (reg FLAGS_REG)
10962         (compare
10963           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10964                      (match_operand:QI 2 "immediate_operand" "e"))
10965           (const_int 0)))
10966    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10967         (ashift:DI (match_dup 1) (match_dup 2)))]
10968   "TARGET_64BIT
10969    && (optimize_size
10970        || !TARGET_PARTIAL_FLAG_REG_STALL
10971        || (operands[2] == const1_rtx
10972            && (TARGET_SHIFT1
10973                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10974    && ix86_match_ccmode (insn, CCGOCmode)
10975    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10976 {
10977   switch (get_attr_type (insn))
10978     {
10979     case TYPE_ALU:
10980       gcc_assert (operands[2] == const1_rtx);
10981       return "add{q}\t%0, %0";
10982
10983     default:
10984       if (REG_P (operands[2]))
10985         return "sal{q}\t{%b2, %0|%0, %b2}";
10986       else if (operands[2] == const1_rtx
10987                && (TARGET_SHIFT1 || optimize_size))
10988         return "sal{q}\t%0";
10989       else
10990         return "sal{q}\t{%2, %0|%0, %2}";
10991     }
10992 }
10993   [(set (attr "type")
10994      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10995                           (const_int 0))
10996                       (match_operand 0 "register_operand" ""))
10997                  (match_operand 2 "const1_operand" ""))
10998               (const_string "alu")
10999            ]
11000            (const_string "ishift")))
11001    (set_attr "mode" "DI")])
11002
11003 (define_insn "*ashldi3_cconly_rex64"
11004   [(set (reg FLAGS_REG)
11005         (compare
11006           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11007                      (match_operand:QI 2 "immediate_operand" "e"))
11008           (const_int 0)))
11009    (clobber (match_scratch:DI 0 "=r"))]
11010   "TARGET_64BIT
11011    && (optimize_size
11012        || !TARGET_PARTIAL_FLAG_REG_STALL
11013        || (operands[2] == const1_rtx
11014            && (TARGET_SHIFT1
11015                || TARGET_DOUBLE_WITH_ADD)))
11016    && ix86_match_ccmode (insn, CCGOCmode)
11017    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11018 {
11019   switch (get_attr_type (insn))
11020     {
11021     case TYPE_ALU:
11022       gcc_assert (operands[2] == const1_rtx);
11023       return "add{q}\t%0, %0";
11024
11025     default:
11026       if (REG_P (operands[2]))
11027         return "sal{q}\t{%b2, %0|%0, %b2}";
11028       else if (operands[2] == const1_rtx
11029                && (TARGET_SHIFT1 || optimize_size))
11030         return "sal{q}\t%0";
11031       else
11032         return "sal{q}\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" "DI")])
11044
11045 (define_insn "*ashldi3_1"
11046   [(set (match_operand:DI 0 "register_operand" "=&r,r")
11047         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11048                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11049    (clobber (reg:CC FLAGS_REG))]
11050   "!TARGET_64BIT"
11051   "#"
11052   [(set_attr "type" "multi")])
11053
11054 ;; By default we don't ask for a scratch register, because when DImode
11055 ;; values are manipulated, registers are already at a premium.  But if
11056 ;; we have one handy, we won't turn it away.
11057 (define_peephole2
11058   [(match_scratch:SI 3 "r")
11059    (parallel [(set (match_operand:DI 0 "register_operand" "")
11060                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11061                               (match_operand:QI 2 "nonmemory_operand" "")))
11062               (clobber (reg:CC FLAGS_REG))])
11063    (match_dup 3)]
11064   "!TARGET_64BIT && TARGET_CMOVE"
11065   [(const_int 0)]
11066   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11067
11068 (define_split
11069   [(set (match_operand:DI 0 "register_operand" "")
11070         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11071                    (match_operand:QI 2 "nonmemory_operand" "")))
11072    (clobber (reg:CC FLAGS_REG))]
11073   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11074                      ? epilogue_completed : reload_completed)"
11075   [(const_int 0)]
11076   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11077
11078 (define_insn "x86_shld_1"
11079   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11080         (ior:SI (ashift:SI (match_dup 0)
11081                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11082                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11083                   (minus:QI (const_int 32) (match_dup 2)))))
11084    (clobber (reg:CC FLAGS_REG))]
11085   ""
11086   "@
11087    shld{l}\t{%2, %1, %0|%0, %1, %2}
11088    shld{l}\t{%s2%1, %0|%0, %1, %2}"
11089   [(set_attr "type" "ishift")
11090    (set_attr "prefix_0f" "1")
11091    (set_attr "mode" "SI")
11092    (set_attr "pent_pair" "np")
11093    (set_attr "athlon_decode" "vector")
11094    (set_attr "amdfam10_decode" "vector")])
11095
11096 (define_expand "x86_shift_adj_1"
11097   [(set (reg:CCZ FLAGS_REG)
11098         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11099                              (const_int 32))
11100                      (const_int 0)))
11101    (set (match_operand:SI 0 "register_operand" "")
11102         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11103                          (match_operand:SI 1 "register_operand" "")
11104                          (match_dup 0)))
11105    (set (match_dup 1)
11106         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11107                          (match_operand:SI 3 "register_operand" "r")
11108                          (match_dup 1)))]
11109   "TARGET_CMOVE"
11110   "")
11111
11112 (define_expand "x86_shift_adj_2"
11113   [(use (match_operand:SI 0 "register_operand" ""))
11114    (use (match_operand:SI 1 "register_operand" ""))
11115    (use (match_operand:QI 2 "register_operand" ""))]
11116   ""
11117 {
11118   rtx label = gen_label_rtx ();
11119   rtx tmp;
11120
11121   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11122
11123   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11124   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11125   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11126                               gen_rtx_LABEL_REF (VOIDmode, label),
11127                               pc_rtx);
11128   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11129   JUMP_LABEL (tmp) = label;
11130
11131   emit_move_insn (operands[0], operands[1]);
11132   ix86_expand_clear (operands[1]);
11133
11134   emit_label (label);
11135   LABEL_NUSES (label) = 1;
11136
11137   DONE;
11138 })
11139
11140 (define_expand "ashlsi3"
11141   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11142         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11143                    (match_operand:QI 2 "nonmemory_operand" "")))
11144    (clobber (reg:CC FLAGS_REG))]
11145   ""
11146   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11147
11148 (define_insn "*ashlsi3_1"
11149   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11150         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11151                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11152    (clobber (reg:CC FLAGS_REG))]
11153   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11154 {
11155   switch (get_attr_type (insn))
11156     {
11157     case TYPE_ALU:
11158       gcc_assert (operands[2] == const1_rtx);
11159       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11160       return "add{l}\t%0, %0";
11161
11162     case TYPE_LEA:
11163       return "#";
11164
11165     default:
11166       if (REG_P (operands[2]))
11167         return "sal{l}\t{%b2, %0|%0, %b2}";
11168       else if (operands[2] == const1_rtx
11169                && (TARGET_SHIFT1 || optimize_size))
11170         return "sal{l}\t%0";
11171       else
11172         return "sal{l}\t{%2, %0|%0, %2}";
11173     }
11174 }
11175   [(set (attr "type")
11176      (cond [(eq_attr "alternative" "1")
11177               (const_string "lea")
11178             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11179                           (const_int 0))
11180                       (match_operand 0 "register_operand" ""))
11181                  (match_operand 2 "const1_operand" ""))
11182               (const_string "alu")
11183            ]
11184            (const_string "ishift")))
11185    (set_attr "mode" "SI")])
11186
11187 ;; Convert lea to the lea pattern to avoid flags dependency.
11188 (define_split
11189   [(set (match_operand 0 "register_operand" "")
11190         (ashift (match_operand 1 "index_register_operand" "")
11191                 (match_operand:QI 2 "const_int_operand" "")))
11192    (clobber (reg:CC FLAGS_REG))]
11193   "reload_completed
11194    && true_regnum (operands[0]) != true_regnum (operands[1])
11195    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11196   [(const_int 0)]
11197 {
11198   rtx pat;
11199   enum machine_mode mode = GET_MODE (operands[0]);
11200
11201   if (GET_MODE_SIZE (mode) < 4)
11202     operands[0] = gen_lowpart (SImode, operands[0]);
11203   if (mode != Pmode)
11204     operands[1] = gen_lowpart (Pmode, operands[1]);
11205   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11206
11207   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11208   if (Pmode != SImode)
11209     pat = gen_rtx_SUBREG (SImode, pat, 0);
11210   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11211   DONE;
11212 })
11213
11214 ;; Rare case of shifting RSP is handled by generating move and shift
11215 (define_split
11216   [(set (match_operand 0 "register_operand" "")
11217         (ashift (match_operand 1 "register_operand" "")
11218                 (match_operand:QI 2 "const_int_operand" "")))
11219    (clobber (reg:CC FLAGS_REG))]
11220   "reload_completed
11221    && true_regnum (operands[0]) != true_regnum (operands[1])"
11222   [(const_int 0)]
11223 {
11224   rtx pat, clob;
11225   emit_move_insn (operands[0], operands[1]);
11226   pat = gen_rtx_SET (VOIDmode, operands[0],
11227                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11228                                      operands[0], operands[2]));
11229   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11230   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11231   DONE;
11232 })
11233
11234 (define_insn "*ashlsi3_1_zext"
11235   [(set (match_operand:DI 0 "register_operand" "=r,r")
11236         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11237                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11238    (clobber (reg:CC FLAGS_REG))]
11239   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11240 {
11241   switch (get_attr_type (insn))
11242     {
11243     case TYPE_ALU:
11244       gcc_assert (operands[2] == const1_rtx);
11245       return "add{l}\t%k0, %k0";
11246
11247     case TYPE_LEA:
11248       return "#";
11249
11250     default:
11251       if (REG_P (operands[2]))
11252         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11253       else if (operands[2] == const1_rtx
11254                && (TARGET_SHIFT1 || optimize_size))
11255         return "sal{l}\t%k0";
11256       else
11257         return "sal{l}\t{%2, %k0|%k0, %2}";
11258     }
11259 }
11260   [(set (attr "type")
11261      (cond [(eq_attr "alternative" "1")
11262               (const_string "lea")
11263             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11264                      (const_int 0))
11265                  (match_operand 2 "const1_operand" ""))
11266               (const_string "alu")
11267            ]
11268            (const_string "ishift")))
11269    (set_attr "mode" "SI")])
11270
11271 ;; Convert lea to the lea pattern to avoid flags dependency.
11272 (define_split
11273   [(set (match_operand:DI 0 "register_operand" "")
11274         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11275                                 (match_operand:QI 2 "const_int_operand" ""))))
11276    (clobber (reg:CC FLAGS_REG))]
11277   "TARGET_64BIT && reload_completed
11278    && true_regnum (operands[0]) != true_regnum (operands[1])"
11279   [(set (match_dup 0) (zero_extend:DI
11280                         (subreg:SI (mult:SI (match_dup 1)
11281                                             (match_dup 2)) 0)))]
11282 {
11283   operands[1] = gen_lowpart (Pmode, operands[1]);
11284   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11285 })
11286
11287 ;; This pattern can't accept a variable shift count, since shifts by
11288 ;; zero don't affect the flags.  We assume that shifts by constant
11289 ;; zero are optimized away.
11290 (define_insn "*ashlsi3_cmp"
11291   [(set (reg FLAGS_REG)
11292         (compare
11293           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11294                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11295           (const_int 0)))
11296    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11297         (ashift:SI (match_dup 1) (match_dup 2)))]
11298    "(optimize_size
11299      || !TARGET_PARTIAL_FLAG_REG_STALL
11300      || (operands[2] == const1_rtx
11301          && (TARGET_SHIFT1
11302              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11303    && ix86_match_ccmode (insn, CCGOCmode)
11304    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11305 {
11306   switch (get_attr_type (insn))
11307     {
11308     case TYPE_ALU:
11309       gcc_assert (operands[2] == const1_rtx);
11310       return "add{l}\t%0, %0";
11311
11312     default:
11313       if (REG_P (operands[2]))
11314         return "sal{l}\t{%b2, %0|%0, %b2}";
11315       else if (operands[2] == const1_rtx
11316                && (TARGET_SHIFT1 || optimize_size))
11317         return "sal{l}\t%0";
11318       else
11319         return "sal{l}\t{%2, %0|%0, %2}";
11320     }
11321 }
11322   [(set (attr "type")
11323      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11324                           (const_int 0))
11325                       (match_operand 0 "register_operand" ""))
11326                  (match_operand 2 "const1_operand" ""))
11327               (const_string "alu")
11328            ]
11329            (const_string "ishift")))
11330    (set_attr "mode" "SI")])
11331
11332 (define_insn "*ashlsi3_cconly"
11333   [(set (reg FLAGS_REG)
11334         (compare
11335           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11336                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11337           (const_int 0)))
11338    (clobber (match_scratch:SI 0 "=r"))]
11339   "(optimize_size
11340     || !TARGET_PARTIAL_FLAG_REG_STALL
11341     || (operands[2] == const1_rtx
11342         && (TARGET_SHIFT1
11343             || TARGET_DOUBLE_WITH_ADD)))
11344    && ix86_match_ccmode (insn, CCGOCmode)
11345    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11346 {
11347   switch (get_attr_type (insn))
11348     {
11349     case TYPE_ALU:
11350       gcc_assert (operands[2] == const1_rtx);
11351       return "add{l}\t%0, %0";
11352
11353     default:
11354       if (REG_P (operands[2]))
11355         return "sal{l}\t{%b2, %0|%0, %b2}";
11356       else if (operands[2] == const1_rtx
11357                && (TARGET_SHIFT1 || optimize_size))
11358         return "sal{l}\t%0";
11359       else
11360         return "sal{l}\t{%2, %0|%0, %2}";
11361     }
11362 }
11363   [(set (attr "type")
11364      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11365                           (const_int 0))
11366                       (match_operand 0 "register_operand" ""))
11367                  (match_operand 2 "const1_operand" ""))
11368               (const_string "alu")
11369            ]
11370            (const_string "ishift")))
11371    (set_attr "mode" "SI")])
11372
11373 (define_insn "*ashlsi3_cmp_zext"
11374   [(set (reg FLAGS_REG)
11375         (compare
11376           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11377                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11378           (const_int 0)))
11379    (set (match_operand:DI 0 "register_operand" "=r")
11380         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11381   "TARGET_64BIT
11382    && (optimize_size
11383        || !TARGET_PARTIAL_FLAG_REG_STALL
11384        || (operands[2] == const1_rtx
11385            && (TARGET_SHIFT1
11386                || TARGET_DOUBLE_WITH_ADD)))
11387    && ix86_match_ccmode (insn, CCGOCmode)
11388    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11389 {
11390   switch (get_attr_type (insn))
11391     {
11392     case TYPE_ALU:
11393       gcc_assert (operands[2] == const1_rtx);
11394       return "add{l}\t%k0, %k0";
11395
11396     default:
11397       if (REG_P (operands[2]))
11398         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11399       else if (operands[2] == const1_rtx
11400                && (TARGET_SHIFT1 || optimize_size))
11401         return "sal{l}\t%k0";
11402       else
11403         return "sal{l}\t{%2, %k0|%k0, %2}";
11404     }
11405 }
11406   [(set (attr "type")
11407      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11408                      (const_int 0))
11409                  (match_operand 2 "const1_operand" ""))
11410               (const_string "alu")
11411            ]
11412            (const_string "ishift")))
11413    (set_attr "mode" "SI")])
11414
11415 (define_expand "ashlhi3"
11416   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11417         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11418                    (match_operand:QI 2 "nonmemory_operand" "")))
11419    (clobber (reg:CC FLAGS_REG))]
11420   "TARGET_HIMODE_MATH"
11421   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11422
11423 (define_insn "*ashlhi3_1_lea"
11424   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11425         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11426                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11427    (clobber (reg:CC FLAGS_REG))]
11428   "!TARGET_PARTIAL_REG_STALL
11429    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11430 {
11431   switch (get_attr_type (insn))
11432     {
11433     case TYPE_LEA:
11434       return "#";
11435     case TYPE_ALU:
11436       gcc_assert (operands[2] == const1_rtx);
11437       return "add{w}\t%0, %0";
11438
11439     default:
11440       if (REG_P (operands[2]))
11441         return "sal{w}\t{%b2, %0|%0, %b2}";
11442       else if (operands[2] == const1_rtx
11443                && (TARGET_SHIFT1 || optimize_size))
11444         return "sal{w}\t%0";
11445       else
11446         return "sal{w}\t{%2, %0|%0, %2}";
11447     }
11448 }
11449   [(set (attr "type")
11450      (cond [(eq_attr "alternative" "1")
11451               (const_string "lea")
11452             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11453                           (const_int 0))
11454                       (match_operand 0 "register_operand" ""))
11455                  (match_operand 2 "const1_operand" ""))
11456               (const_string "alu")
11457            ]
11458            (const_string "ishift")))
11459    (set_attr "mode" "HI,SI")])
11460
11461 (define_insn "*ashlhi3_1"
11462   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11463         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11464                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11465    (clobber (reg:CC FLAGS_REG))]
11466   "TARGET_PARTIAL_REG_STALL
11467    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11468 {
11469   switch (get_attr_type (insn))
11470     {
11471     case TYPE_ALU:
11472       gcc_assert (operands[2] == const1_rtx);
11473       return "add{w}\t%0, %0";
11474
11475     default:
11476       if (REG_P (operands[2]))
11477         return "sal{w}\t{%b2, %0|%0, %b2}";
11478       else if (operands[2] == const1_rtx
11479                && (TARGET_SHIFT1 || optimize_size))
11480         return "sal{w}\t%0";
11481       else
11482         return "sal{w}\t{%2, %0|%0, %2}";
11483     }
11484 }
11485   [(set (attr "type")
11486      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11487                           (const_int 0))
11488                       (match_operand 0 "register_operand" ""))
11489                  (match_operand 2 "const1_operand" ""))
11490               (const_string "alu")
11491            ]
11492            (const_string "ishift")))
11493    (set_attr "mode" "HI")])
11494
11495 ;; This pattern can't accept a variable shift count, since shifts by
11496 ;; zero don't affect the flags.  We assume that shifts by constant
11497 ;; zero are optimized away.
11498 (define_insn "*ashlhi3_cmp"
11499   [(set (reg FLAGS_REG)
11500         (compare
11501           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11502                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11503           (const_int 0)))
11504    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11505         (ashift:HI (match_dup 1) (match_dup 2)))]
11506   "(optimize_size
11507     || !TARGET_PARTIAL_FLAG_REG_STALL
11508     || (operands[2] == const1_rtx
11509         && (TARGET_SHIFT1
11510             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11511    && ix86_match_ccmode (insn, CCGOCmode)
11512    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11513 {
11514   switch (get_attr_type (insn))
11515     {
11516     case TYPE_ALU:
11517       gcc_assert (operands[2] == const1_rtx);
11518       return "add{w}\t%0, %0";
11519
11520     default:
11521       if (REG_P (operands[2]))
11522         return "sal{w}\t{%b2, %0|%0, %b2}";
11523       else if (operands[2] == const1_rtx
11524                && (TARGET_SHIFT1 || optimize_size))
11525         return "sal{w}\t%0";
11526       else
11527         return "sal{w}\t{%2, %0|%0, %2}";
11528     }
11529 }
11530   [(set (attr "type")
11531      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11532                           (const_int 0))
11533                       (match_operand 0 "register_operand" ""))
11534                  (match_operand 2 "const1_operand" ""))
11535               (const_string "alu")
11536            ]
11537            (const_string "ishift")))
11538    (set_attr "mode" "HI")])
11539
11540 (define_insn "*ashlhi3_cconly"
11541   [(set (reg FLAGS_REG)
11542         (compare
11543           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11544                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11545           (const_int 0)))
11546    (clobber (match_scratch:HI 0 "=r"))]
11547   "(optimize_size
11548     || !TARGET_PARTIAL_FLAG_REG_STALL
11549     || (operands[2] == const1_rtx
11550         && (TARGET_SHIFT1
11551             || TARGET_DOUBLE_WITH_ADD)))
11552    && ix86_match_ccmode (insn, CCGOCmode)
11553    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11554 {
11555   switch (get_attr_type (insn))
11556     {
11557     case TYPE_ALU:
11558       gcc_assert (operands[2] == const1_rtx);
11559       return "add{w}\t%0, %0";
11560
11561     default:
11562       if (REG_P (operands[2]))
11563         return "sal{w}\t{%b2, %0|%0, %b2}";
11564       else if (operands[2] == const1_rtx
11565                && (TARGET_SHIFT1 || optimize_size))
11566         return "sal{w}\t%0";
11567       else
11568         return "sal{w}\t{%2, %0|%0, %2}";
11569     }
11570 }
11571   [(set (attr "type")
11572      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11573                           (const_int 0))
11574                       (match_operand 0 "register_operand" ""))
11575                  (match_operand 2 "const1_operand" ""))
11576               (const_string "alu")
11577            ]
11578            (const_string "ishift")))
11579    (set_attr "mode" "HI")])
11580
11581 (define_expand "ashlqi3"
11582   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11583         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11584                    (match_operand:QI 2 "nonmemory_operand" "")))
11585    (clobber (reg:CC FLAGS_REG))]
11586   "TARGET_QIMODE_MATH"
11587   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11588
11589 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11590
11591 (define_insn "*ashlqi3_1_lea"
11592   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11593         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11594                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11595    (clobber (reg:CC FLAGS_REG))]
11596   "!TARGET_PARTIAL_REG_STALL
11597    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11598 {
11599   switch (get_attr_type (insn))
11600     {
11601     case TYPE_LEA:
11602       return "#";
11603     case TYPE_ALU:
11604       gcc_assert (operands[2] == const1_rtx);
11605       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11606         return "add{l}\t%k0, %k0";
11607       else
11608         return "add{b}\t%0, %0";
11609
11610     default:
11611       if (REG_P (operands[2]))
11612         {
11613           if (get_attr_mode (insn) == MODE_SI)
11614             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11615           else
11616             return "sal{b}\t{%b2, %0|%0, %b2}";
11617         }
11618       else if (operands[2] == const1_rtx
11619                && (TARGET_SHIFT1 || optimize_size))
11620         {
11621           if (get_attr_mode (insn) == MODE_SI)
11622             return "sal{l}\t%0";
11623           else
11624             return "sal{b}\t%0";
11625         }
11626       else
11627         {
11628           if (get_attr_mode (insn) == MODE_SI)
11629             return "sal{l}\t{%2, %k0|%k0, %2}";
11630           else
11631             return "sal{b}\t{%2, %0|%0, %2}";
11632         }
11633     }
11634 }
11635   [(set (attr "type")
11636      (cond [(eq_attr "alternative" "2")
11637               (const_string "lea")
11638             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11639                           (const_int 0))
11640                       (match_operand 0 "register_operand" ""))
11641                  (match_operand 2 "const1_operand" ""))
11642               (const_string "alu")
11643            ]
11644            (const_string "ishift")))
11645    (set_attr "mode" "QI,SI,SI")])
11646
11647 (define_insn "*ashlqi3_1"
11648   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11649         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11650                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11651    (clobber (reg:CC FLAGS_REG))]
11652   "TARGET_PARTIAL_REG_STALL
11653    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11654 {
11655   switch (get_attr_type (insn))
11656     {
11657     case TYPE_ALU:
11658       gcc_assert (operands[2] == const1_rtx);
11659       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11660         return "add{l}\t%k0, %k0";
11661       else
11662         return "add{b}\t%0, %0";
11663
11664     default:
11665       if (REG_P (operands[2]))
11666         {
11667           if (get_attr_mode (insn) == MODE_SI)
11668             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11669           else
11670             return "sal{b}\t{%b2, %0|%0, %b2}";
11671         }
11672       else if (operands[2] == const1_rtx
11673                && (TARGET_SHIFT1 || optimize_size))
11674         {
11675           if (get_attr_mode (insn) == MODE_SI)
11676             return "sal{l}\t%0";
11677           else
11678             return "sal{b}\t%0";
11679         }
11680       else
11681         {
11682           if (get_attr_mode (insn) == MODE_SI)
11683             return "sal{l}\t{%2, %k0|%k0, %2}";
11684           else
11685             return "sal{b}\t{%2, %0|%0, %2}";
11686         }
11687     }
11688 }
11689   [(set (attr "type")
11690      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11691                           (const_int 0))
11692                       (match_operand 0 "register_operand" ""))
11693                  (match_operand 2 "const1_operand" ""))
11694               (const_string "alu")
11695            ]
11696            (const_string "ishift")))
11697    (set_attr "mode" "QI,SI")])
11698
11699 ;; This pattern can't accept a variable shift count, since shifts by
11700 ;; zero don't affect the flags.  We assume that shifts by constant
11701 ;; zero are optimized away.
11702 (define_insn "*ashlqi3_cmp"
11703   [(set (reg FLAGS_REG)
11704         (compare
11705           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11706                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11707           (const_int 0)))
11708    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11709         (ashift:QI (match_dup 1) (match_dup 2)))]
11710   "(optimize_size
11711     || !TARGET_PARTIAL_FLAG_REG_STALL
11712     || (operands[2] == const1_rtx
11713         && (TARGET_SHIFT1
11714             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11715    && ix86_match_ccmode (insn, CCGOCmode)
11716    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11717 {
11718   switch (get_attr_type (insn))
11719     {
11720     case TYPE_ALU:
11721       gcc_assert (operands[2] == const1_rtx);
11722       return "add{b}\t%0, %0";
11723
11724     default:
11725       if (REG_P (operands[2]))
11726         return "sal{b}\t{%b2, %0|%0, %b2}";
11727       else if (operands[2] == const1_rtx
11728                && (TARGET_SHIFT1 || optimize_size))
11729         return "sal{b}\t%0";
11730       else
11731         return "sal{b}\t{%2, %0|%0, %2}";
11732     }
11733 }
11734   [(set (attr "type")
11735      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11736                           (const_int 0))
11737                       (match_operand 0 "register_operand" ""))
11738                  (match_operand 2 "const1_operand" ""))
11739               (const_string "alu")
11740            ]
11741            (const_string "ishift")))
11742    (set_attr "mode" "QI")])
11743
11744 (define_insn "*ashlqi3_cconly"
11745   [(set (reg FLAGS_REG)
11746         (compare
11747           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11748                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11749           (const_int 0)))
11750    (clobber (match_scratch:QI 0 "=q"))]
11751   "(optimize_size
11752     || !TARGET_PARTIAL_FLAG_REG_STALL
11753     || (operands[2] == const1_rtx
11754         && (TARGET_SHIFT1
11755             || TARGET_DOUBLE_WITH_ADD)))
11756    && ix86_match_ccmode (insn, CCGOCmode)
11757    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11758 {
11759   switch (get_attr_type (insn))
11760     {
11761     case TYPE_ALU:
11762       gcc_assert (operands[2] == const1_rtx);
11763       return "add{b}\t%0, %0";
11764
11765     default:
11766       if (REG_P (operands[2]))
11767         return "sal{b}\t{%b2, %0|%0, %b2}";
11768       else if (operands[2] == const1_rtx
11769                && (TARGET_SHIFT1 || optimize_size))
11770         return "sal{b}\t%0";
11771       else
11772         return "sal{b}\t{%2, %0|%0, %2}";
11773     }
11774 }
11775   [(set (attr "type")
11776      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11777                           (const_int 0))
11778                       (match_operand 0 "register_operand" ""))
11779                  (match_operand 2 "const1_operand" ""))
11780               (const_string "alu")
11781            ]
11782            (const_string "ishift")))
11783    (set_attr "mode" "QI")])
11784
11785 ;; See comment above `ashldi3' about how this works.
11786
11787 (define_expand "ashrti3"
11788   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11789                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11790                                 (match_operand:QI 2 "nonmemory_operand" "")))
11791               (clobber (reg:CC FLAGS_REG))])]
11792   "TARGET_64BIT"
11793 {
11794   if (! immediate_operand (operands[2], QImode))
11795     {
11796       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11797       DONE;
11798     }
11799   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11800   DONE;
11801 })
11802
11803 (define_insn "ashrti3_1"
11804   [(set (match_operand:TI 0 "register_operand" "=r")
11805         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11806                      (match_operand:QI 2 "register_operand" "c")))
11807    (clobber (match_scratch:DI 3 "=&r"))
11808    (clobber (reg:CC FLAGS_REG))]
11809   "TARGET_64BIT"
11810   "#"
11811   [(set_attr "type" "multi")])
11812
11813 (define_insn "*ashrti3_2"
11814   [(set (match_operand:TI 0 "register_operand" "=r")
11815         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11816                      (match_operand:QI 2 "immediate_operand" "O")))
11817    (clobber (reg:CC FLAGS_REG))]
11818   "TARGET_64BIT"
11819   "#"
11820   [(set_attr "type" "multi")])
11821
11822 (define_split
11823   [(set (match_operand:TI 0 "register_operand" "")
11824         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11825                      (match_operand:QI 2 "register_operand" "")))
11826    (clobber (match_scratch:DI 3 ""))
11827    (clobber (reg:CC FLAGS_REG))]
11828   "TARGET_64BIT && reload_completed"
11829   [(const_int 0)]
11830   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11831
11832 (define_split
11833   [(set (match_operand:TI 0 "register_operand" "")
11834         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11835                      (match_operand:QI 2 "immediate_operand" "")))
11836    (clobber (reg:CC FLAGS_REG))]
11837   "TARGET_64BIT && reload_completed"
11838   [(const_int 0)]
11839   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11840
11841 (define_insn "x86_64_shrd"
11842   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11843         (ior:DI (ashiftrt:DI (match_dup 0)
11844                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11845                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11846                   (minus:QI (const_int 64) (match_dup 2)))))
11847    (clobber (reg:CC FLAGS_REG))]
11848   "TARGET_64BIT"
11849   "@
11850    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11851    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11852   [(set_attr "type" "ishift")
11853    (set_attr "prefix_0f" "1")
11854    (set_attr "mode" "DI")
11855    (set_attr "athlon_decode" "vector")
11856    (set_attr "amdfam10_decode" "vector")])
11857
11858 (define_expand "ashrdi3"
11859   [(set (match_operand:DI 0 "shiftdi_operand" "")
11860         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11861                      (match_operand:QI 2 "nonmemory_operand" "")))]
11862   ""
11863   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11864
11865 (define_insn "*ashrdi3_63_rex64"
11866   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11867         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11868                      (match_operand:DI 2 "const_int_operand" "i,i")))
11869    (clobber (reg:CC FLAGS_REG))]
11870   "TARGET_64BIT && INTVAL (operands[2]) == 63
11871    && (TARGET_USE_CLTD || optimize_size)
11872    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11873   "@
11874    {cqto|cqo}
11875    sar{q}\t{%2, %0|%0, %2}"
11876   [(set_attr "type" "imovx,ishift")
11877    (set_attr "prefix_0f" "0,*")
11878    (set_attr "length_immediate" "0,*")
11879    (set_attr "modrm" "0,1")
11880    (set_attr "mode" "DI")])
11881
11882 (define_insn "*ashrdi3_1_one_bit_rex64"
11883   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11884         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11885                      (match_operand:QI 2 "const1_operand" "")))
11886    (clobber (reg:CC FLAGS_REG))]
11887   "TARGET_64BIT
11888    && (TARGET_SHIFT1 || optimize_size)
11889    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11890   "sar{q}\t%0"
11891   [(set_attr "type" "ishift")
11892    (set (attr "length")
11893      (if_then_else (match_operand:DI 0 "register_operand" "")
11894         (const_string "2")
11895         (const_string "*")))])
11896
11897 (define_insn "*ashrdi3_1_rex64"
11898   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11899         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11900                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11901    (clobber (reg:CC FLAGS_REG))]
11902   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11903   "@
11904    sar{q}\t{%2, %0|%0, %2}
11905    sar{q}\t{%b2, %0|%0, %b2}"
11906   [(set_attr "type" "ishift")
11907    (set_attr "mode" "DI")])
11908
11909 ;; This pattern can't accept a variable shift count, since shifts by
11910 ;; zero don't affect the flags.  We assume that shifts by constant
11911 ;; zero are optimized away.
11912 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11913   [(set (reg FLAGS_REG)
11914         (compare
11915           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11916                        (match_operand:QI 2 "const1_operand" ""))
11917           (const_int 0)))
11918    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11919         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11920   "TARGET_64BIT
11921    && (TARGET_SHIFT1 || optimize_size)
11922    && ix86_match_ccmode (insn, CCGOCmode)
11923    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11924   "sar{q}\t%0"
11925   [(set_attr "type" "ishift")
11926    (set (attr "length")
11927      (if_then_else (match_operand:DI 0 "register_operand" "")
11928         (const_string "2")
11929         (const_string "*")))])
11930
11931 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11932   [(set (reg FLAGS_REG)
11933         (compare
11934           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11935                        (match_operand:QI 2 "const1_operand" ""))
11936           (const_int 0)))
11937    (clobber (match_scratch:DI 0 "=r"))]
11938   "TARGET_64BIT
11939    && (TARGET_SHIFT1 || optimize_size)
11940    && ix86_match_ccmode (insn, CCGOCmode)
11941    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11942   "sar{q}\t%0"
11943   [(set_attr "type" "ishift")
11944    (set_attr "length" "2")])
11945
11946 ;; This pattern can't accept a variable shift count, since shifts by
11947 ;; zero don't affect the flags.  We assume that shifts by constant
11948 ;; zero are optimized away.
11949 (define_insn "*ashrdi3_cmp_rex64"
11950   [(set (reg FLAGS_REG)
11951         (compare
11952           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11953                        (match_operand:QI 2 "const_int_operand" "n"))
11954           (const_int 0)))
11955    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11956         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11957   "TARGET_64BIT
11958    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11959    && ix86_match_ccmode (insn, CCGOCmode)
11960    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11961   "sar{q}\t{%2, %0|%0, %2}"
11962   [(set_attr "type" "ishift")
11963    (set_attr "mode" "DI")])
11964
11965 (define_insn "*ashrdi3_cconly_rex64"
11966   [(set (reg FLAGS_REG)
11967         (compare
11968           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11969                        (match_operand:QI 2 "const_int_operand" "n"))
11970           (const_int 0)))
11971    (clobber (match_scratch:DI 0 "=r"))]
11972   "TARGET_64BIT
11973    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11974    && ix86_match_ccmode (insn, CCGOCmode)
11975    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11976   "sar{q}\t{%2, %0|%0, %2}"
11977   [(set_attr "type" "ishift")
11978    (set_attr "mode" "DI")])
11979
11980 (define_insn "*ashrdi3_1"
11981   [(set (match_operand:DI 0 "register_operand" "=r")
11982         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11983                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11984    (clobber (reg:CC FLAGS_REG))]
11985   "!TARGET_64BIT"
11986   "#"
11987   [(set_attr "type" "multi")])
11988
11989 ;; By default we don't ask for a scratch register, because when DImode
11990 ;; values are manipulated, registers are already at a premium.  But if
11991 ;; we have one handy, we won't turn it away.
11992 (define_peephole2
11993   [(match_scratch:SI 3 "r")
11994    (parallel [(set (match_operand:DI 0 "register_operand" "")
11995                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11996                                 (match_operand:QI 2 "nonmemory_operand" "")))
11997               (clobber (reg:CC FLAGS_REG))])
11998    (match_dup 3)]
11999   "!TARGET_64BIT && TARGET_CMOVE"
12000   [(const_int 0)]
12001   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12002
12003 (define_split
12004   [(set (match_operand:DI 0 "register_operand" "")
12005         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12006                      (match_operand:QI 2 "nonmemory_operand" "")))
12007    (clobber (reg:CC FLAGS_REG))]
12008   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12009                      ? epilogue_completed : reload_completed)"
12010   [(const_int 0)]
12011   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12012
12013 (define_insn "x86_shrd_1"
12014   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
12015         (ior:SI (ashiftrt:SI (match_dup 0)
12016                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
12017                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
12018                   (minus:QI (const_int 32) (match_dup 2)))))
12019    (clobber (reg:CC FLAGS_REG))]
12020   ""
12021   "@
12022    shrd{l}\t{%2, %1, %0|%0, %1, %2}
12023    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12024   [(set_attr "type" "ishift")
12025    (set_attr "prefix_0f" "1")
12026    (set_attr "pent_pair" "np")
12027    (set_attr "mode" "SI")])
12028
12029 (define_expand "x86_shift_adj_3"
12030   [(use (match_operand:SI 0 "register_operand" ""))
12031    (use (match_operand:SI 1 "register_operand" ""))
12032    (use (match_operand:QI 2 "register_operand" ""))]
12033   ""
12034 {
12035   rtx label = gen_label_rtx ();
12036   rtx tmp;
12037
12038   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12039
12040   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12041   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12042   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12043                               gen_rtx_LABEL_REF (VOIDmode, label),
12044                               pc_rtx);
12045   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12046   JUMP_LABEL (tmp) = label;
12047
12048   emit_move_insn (operands[0], operands[1]);
12049   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12050
12051   emit_label (label);
12052   LABEL_NUSES (label) = 1;
12053
12054   DONE;
12055 })
12056
12057 (define_insn "ashrsi3_31"
12058   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12059         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12060                      (match_operand:SI 2 "const_int_operand" "i,i")))
12061    (clobber (reg:CC FLAGS_REG))]
12062   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12063    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12064   "@
12065    {cltd|cdq}
12066    sar{l}\t{%2, %0|%0, %2}"
12067   [(set_attr "type" "imovx,ishift")
12068    (set_attr "prefix_0f" "0,*")
12069    (set_attr "length_immediate" "0,*")
12070    (set_attr "modrm" "0,1")
12071    (set_attr "mode" "SI")])
12072
12073 (define_insn "*ashrsi3_31_zext"
12074   [(set (match_operand:DI 0 "register_operand" "=*d,r")
12075         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12076                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
12077    (clobber (reg:CC FLAGS_REG))]
12078   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12079    && INTVAL (operands[2]) == 31
12080    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12081   "@
12082    {cltd|cdq}
12083    sar{l}\t{%2, %k0|%k0, %2}"
12084   [(set_attr "type" "imovx,ishift")
12085    (set_attr "prefix_0f" "0,*")
12086    (set_attr "length_immediate" "0,*")
12087    (set_attr "modrm" "0,1")
12088    (set_attr "mode" "SI")])
12089
12090 (define_expand "ashrsi3"
12091   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12092         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12093                      (match_operand:QI 2 "nonmemory_operand" "")))
12094    (clobber (reg:CC FLAGS_REG))]
12095   ""
12096   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12097
12098 (define_insn "*ashrsi3_1_one_bit"
12099   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12100         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12101                      (match_operand:QI 2 "const1_operand" "")))
12102    (clobber (reg:CC FLAGS_REG))]
12103   "(TARGET_SHIFT1 || optimize_size)
12104    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12105   "sar{l}\t%0"
12106   [(set_attr "type" "ishift")
12107    (set (attr "length")
12108      (if_then_else (match_operand:SI 0 "register_operand" "")
12109         (const_string "2")
12110         (const_string "*")))])
12111
12112 (define_insn "*ashrsi3_1_one_bit_zext"
12113   [(set (match_operand:DI 0 "register_operand" "=r")
12114         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12115                                      (match_operand:QI 2 "const1_operand" ""))))
12116    (clobber (reg:CC FLAGS_REG))]
12117   "TARGET_64BIT
12118    && (TARGET_SHIFT1 || optimize_size)
12119    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12120   "sar{l}\t%k0"
12121   [(set_attr "type" "ishift")
12122    (set_attr "length" "2")])
12123
12124 (define_insn "*ashrsi3_1"
12125   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12126         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12127                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12128    (clobber (reg:CC FLAGS_REG))]
12129   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12130   "@
12131    sar{l}\t{%2, %0|%0, %2}
12132    sar{l}\t{%b2, %0|%0, %b2}"
12133   [(set_attr "type" "ishift")
12134    (set_attr "mode" "SI")])
12135
12136 (define_insn "*ashrsi3_1_zext"
12137   [(set (match_operand:DI 0 "register_operand" "=r,r")
12138         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12139                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12140    (clobber (reg:CC FLAGS_REG))]
12141   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12142   "@
12143    sar{l}\t{%2, %k0|%k0, %2}
12144    sar{l}\t{%b2, %k0|%k0, %b2}"
12145   [(set_attr "type" "ishift")
12146    (set_attr "mode" "SI")])
12147
12148 ;; This pattern can't accept a variable shift count, since shifts by
12149 ;; zero don't affect the flags.  We assume that shifts by constant
12150 ;; zero are optimized away.
12151 (define_insn "*ashrsi3_one_bit_cmp"
12152   [(set (reg FLAGS_REG)
12153         (compare
12154           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12155                        (match_operand:QI 2 "const1_operand" ""))
12156           (const_int 0)))
12157    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12158         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12159   "(TARGET_SHIFT1 || optimize_size)
12160    && ix86_match_ccmode (insn, CCGOCmode)
12161    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12162   "sar{l}\t%0"
12163   [(set_attr "type" "ishift")
12164    (set (attr "length")
12165      (if_then_else (match_operand:SI 0 "register_operand" "")
12166         (const_string "2")
12167         (const_string "*")))])
12168
12169 (define_insn "*ashrsi3_one_bit_cconly"
12170   [(set (reg FLAGS_REG)
12171         (compare
12172           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12173                        (match_operand:QI 2 "const1_operand" ""))
12174           (const_int 0)))
12175    (clobber (match_scratch:SI 0 "=r"))]
12176   "(TARGET_SHIFT1 || optimize_size)
12177    && ix86_match_ccmode (insn, CCGOCmode)
12178    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12179   "sar{l}\t%0"
12180   [(set_attr "type" "ishift")
12181    (set_attr "length" "2")])
12182
12183 (define_insn "*ashrsi3_one_bit_cmp_zext"
12184   [(set (reg FLAGS_REG)
12185         (compare
12186           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12187                        (match_operand:QI 2 "const1_operand" ""))
12188           (const_int 0)))
12189    (set (match_operand:DI 0 "register_operand" "=r")
12190         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12191   "TARGET_64BIT
12192    && (TARGET_SHIFT1 || optimize_size)
12193    && ix86_match_ccmode (insn, CCmode)
12194    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12195   "sar{l}\t%k0"
12196   [(set_attr "type" "ishift")
12197    (set_attr "length" "2")])
12198
12199 ;; This pattern can't accept a variable shift count, since shifts by
12200 ;; zero don't affect the flags.  We assume that shifts by constant
12201 ;; zero are optimized away.
12202 (define_insn "*ashrsi3_cmp"
12203   [(set (reg FLAGS_REG)
12204         (compare
12205           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12206                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12207           (const_int 0)))
12208    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12209         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12210   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12211    && ix86_match_ccmode (insn, CCGOCmode)
12212    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12213   "sar{l}\t{%2, %0|%0, %2}"
12214   [(set_attr "type" "ishift")
12215    (set_attr "mode" "SI")])
12216
12217 (define_insn "*ashrsi3_cconly"
12218   [(set (reg FLAGS_REG)
12219         (compare
12220           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12221                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12222           (const_int 0)))
12223    (clobber (match_scratch:SI 0 "=r"))]
12224   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12225    && ix86_match_ccmode (insn, CCGOCmode)
12226    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12227   "sar{l}\t{%2, %0|%0, %2}"
12228   [(set_attr "type" "ishift")
12229    (set_attr "mode" "SI")])
12230
12231 (define_insn "*ashrsi3_cmp_zext"
12232   [(set (reg FLAGS_REG)
12233         (compare
12234           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12235                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12236           (const_int 0)))
12237    (set (match_operand:DI 0 "register_operand" "=r")
12238         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12239   "TARGET_64BIT
12240    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12241    && ix86_match_ccmode (insn, CCGOCmode)
12242    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12243   "sar{l}\t{%2, %k0|%k0, %2}"
12244   [(set_attr "type" "ishift")
12245    (set_attr "mode" "SI")])
12246
12247 (define_expand "ashrhi3"
12248   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12249         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12250                      (match_operand:QI 2 "nonmemory_operand" "")))
12251    (clobber (reg:CC FLAGS_REG))]
12252   "TARGET_HIMODE_MATH"
12253   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12254
12255 (define_insn "*ashrhi3_1_one_bit"
12256   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12257         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12258                      (match_operand:QI 2 "const1_operand" "")))
12259    (clobber (reg:CC FLAGS_REG))]
12260   "(TARGET_SHIFT1 || optimize_size)
12261    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12262   "sar{w}\t%0"
12263   [(set_attr "type" "ishift")
12264    (set (attr "length")
12265      (if_then_else (match_operand 0 "register_operand" "")
12266         (const_string "2")
12267         (const_string "*")))])
12268
12269 (define_insn "*ashrhi3_1"
12270   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12271         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12272                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12273    (clobber (reg:CC FLAGS_REG))]
12274   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12275   "@
12276    sar{w}\t{%2, %0|%0, %2}
12277    sar{w}\t{%b2, %0|%0, %b2}"
12278   [(set_attr "type" "ishift")
12279    (set_attr "mode" "HI")])
12280
12281 ;; This pattern can't accept a variable shift count, since shifts by
12282 ;; zero don't affect the flags.  We assume that shifts by constant
12283 ;; zero are optimized away.
12284 (define_insn "*ashrhi3_one_bit_cmp"
12285   [(set (reg FLAGS_REG)
12286         (compare
12287           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12288                        (match_operand:QI 2 "const1_operand" ""))
12289           (const_int 0)))
12290    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12291         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12292   "(TARGET_SHIFT1 || optimize_size)
12293    && ix86_match_ccmode (insn, CCGOCmode)
12294    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12295   "sar{w}\t%0"
12296   [(set_attr "type" "ishift")
12297    (set (attr "length")
12298      (if_then_else (match_operand 0 "register_operand" "")
12299         (const_string "2")
12300         (const_string "*")))])
12301
12302 (define_insn "*ashrhi3_one_bit_cconly"
12303   [(set (reg FLAGS_REG)
12304         (compare
12305           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12306                        (match_operand:QI 2 "const1_operand" ""))
12307           (const_int 0)))
12308    (clobber (match_scratch:HI 0 "=r"))]
12309   "(TARGET_SHIFT1 || optimize_size)
12310    && ix86_match_ccmode (insn, CCGOCmode)
12311    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12312   "sar{w}\t%0"
12313   [(set_attr "type" "ishift")
12314    (set_attr "length" "2")])
12315
12316 ;; This pattern can't accept a variable shift count, since shifts by
12317 ;; zero don't affect the flags.  We assume that shifts by constant
12318 ;; zero are optimized away.
12319 (define_insn "*ashrhi3_cmp"
12320   [(set (reg FLAGS_REG)
12321         (compare
12322           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12323                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12324           (const_int 0)))
12325    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12326         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12327   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12328    && ix86_match_ccmode (insn, CCGOCmode)
12329    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12330   "sar{w}\t{%2, %0|%0, %2}"
12331   [(set_attr "type" "ishift")
12332    (set_attr "mode" "HI")])
12333
12334 (define_insn "*ashrhi3_cconly"
12335   [(set (reg FLAGS_REG)
12336         (compare
12337           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12338                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12339           (const_int 0)))
12340    (clobber (match_scratch:HI 0 "=r"))]
12341   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12342    && ix86_match_ccmode (insn, CCGOCmode)
12343    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12344   "sar{w}\t{%2, %0|%0, %2}"
12345   [(set_attr "type" "ishift")
12346    (set_attr "mode" "HI")])
12347
12348 (define_expand "ashrqi3"
12349   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12350         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12351                      (match_operand:QI 2 "nonmemory_operand" "")))
12352    (clobber (reg:CC FLAGS_REG))]
12353   "TARGET_QIMODE_MATH"
12354   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12355
12356 (define_insn "*ashrqi3_1_one_bit"
12357   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12358         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12359                      (match_operand:QI 2 "const1_operand" "")))
12360    (clobber (reg:CC FLAGS_REG))]
12361   "(TARGET_SHIFT1 || optimize_size)
12362    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12363   "sar{b}\t%0"
12364   [(set_attr "type" "ishift")
12365    (set (attr "length")
12366      (if_then_else (match_operand 0 "register_operand" "")
12367         (const_string "2")
12368         (const_string "*")))])
12369
12370 (define_insn "*ashrqi3_1_one_bit_slp"
12371   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12372         (ashiftrt:QI (match_dup 0)
12373                      (match_operand:QI 1 "const1_operand" "")))
12374    (clobber (reg:CC FLAGS_REG))]
12375   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12376    && (TARGET_SHIFT1 || optimize_size)
12377    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12378   "sar{b}\t%0"
12379   [(set_attr "type" "ishift1")
12380    (set (attr "length")
12381      (if_then_else (match_operand 0 "register_operand" "")
12382         (const_string "2")
12383         (const_string "*")))])
12384
12385 (define_insn "*ashrqi3_1"
12386   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12387         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12388                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12389    (clobber (reg:CC FLAGS_REG))]
12390   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12391   "@
12392    sar{b}\t{%2, %0|%0, %2}
12393    sar{b}\t{%b2, %0|%0, %b2}"
12394   [(set_attr "type" "ishift")
12395    (set_attr "mode" "QI")])
12396
12397 (define_insn "*ashrqi3_1_slp"
12398   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12399         (ashiftrt:QI (match_dup 0)
12400                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12401    (clobber (reg:CC FLAGS_REG))]
12402   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12403    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12404   "@
12405    sar{b}\t{%1, %0|%0, %1}
12406    sar{b}\t{%b1, %0|%0, %b1}"
12407   [(set_attr "type" "ishift1")
12408    (set_attr "mode" "QI")])
12409
12410 ;; This pattern can't accept a variable shift count, since shifts by
12411 ;; zero don't affect the flags.  We assume that shifts by constant
12412 ;; zero are optimized away.
12413 (define_insn "*ashrqi3_one_bit_cmp"
12414   [(set (reg FLAGS_REG)
12415         (compare
12416           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12417                        (match_operand:QI 2 "const1_operand" "I"))
12418           (const_int 0)))
12419    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12420         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12421   "(TARGET_SHIFT1 || optimize_size)
12422    && ix86_match_ccmode (insn, CCGOCmode)
12423    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12424   "sar{b}\t%0"
12425   [(set_attr "type" "ishift")
12426    (set (attr "length")
12427      (if_then_else (match_operand 0 "register_operand" "")
12428         (const_string "2")
12429         (const_string "*")))])
12430
12431 (define_insn "*ashrqi3_one_bit_cconly"
12432   [(set (reg FLAGS_REG)
12433         (compare
12434           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12435                        (match_operand:QI 2 "const1_operand" "I"))
12436           (const_int 0)))
12437    (clobber (match_scratch:QI 0 "=q"))]
12438   "(TARGET_SHIFT1 || optimize_size)
12439    && ix86_match_ccmode (insn, CCGOCmode)
12440    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12441   "sar{b}\t%0"
12442   [(set_attr "type" "ishift")
12443    (set_attr "length" "2")])
12444
12445 ;; This pattern can't accept a variable shift count, since shifts by
12446 ;; zero don't affect the flags.  We assume that shifts by constant
12447 ;; zero are optimized away.
12448 (define_insn "*ashrqi3_cmp"
12449   [(set (reg FLAGS_REG)
12450         (compare
12451           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12452                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12453           (const_int 0)))
12454    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12455         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12456   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12457    && ix86_match_ccmode (insn, CCGOCmode)
12458    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12459   "sar{b}\t{%2, %0|%0, %2}"
12460   [(set_attr "type" "ishift")
12461    (set_attr "mode" "QI")])
12462
12463 (define_insn "*ashrqi3_cconly"
12464   [(set (reg FLAGS_REG)
12465         (compare
12466           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12467                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12468           (const_int 0)))
12469    (clobber (match_scratch:QI 0 "=q"))]
12470   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12471    && ix86_match_ccmode (insn, CCGOCmode)
12472    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12473   "sar{b}\t{%2, %0|%0, %2}"
12474   [(set_attr "type" "ishift")
12475    (set_attr "mode" "QI")])
12476
12477 \f
12478 ;; Logical shift instructions
12479
12480 ;; See comment above `ashldi3' about how this works.
12481
12482 (define_expand "lshrti3"
12483   [(parallel [(set (match_operand:TI 0 "register_operand" "")
12484                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12485                                 (match_operand:QI 2 "nonmemory_operand" "")))
12486               (clobber (reg:CC FLAGS_REG))])]
12487   "TARGET_64BIT"
12488 {
12489   if (! immediate_operand (operands[2], QImode))
12490     {
12491       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12492       DONE;
12493     }
12494   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12495   DONE;
12496 })
12497
12498 (define_insn "lshrti3_1"
12499   [(set (match_operand:TI 0 "register_operand" "=r")
12500         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12501                      (match_operand:QI 2 "register_operand" "c")))
12502    (clobber (match_scratch:DI 3 "=&r"))
12503    (clobber (reg:CC FLAGS_REG))]
12504   "TARGET_64BIT"
12505   "#"
12506   [(set_attr "type" "multi")])
12507
12508 ;; This pattern must be defined before *lshrti3_2 to prevent
12509 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12510
12511 (define_insn "sse2_lshrti3"
12512   [(set (match_operand:TI 0 "register_operand" "=x")
12513         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12514                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12515   "TARGET_SSE2"
12516 {
12517   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12518   return "psrldq\t{%2, %0|%0, %2}";
12519 }
12520   [(set_attr "type" "sseishft")
12521    (set_attr "prefix_data16" "1")
12522    (set_attr "mode" "TI")])
12523
12524 (define_insn "*lshrti3_2"
12525   [(set (match_operand:TI 0 "register_operand" "=r")
12526         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12527                      (match_operand:QI 2 "immediate_operand" "O")))
12528    (clobber (reg:CC FLAGS_REG))]
12529   "TARGET_64BIT"
12530   "#"
12531   [(set_attr "type" "multi")])
12532
12533 (define_split
12534   [(set (match_operand:TI 0 "register_operand" "")
12535         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12536                      (match_operand:QI 2 "register_operand" "")))
12537    (clobber (match_scratch:DI 3 ""))
12538    (clobber (reg:CC FLAGS_REG))]
12539   "TARGET_64BIT && reload_completed"
12540   [(const_int 0)]
12541   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12542
12543 (define_split
12544   [(set (match_operand:TI 0 "register_operand" "")
12545         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12546                      (match_operand:QI 2 "immediate_operand" "")))
12547    (clobber (reg:CC FLAGS_REG))]
12548   "TARGET_64BIT && reload_completed"
12549   [(const_int 0)]
12550   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12551
12552 (define_expand "lshrdi3"
12553   [(set (match_operand:DI 0 "shiftdi_operand" "")
12554         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12555                      (match_operand:QI 2 "nonmemory_operand" "")))]
12556   ""
12557   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12558
12559 (define_insn "*lshrdi3_1_one_bit_rex64"
12560   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12561         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12562                      (match_operand:QI 2 "const1_operand" "")))
12563    (clobber (reg:CC FLAGS_REG))]
12564   "TARGET_64BIT
12565    && (TARGET_SHIFT1 || optimize_size)
12566    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12567   "shr{q}\t%0"
12568   [(set_attr "type" "ishift")
12569    (set (attr "length")
12570      (if_then_else (match_operand:DI 0 "register_operand" "")
12571         (const_string "2")
12572         (const_string "*")))])
12573
12574 (define_insn "*lshrdi3_1_rex64"
12575   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12576         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12577                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12578    (clobber (reg:CC FLAGS_REG))]
12579   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12580   "@
12581    shr{q}\t{%2, %0|%0, %2}
12582    shr{q}\t{%b2, %0|%0, %b2}"
12583   [(set_attr "type" "ishift")
12584    (set_attr "mode" "DI")])
12585
12586 ;; This pattern can't accept a variable shift count, since shifts by
12587 ;; zero don't affect the flags.  We assume that shifts by constant
12588 ;; zero are optimized away.
12589 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12590   [(set (reg FLAGS_REG)
12591         (compare
12592           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12593                        (match_operand:QI 2 "const1_operand" ""))
12594           (const_int 0)))
12595    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12596         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12597   "TARGET_64BIT
12598    && (TARGET_SHIFT1 || optimize_size)
12599    && ix86_match_ccmode (insn, CCGOCmode)
12600    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12601   "shr{q}\t%0"
12602   [(set_attr "type" "ishift")
12603    (set (attr "length")
12604      (if_then_else (match_operand:DI 0 "register_operand" "")
12605         (const_string "2")
12606         (const_string "*")))])
12607
12608 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12609   [(set (reg FLAGS_REG)
12610         (compare
12611           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12612                        (match_operand:QI 2 "const1_operand" ""))
12613           (const_int 0)))
12614    (clobber (match_scratch:DI 0 "=r"))]
12615   "TARGET_64BIT
12616    && (TARGET_SHIFT1 || optimize_size)
12617    && ix86_match_ccmode (insn, CCGOCmode)
12618    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12619   "shr{q}\t%0"
12620   [(set_attr "type" "ishift")
12621    (set_attr "length" "2")])
12622
12623 ;; This pattern can't accept a variable shift count, since shifts by
12624 ;; zero don't affect the flags.  We assume that shifts by constant
12625 ;; zero are optimized away.
12626 (define_insn "*lshrdi3_cmp_rex64"
12627   [(set (reg FLAGS_REG)
12628         (compare
12629           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12630                        (match_operand:QI 2 "const_int_operand" "e"))
12631           (const_int 0)))
12632    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12633         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12634   "TARGET_64BIT
12635    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12636    && ix86_match_ccmode (insn, CCGOCmode)
12637    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12638   "shr{q}\t{%2, %0|%0, %2}"
12639   [(set_attr "type" "ishift")
12640    (set_attr "mode" "DI")])
12641
12642 (define_insn "*lshrdi3_cconly_rex64"
12643   [(set (reg FLAGS_REG)
12644         (compare
12645           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12646                        (match_operand:QI 2 "const_int_operand" "e"))
12647           (const_int 0)))
12648    (clobber (match_scratch:DI 0 "=r"))]
12649   "TARGET_64BIT
12650    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12651    && ix86_match_ccmode (insn, CCGOCmode)
12652    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12653   "shr{q}\t{%2, %0|%0, %2}"
12654   [(set_attr "type" "ishift")
12655    (set_attr "mode" "DI")])
12656
12657 (define_insn "*lshrdi3_1"
12658   [(set (match_operand:DI 0 "register_operand" "=r")
12659         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12660                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12661    (clobber (reg:CC FLAGS_REG))]
12662   "!TARGET_64BIT"
12663   "#"
12664   [(set_attr "type" "multi")])
12665
12666 ;; By default we don't ask for a scratch register, because when DImode
12667 ;; values are manipulated, registers are already at a premium.  But if
12668 ;; we have one handy, we won't turn it away.
12669 (define_peephole2
12670   [(match_scratch:SI 3 "r")
12671    (parallel [(set (match_operand:DI 0 "register_operand" "")
12672                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12673                                 (match_operand:QI 2 "nonmemory_operand" "")))
12674               (clobber (reg:CC FLAGS_REG))])
12675    (match_dup 3)]
12676   "!TARGET_64BIT && TARGET_CMOVE"
12677   [(const_int 0)]
12678   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12679
12680 (define_split
12681   [(set (match_operand:DI 0 "register_operand" "")
12682         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12683                      (match_operand:QI 2 "nonmemory_operand" "")))
12684    (clobber (reg:CC FLAGS_REG))]
12685   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12686                      ? epilogue_completed : reload_completed)"
12687   [(const_int 0)]
12688   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12689
12690 (define_expand "lshrsi3"
12691   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12692         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12693                      (match_operand:QI 2 "nonmemory_operand" "")))
12694    (clobber (reg:CC FLAGS_REG))]
12695   ""
12696   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12697
12698 (define_insn "*lshrsi3_1_one_bit"
12699   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12700         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12701                      (match_operand:QI 2 "const1_operand" "")))
12702    (clobber (reg:CC FLAGS_REG))]
12703   "(TARGET_SHIFT1 || optimize_size)
12704    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12705   "shr{l}\t%0"
12706   [(set_attr "type" "ishift")
12707    (set (attr "length")
12708      (if_then_else (match_operand:SI 0 "register_operand" "")
12709         (const_string "2")
12710         (const_string "*")))])
12711
12712 (define_insn "*lshrsi3_1_one_bit_zext"
12713   [(set (match_operand:DI 0 "register_operand" "=r")
12714         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12715                      (match_operand:QI 2 "const1_operand" "")))
12716    (clobber (reg:CC FLAGS_REG))]
12717   "TARGET_64BIT
12718    && (TARGET_SHIFT1 || optimize_size)
12719    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12720   "shr{l}\t%k0"
12721   [(set_attr "type" "ishift")
12722    (set_attr "length" "2")])
12723
12724 (define_insn "*lshrsi3_1"
12725   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12726         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12727                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12728    (clobber (reg:CC FLAGS_REG))]
12729   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12730   "@
12731    shr{l}\t{%2, %0|%0, %2}
12732    shr{l}\t{%b2, %0|%0, %b2}"
12733   [(set_attr "type" "ishift")
12734    (set_attr "mode" "SI")])
12735
12736 (define_insn "*lshrsi3_1_zext"
12737   [(set (match_operand:DI 0 "register_operand" "=r,r")
12738         (zero_extend:DI
12739           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12740                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12741    (clobber (reg:CC FLAGS_REG))]
12742   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12743   "@
12744    shr{l}\t{%2, %k0|%k0, %2}
12745    shr{l}\t{%b2, %k0|%k0, %b2}"
12746   [(set_attr "type" "ishift")
12747    (set_attr "mode" "SI")])
12748
12749 ;; This pattern can't accept a variable shift count, since shifts by
12750 ;; zero don't affect the flags.  We assume that shifts by constant
12751 ;; zero are optimized away.
12752 (define_insn "*lshrsi3_one_bit_cmp"
12753   [(set (reg FLAGS_REG)
12754         (compare
12755           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12756                        (match_operand:QI 2 "const1_operand" ""))
12757           (const_int 0)))
12758    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12759         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12760   "(TARGET_SHIFT1 || optimize_size)
12761    && ix86_match_ccmode (insn, CCGOCmode)
12762    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12763   "shr{l}\t%0"
12764   [(set_attr "type" "ishift")
12765    (set (attr "length")
12766      (if_then_else (match_operand:SI 0 "register_operand" "")
12767         (const_string "2")
12768         (const_string "*")))])
12769
12770 (define_insn "*lshrsi3_one_bit_cconly"
12771   [(set (reg FLAGS_REG)
12772         (compare
12773           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12774                        (match_operand:QI 2 "const1_operand" ""))
12775           (const_int 0)))
12776    (clobber (match_scratch:SI 0 "=r"))]
12777   "(TARGET_SHIFT1 || optimize_size)
12778    && ix86_match_ccmode (insn, CCGOCmode)
12779    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12780   "shr{l}\t%0"
12781   [(set_attr "type" "ishift")
12782    (set_attr "length" "2")])
12783
12784 (define_insn "*lshrsi3_cmp_one_bit_zext"
12785   [(set (reg FLAGS_REG)
12786         (compare
12787           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12788                        (match_operand:QI 2 "const1_operand" ""))
12789           (const_int 0)))
12790    (set (match_operand:DI 0 "register_operand" "=r")
12791         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12792   "TARGET_64BIT
12793    && (TARGET_SHIFT1 || optimize_size)
12794    && ix86_match_ccmode (insn, CCGOCmode)
12795    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12796   "shr{l}\t%k0"
12797   [(set_attr "type" "ishift")
12798    (set_attr "length" "2")])
12799
12800 ;; This pattern can't accept a variable shift count, since shifts by
12801 ;; zero don't affect the flags.  We assume that shifts by constant
12802 ;; zero are optimized away.
12803 (define_insn "*lshrsi3_cmp"
12804   [(set (reg FLAGS_REG)
12805         (compare
12806           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12807                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12808           (const_int 0)))
12809    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12810         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12811   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12812    && ix86_match_ccmode (insn, CCGOCmode)
12813    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12814   "shr{l}\t{%2, %0|%0, %2}"
12815   [(set_attr "type" "ishift")
12816    (set_attr "mode" "SI")])
12817
12818 (define_insn "*lshrsi3_cconly"
12819   [(set (reg FLAGS_REG)
12820       (compare
12821         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12822                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12823         (const_int 0)))
12824    (clobber (match_scratch:SI 0 "=r"))]
12825   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12826    && ix86_match_ccmode (insn, CCGOCmode)
12827    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12828   "shr{l}\t{%2, %0|%0, %2}"
12829   [(set_attr "type" "ishift")
12830    (set_attr "mode" "SI")])
12831
12832 (define_insn "*lshrsi3_cmp_zext"
12833   [(set (reg FLAGS_REG)
12834         (compare
12835           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12836                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12837           (const_int 0)))
12838    (set (match_operand:DI 0 "register_operand" "=r")
12839         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12840   "TARGET_64BIT
12841    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12842    && ix86_match_ccmode (insn, CCGOCmode)
12843    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12844   "shr{l}\t{%2, %k0|%k0, %2}"
12845   [(set_attr "type" "ishift")
12846    (set_attr "mode" "SI")])
12847
12848 (define_expand "lshrhi3"
12849   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12850         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12851                      (match_operand:QI 2 "nonmemory_operand" "")))
12852    (clobber (reg:CC FLAGS_REG))]
12853   "TARGET_HIMODE_MATH"
12854   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12855
12856 (define_insn "*lshrhi3_1_one_bit"
12857   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12858         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12859                      (match_operand:QI 2 "const1_operand" "")))
12860    (clobber (reg:CC FLAGS_REG))]
12861   "(TARGET_SHIFT1 || optimize_size)
12862    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12863   "shr{w}\t%0"
12864   [(set_attr "type" "ishift")
12865    (set (attr "length")
12866      (if_then_else (match_operand 0 "register_operand" "")
12867         (const_string "2")
12868         (const_string "*")))])
12869
12870 (define_insn "*lshrhi3_1"
12871   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12872         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12873                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12874    (clobber (reg:CC FLAGS_REG))]
12875   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12876   "@
12877    shr{w}\t{%2, %0|%0, %2}
12878    shr{w}\t{%b2, %0|%0, %b2}"
12879   [(set_attr "type" "ishift")
12880    (set_attr "mode" "HI")])
12881
12882 ;; This pattern can't accept a variable shift count, since shifts by
12883 ;; zero don't affect the flags.  We assume that shifts by constant
12884 ;; zero are optimized away.
12885 (define_insn "*lshrhi3_one_bit_cmp"
12886   [(set (reg FLAGS_REG)
12887         (compare
12888           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12889                        (match_operand:QI 2 "const1_operand" ""))
12890           (const_int 0)))
12891    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12892         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12893   "(TARGET_SHIFT1 || optimize_size)
12894    && ix86_match_ccmode (insn, CCGOCmode)
12895    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12896   "shr{w}\t%0"
12897   [(set_attr "type" "ishift")
12898    (set (attr "length")
12899      (if_then_else (match_operand:SI 0 "register_operand" "")
12900         (const_string "2")
12901         (const_string "*")))])
12902
12903 (define_insn "*lshrhi3_one_bit_cconly"
12904   [(set (reg FLAGS_REG)
12905         (compare
12906           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12907                        (match_operand:QI 2 "const1_operand" ""))
12908           (const_int 0)))
12909    (clobber (match_scratch:HI 0 "=r"))]
12910   "(TARGET_SHIFT1 || optimize_size)
12911    && ix86_match_ccmode (insn, CCGOCmode)
12912    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12913   "shr{w}\t%0"
12914   [(set_attr "type" "ishift")
12915    (set_attr "length" "2")])
12916
12917 ;; This pattern can't accept a variable shift count, since shifts by
12918 ;; zero don't affect the flags.  We assume that shifts by constant
12919 ;; zero are optimized away.
12920 (define_insn "*lshrhi3_cmp"
12921   [(set (reg FLAGS_REG)
12922         (compare
12923           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12924                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12925           (const_int 0)))
12926    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12927         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12928   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12929    && ix86_match_ccmode (insn, CCGOCmode)
12930    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12931   "shr{w}\t{%2, %0|%0, %2}"
12932   [(set_attr "type" "ishift")
12933    (set_attr "mode" "HI")])
12934
12935 (define_insn "*lshrhi3_cconly"
12936   [(set (reg FLAGS_REG)
12937         (compare
12938           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12939                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12940           (const_int 0)))
12941    (clobber (match_scratch:HI 0 "=r"))]
12942   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12943    && ix86_match_ccmode (insn, CCGOCmode)
12944    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12945   "shr{w}\t{%2, %0|%0, %2}"
12946   [(set_attr "type" "ishift")
12947    (set_attr "mode" "HI")])
12948
12949 (define_expand "lshrqi3"
12950   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12951         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12952                      (match_operand:QI 2 "nonmemory_operand" "")))
12953    (clobber (reg:CC FLAGS_REG))]
12954   "TARGET_QIMODE_MATH"
12955   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12956
12957 (define_insn "*lshrqi3_1_one_bit"
12958   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12959         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12960                      (match_operand:QI 2 "const1_operand" "")))
12961    (clobber (reg:CC FLAGS_REG))]
12962   "(TARGET_SHIFT1 || optimize_size)
12963    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12964   "shr{b}\t%0"
12965   [(set_attr "type" "ishift")
12966    (set (attr "length")
12967      (if_then_else (match_operand 0 "register_operand" "")
12968         (const_string "2")
12969         (const_string "*")))])
12970
12971 (define_insn "*lshrqi3_1_one_bit_slp"
12972   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12973         (lshiftrt:QI (match_dup 0)
12974                      (match_operand:QI 1 "const1_operand" "")))
12975    (clobber (reg:CC FLAGS_REG))]
12976   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12977    && (TARGET_SHIFT1 || optimize_size)"
12978   "shr{b}\t%0"
12979   [(set_attr "type" "ishift1")
12980    (set (attr "length")
12981      (if_then_else (match_operand 0 "register_operand" "")
12982         (const_string "2")
12983         (const_string "*")))])
12984
12985 (define_insn "*lshrqi3_1"
12986   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12987         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12988                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12989    (clobber (reg:CC FLAGS_REG))]
12990   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12991   "@
12992    shr{b}\t{%2, %0|%0, %2}
12993    shr{b}\t{%b2, %0|%0, %b2}"
12994   [(set_attr "type" "ishift")
12995    (set_attr "mode" "QI")])
12996
12997 (define_insn "*lshrqi3_1_slp"
12998   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12999         (lshiftrt:QI (match_dup 0)
13000                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13001    (clobber (reg:CC FLAGS_REG))]
13002   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13003    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13004   "@
13005    shr{b}\t{%1, %0|%0, %1}
13006    shr{b}\t{%b1, %0|%0, %b1}"
13007   [(set_attr "type" "ishift1")
13008    (set_attr "mode" "QI")])
13009
13010 ;; This pattern can't accept a variable shift count, since shifts by
13011 ;; zero don't affect the flags.  We assume that shifts by constant
13012 ;; zero are optimized away.
13013 (define_insn "*lshrqi2_one_bit_cmp"
13014   [(set (reg FLAGS_REG)
13015         (compare
13016           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13017                        (match_operand:QI 2 "const1_operand" ""))
13018           (const_int 0)))
13019    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13020         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13021   "(TARGET_SHIFT1 || optimize_size)
13022    && ix86_match_ccmode (insn, CCGOCmode)
13023    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13024   "shr{b}\t%0"
13025   [(set_attr "type" "ishift")
13026    (set (attr "length")
13027      (if_then_else (match_operand:SI 0 "register_operand" "")
13028         (const_string "2")
13029         (const_string "*")))])
13030
13031 (define_insn "*lshrqi2_one_bit_cconly"
13032   [(set (reg FLAGS_REG)
13033         (compare
13034           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13035                        (match_operand:QI 2 "const1_operand" ""))
13036           (const_int 0)))
13037    (clobber (match_scratch:QI 0 "=q"))]
13038   "(TARGET_SHIFT1 || optimize_size)
13039    && ix86_match_ccmode (insn, CCGOCmode)
13040    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13041   "shr{b}\t%0"
13042   [(set_attr "type" "ishift")
13043    (set_attr "length" "2")])
13044
13045 ;; This pattern can't accept a variable shift count, since shifts by
13046 ;; zero don't affect the flags.  We assume that shifts by constant
13047 ;; zero are optimized away.
13048 (define_insn "*lshrqi2_cmp"
13049   [(set (reg FLAGS_REG)
13050         (compare
13051           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13052                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13053           (const_int 0)))
13054    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13055         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13056   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13057    && ix86_match_ccmode (insn, CCGOCmode)
13058    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13059   "shr{b}\t{%2, %0|%0, %2}"
13060   [(set_attr "type" "ishift")
13061    (set_attr "mode" "QI")])
13062
13063 (define_insn "*lshrqi2_cconly"
13064   [(set (reg FLAGS_REG)
13065         (compare
13066           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13067                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13068           (const_int 0)))
13069    (clobber (match_scratch:QI 0 "=q"))]
13070   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13071    && ix86_match_ccmode (insn, CCGOCmode)
13072    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13073   "shr{b}\t{%2, %0|%0, %2}"
13074   [(set_attr "type" "ishift")
13075    (set_attr "mode" "QI")])
13076 \f
13077 ;; Rotate instructions
13078
13079 (define_expand "rotldi3"
13080   [(set (match_operand:DI 0 "shiftdi_operand" "")
13081         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13082                    (match_operand:QI 2 "nonmemory_operand" "")))
13083    (clobber (reg:CC FLAGS_REG))]
13084  ""
13085 {
13086   if (TARGET_64BIT)
13087     {
13088       ix86_expand_binary_operator (ROTATE, DImode, operands);
13089       DONE;
13090     }
13091   if (!const_1_to_31_operand (operands[2], VOIDmode))
13092     FAIL;
13093   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13094   DONE;
13095 })
13096
13097 ;; Implement rotation using two double-precision shift instructions
13098 ;; and a scratch register.
13099 (define_insn_and_split "ix86_rotldi3"
13100  [(set (match_operand:DI 0 "register_operand" "=r")
13101        (rotate:DI (match_operand:DI 1 "register_operand" "0")
13102                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
13103   (clobber (reg:CC FLAGS_REG))
13104   (clobber (match_scratch:SI 3 "=&r"))]
13105  "!TARGET_64BIT"
13106  ""
13107  "&& reload_completed"
13108  [(set (match_dup 3) (match_dup 4))
13109   (parallel
13110    [(set (match_dup 4)
13111          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13112                  (lshiftrt:SI (match_dup 5)
13113                               (minus:QI (const_int 32) (match_dup 2)))))
13114     (clobber (reg:CC FLAGS_REG))])
13115   (parallel
13116    [(set (match_dup 5)
13117          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13118                  (lshiftrt:SI (match_dup 3)
13119                               (minus:QI (const_int 32) (match_dup 2)))))
13120     (clobber (reg:CC FLAGS_REG))])]
13121  "split_di (operands, 1, operands + 4, operands + 5);")
13122
13123 (define_insn "*rotlsi3_1_one_bit_rex64"
13124   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13125         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13126                    (match_operand:QI 2 "const1_operand" "")))
13127    (clobber (reg:CC FLAGS_REG))]
13128   "TARGET_64BIT
13129    && (TARGET_SHIFT1 || optimize_size)
13130    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13131   "rol{q}\t%0"
13132   [(set_attr "type" "rotate")
13133    (set (attr "length")
13134      (if_then_else (match_operand:DI 0 "register_operand" "")
13135         (const_string "2")
13136         (const_string "*")))])
13137
13138 (define_insn "*rotldi3_1_rex64"
13139   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13140         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13141                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
13142    (clobber (reg:CC FLAGS_REG))]
13143   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13144   "@
13145    rol{q}\t{%2, %0|%0, %2}
13146    rol{q}\t{%b2, %0|%0, %b2}"
13147   [(set_attr "type" "rotate")
13148    (set_attr "mode" "DI")])
13149
13150 (define_expand "rotlsi3"
13151   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13152         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13153                    (match_operand:QI 2 "nonmemory_operand" "")))
13154    (clobber (reg:CC FLAGS_REG))]
13155   ""
13156   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13157
13158 (define_insn "*rotlsi3_1_one_bit"
13159   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13160         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13161                    (match_operand:QI 2 "const1_operand" "")))
13162    (clobber (reg:CC FLAGS_REG))]
13163   "(TARGET_SHIFT1 || optimize_size)
13164    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13165   "rol{l}\t%0"
13166   [(set_attr "type" "rotate")
13167    (set (attr "length")
13168      (if_then_else (match_operand:SI 0 "register_operand" "")
13169         (const_string "2")
13170         (const_string "*")))])
13171
13172 (define_insn "*rotlsi3_1_one_bit_zext"
13173   [(set (match_operand:DI 0 "register_operand" "=r")
13174         (zero_extend:DI
13175           (rotate:SI (match_operand:SI 1 "register_operand" "0")
13176                      (match_operand:QI 2 "const1_operand" ""))))
13177    (clobber (reg:CC FLAGS_REG))]
13178   "TARGET_64BIT
13179    && (TARGET_SHIFT1 || optimize_size)
13180    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13181   "rol{l}\t%k0"
13182   [(set_attr "type" "rotate")
13183    (set_attr "length" "2")])
13184
13185 (define_insn "*rotlsi3_1"
13186   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13187         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13188                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13189    (clobber (reg:CC FLAGS_REG))]
13190   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13191   "@
13192    rol{l}\t{%2, %0|%0, %2}
13193    rol{l}\t{%b2, %0|%0, %b2}"
13194   [(set_attr "type" "rotate")
13195    (set_attr "mode" "SI")])
13196
13197 (define_insn "*rotlsi3_1_zext"
13198   [(set (match_operand:DI 0 "register_operand" "=r,r")
13199         (zero_extend:DI
13200           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13201                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13202    (clobber (reg:CC FLAGS_REG))]
13203   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13204   "@
13205    rol{l}\t{%2, %k0|%k0, %2}
13206    rol{l}\t{%b2, %k0|%k0, %b2}"
13207   [(set_attr "type" "rotate")
13208    (set_attr "mode" "SI")])
13209
13210 (define_expand "rotlhi3"
13211   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13212         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13213                    (match_operand:QI 2 "nonmemory_operand" "")))
13214    (clobber (reg:CC FLAGS_REG))]
13215   "TARGET_HIMODE_MATH"
13216   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13217
13218 (define_insn "*rotlhi3_1_one_bit"
13219   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13220         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13221                    (match_operand:QI 2 "const1_operand" "")))
13222    (clobber (reg:CC FLAGS_REG))]
13223   "(TARGET_SHIFT1 || optimize_size)
13224    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13225   "rol{w}\t%0"
13226   [(set_attr "type" "rotate")
13227    (set (attr "length")
13228      (if_then_else (match_operand 0 "register_operand" "")
13229         (const_string "2")
13230         (const_string "*")))])
13231
13232 (define_insn "*rotlhi3_1"
13233   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13234         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13235                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13236    (clobber (reg:CC FLAGS_REG))]
13237   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13238   "@
13239    rol{w}\t{%2, %0|%0, %2}
13240    rol{w}\t{%b2, %0|%0, %b2}"
13241   [(set_attr "type" "rotate")
13242    (set_attr "mode" "HI")])
13243
13244 (define_split
13245  [(set (match_operand:HI 0 "register_operand" "")
13246        (rotate:HI (match_dup 0) (const_int 8)))
13247   (clobber (reg:CC FLAGS_REG))]
13248  "reload_completed"
13249  [(parallel [(set (strict_low_part (match_dup 0))
13250                   (bswap:HI (match_dup 0)))
13251              (clobber (reg:CC FLAGS_REG))])]
13252  "")
13253
13254 (define_expand "rotlqi3"
13255   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13256         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13257                    (match_operand:QI 2 "nonmemory_operand" "")))
13258    (clobber (reg:CC FLAGS_REG))]
13259   "TARGET_QIMODE_MATH"
13260   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13261
13262 (define_insn "*rotlqi3_1_one_bit_slp"
13263   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13264         (rotate:QI (match_dup 0)
13265                    (match_operand:QI 1 "const1_operand" "")))
13266    (clobber (reg:CC FLAGS_REG))]
13267   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13268    && (TARGET_SHIFT1 || optimize_size)"
13269   "rol{b}\t%0"
13270   [(set_attr "type" "rotate1")
13271    (set (attr "length")
13272      (if_then_else (match_operand 0 "register_operand" "")
13273         (const_string "2")
13274         (const_string "*")))])
13275
13276 (define_insn "*rotlqi3_1_one_bit"
13277   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13278         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13279                    (match_operand:QI 2 "const1_operand" "")))
13280    (clobber (reg:CC FLAGS_REG))]
13281   "(TARGET_SHIFT1 || optimize_size)
13282    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13283   "rol{b}\t%0"
13284   [(set_attr "type" "rotate")
13285    (set (attr "length")
13286      (if_then_else (match_operand 0 "register_operand" "")
13287         (const_string "2")
13288         (const_string "*")))])
13289
13290 (define_insn "*rotlqi3_1_slp"
13291   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13292         (rotate:QI (match_dup 0)
13293                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13294    (clobber (reg:CC FLAGS_REG))]
13295   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13296    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13297   "@
13298    rol{b}\t{%1, %0|%0, %1}
13299    rol{b}\t{%b1, %0|%0, %b1}"
13300   [(set_attr "type" "rotate1")
13301    (set_attr "mode" "QI")])
13302
13303 (define_insn "*rotlqi3_1"
13304   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13305         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13306                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13307    (clobber (reg:CC FLAGS_REG))]
13308   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13309   "@
13310    rol{b}\t{%2, %0|%0, %2}
13311    rol{b}\t{%b2, %0|%0, %b2}"
13312   [(set_attr "type" "rotate")
13313    (set_attr "mode" "QI")])
13314
13315 (define_expand "rotrdi3"
13316   [(set (match_operand:DI 0 "shiftdi_operand" "")
13317         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13318                    (match_operand:QI 2 "nonmemory_operand" "")))
13319    (clobber (reg:CC FLAGS_REG))]
13320  ""
13321 {
13322   if (TARGET_64BIT)
13323     {
13324       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13325       DONE;
13326     }
13327   if (!const_1_to_31_operand (operands[2], VOIDmode))
13328     FAIL;
13329   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13330   DONE;
13331 })
13332
13333 ;; Implement rotation using two double-precision shift instructions
13334 ;; and a scratch register.
13335 (define_insn_and_split "ix86_rotrdi3"
13336  [(set (match_operand:DI 0 "register_operand" "=r")
13337        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13338                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13339   (clobber (reg:CC FLAGS_REG))
13340   (clobber (match_scratch:SI 3 "=&r"))]
13341  "!TARGET_64BIT"
13342  ""
13343  "&& reload_completed"
13344  [(set (match_dup 3) (match_dup 4))
13345   (parallel
13346    [(set (match_dup 4)
13347          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13348                  (ashift:SI (match_dup 5)
13349                             (minus:QI (const_int 32) (match_dup 2)))))
13350     (clobber (reg:CC FLAGS_REG))])
13351   (parallel
13352    [(set (match_dup 5)
13353          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13354                  (ashift:SI (match_dup 3)
13355                             (minus:QI (const_int 32) (match_dup 2)))))
13356     (clobber (reg:CC FLAGS_REG))])]
13357  "split_di (operands, 1, operands + 4, operands + 5);")
13358
13359 (define_insn "*rotrdi3_1_one_bit_rex64"
13360   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13361         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13362                      (match_operand:QI 2 "const1_operand" "")))
13363    (clobber (reg:CC FLAGS_REG))]
13364   "TARGET_64BIT
13365    && (TARGET_SHIFT1 || optimize_size)
13366    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13367   "ror{q}\t%0"
13368   [(set_attr "type" "rotate")
13369    (set (attr "length")
13370      (if_then_else (match_operand:DI 0 "register_operand" "")
13371         (const_string "2")
13372         (const_string "*")))])
13373
13374 (define_insn "*rotrdi3_1_rex64"
13375   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13376         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13377                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13378    (clobber (reg:CC FLAGS_REG))]
13379   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13380   "@
13381    ror{q}\t{%2, %0|%0, %2}
13382    ror{q}\t{%b2, %0|%0, %b2}"
13383   [(set_attr "type" "rotate")
13384    (set_attr "mode" "DI")])
13385
13386 (define_expand "rotrsi3"
13387   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13388         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13389                      (match_operand:QI 2 "nonmemory_operand" "")))
13390    (clobber (reg:CC FLAGS_REG))]
13391   ""
13392   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13393
13394 (define_insn "*rotrsi3_1_one_bit"
13395   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13396         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13397                      (match_operand:QI 2 "const1_operand" "")))
13398    (clobber (reg:CC FLAGS_REG))]
13399   "(TARGET_SHIFT1 || optimize_size)
13400    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13401   "ror{l}\t%0"
13402   [(set_attr "type" "rotate")
13403    (set (attr "length")
13404      (if_then_else (match_operand:SI 0 "register_operand" "")
13405         (const_string "2")
13406         (const_string "*")))])
13407
13408 (define_insn "*rotrsi3_1_one_bit_zext"
13409   [(set (match_operand:DI 0 "register_operand" "=r")
13410         (zero_extend:DI
13411           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13412                        (match_operand:QI 2 "const1_operand" ""))))
13413    (clobber (reg:CC FLAGS_REG))]
13414   "TARGET_64BIT
13415    && (TARGET_SHIFT1 || optimize_size)
13416    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13417   "ror{l}\t%k0"
13418   [(set_attr "type" "rotate")
13419    (set (attr "length")
13420      (if_then_else (match_operand:SI 0 "register_operand" "")
13421         (const_string "2")
13422         (const_string "*")))])
13423
13424 (define_insn "*rotrsi3_1"
13425   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13426         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13427                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13428    (clobber (reg:CC FLAGS_REG))]
13429   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13430   "@
13431    ror{l}\t{%2, %0|%0, %2}
13432    ror{l}\t{%b2, %0|%0, %b2}"
13433   [(set_attr "type" "rotate")
13434    (set_attr "mode" "SI")])
13435
13436 (define_insn "*rotrsi3_1_zext"
13437   [(set (match_operand:DI 0 "register_operand" "=r,r")
13438         (zero_extend:DI
13439           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13440                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13441    (clobber (reg:CC FLAGS_REG))]
13442   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13443   "@
13444    ror{l}\t{%2, %k0|%k0, %2}
13445    ror{l}\t{%b2, %k0|%k0, %b2}"
13446   [(set_attr "type" "rotate")
13447    (set_attr "mode" "SI")])
13448
13449 (define_expand "rotrhi3"
13450   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13451         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13452                      (match_operand:QI 2 "nonmemory_operand" "")))
13453    (clobber (reg:CC FLAGS_REG))]
13454   "TARGET_HIMODE_MATH"
13455   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13456
13457 (define_insn "*rotrhi3_one_bit"
13458   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13459         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13460                      (match_operand:QI 2 "const1_operand" "")))
13461    (clobber (reg:CC FLAGS_REG))]
13462   "(TARGET_SHIFT1 || optimize_size)
13463    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13464   "ror{w}\t%0"
13465   [(set_attr "type" "rotate")
13466    (set (attr "length")
13467      (if_then_else (match_operand 0 "register_operand" "")
13468         (const_string "2")
13469         (const_string "*")))])
13470
13471 (define_insn "*rotrhi3_1"
13472   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13473         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13474                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13475    (clobber (reg:CC FLAGS_REG))]
13476   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13477   "@
13478    ror{w}\t{%2, %0|%0, %2}
13479    ror{w}\t{%b2, %0|%0, %b2}"
13480   [(set_attr "type" "rotate")
13481    (set_attr "mode" "HI")])
13482
13483 (define_split
13484  [(set (match_operand:HI 0 "register_operand" "")
13485        (rotatert:HI (match_dup 0) (const_int 8)))
13486   (clobber (reg:CC FLAGS_REG))]
13487  "reload_completed"
13488  [(parallel [(set (strict_low_part (match_dup 0))
13489                   (bswap:HI (match_dup 0)))
13490              (clobber (reg:CC FLAGS_REG))])]
13491  "")
13492
13493 (define_expand "rotrqi3"
13494   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13495         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13496                      (match_operand:QI 2 "nonmemory_operand" "")))
13497    (clobber (reg:CC FLAGS_REG))]
13498   "TARGET_QIMODE_MATH"
13499   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13500
13501 (define_insn "*rotrqi3_1_one_bit"
13502   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13503         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13504                      (match_operand:QI 2 "const1_operand" "")))
13505    (clobber (reg:CC FLAGS_REG))]
13506   "(TARGET_SHIFT1 || optimize_size)
13507    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13508   "ror{b}\t%0"
13509   [(set_attr "type" "rotate")
13510    (set (attr "length")
13511      (if_then_else (match_operand 0 "register_operand" "")
13512         (const_string "2")
13513         (const_string "*")))])
13514
13515 (define_insn "*rotrqi3_1_one_bit_slp"
13516   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13517         (rotatert:QI (match_dup 0)
13518                      (match_operand:QI 1 "const1_operand" "")))
13519    (clobber (reg:CC FLAGS_REG))]
13520   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13521    && (TARGET_SHIFT1 || optimize_size)"
13522   "ror{b}\t%0"
13523   [(set_attr "type" "rotate1")
13524    (set (attr "length")
13525      (if_then_else (match_operand 0 "register_operand" "")
13526         (const_string "2")
13527         (const_string "*")))])
13528
13529 (define_insn "*rotrqi3_1"
13530   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13531         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13532                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13533    (clobber (reg:CC FLAGS_REG))]
13534   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13535   "@
13536    ror{b}\t{%2, %0|%0, %2}
13537    ror{b}\t{%b2, %0|%0, %b2}"
13538   [(set_attr "type" "rotate")
13539    (set_attr "mode" "QI")])
13540
13541 (define_insn "*rotrqi3_1_slp"
13542   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13543         (rotatert:QI (match_dup 0)
13544                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13545    (clobber (reg:CC FLAGS_REG))]
13546   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13547    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13548   "@
13549    ror{b}\t{%1, %0|%0, %1}
13550    ror{b}\t{%b1, %0|%0, %b1}"
13551   [(set_attr "type" "rotate1")
13552    (set_attr "mode" "QI")])
13553 \f
13554 ;; Bit set / bit test instructions
13555
13556 (define_expand "extv"
13557   [(set (match_operand:SI 0 "register_operand" "")
13558         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13559                          (match_operand:SI 2 "const8_operand" "")
13560                          (match_operand:SI 3 "const8_operand" "")))]
13561   ""
13562 {
13563   /* Handle extractions from %ah et al.  */
13564   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13565     FAIL;
13566
13567   /* From mips.md: extract_bit_field doesn't verify that our source
13568      matches the predicate, so check it again here.  */
13569   if (! ext_register_operand (operands[1], VOIDmode))
13570     FAIL;
13571 })
13572
13573 (define_expand "extzv"
13574   [(set (match_operand:SI 0 "register_operand" "")
13575         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13576                          (match_operand:SI 2 "const8_operand" "")
13577                          (match_operand:SI 3 "const8_operand" "")))]
13578   ""
13579 {
13580   /* Handle extractions from %ah et al.  */
13581   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13582     FAIL;
13583
13584   /* From mips.md: extract_bit_field doesn't verify that our source
13585      matches the predicate, so check it again here.  */
13586   if (! ext_register_operand (operands[1], VOIDmode))
13587     FAIL;
13588 })
13589
13590 (define_expand "insv"
13591   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13592                       (match_operand 1 "const8_operand" "")
13593                       (match_operand 2 "const8_operand" ""))
13594         (match_operand 3 "register_operand" ""))]
13595   ""
13596 {
13597   /* Handle insertions to %ah et al.  */
13598   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13599     FAIL;
13600
13601   /* From mips.md: insert_bit_field doesn't verify that our source
13602      matches the predicate, so check it again here.  */
13603   if (! ext_register_operand (operands[0], VOIDmode))
13604     FAIL;
13605
13606   if (TARGET_64BIT)
13607     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13608   else
13609     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13610
13611   DONE;
13612 })
13613
13614 ;; %%% bts, btr, btc, bt.
13615 ;; In general these instructions are *slow* when applied to memory,
13616 ;; since they enforce atomic operation.  When applied to registers,
13617 ;; it depends on the cpu implementation.  They're never faster than
13618 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13619 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13620 ;; within the instruction itself, so operating on bits in the high
13621 ;; 32-bits of a register becomes easier.
13622 ;;
13623 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13624 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13625 ;; negdf respectively, so they can never be disabled entirely.
13626
13627 (define_insn "*btsq"
13628   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13629                          (const_int 1)
13630                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13631         (const_int 1))
13632    (clobber (reg:CC FLAGS_REG))]
13633   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13634   "bts{q} %1,%0"
13635   [(set_attr "type" "alu1")])
13636
13637 (define_insn "*btrq"
13638   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13639                          (const_int 1)
13640                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13641         (const_int 0))
13642    (clobber (reg:CC FLAGS_REG))]
13643   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13644   "btr{q} %1,%0"
13645   [(set_attr "type" "alu1")])
13646
13647 (define_insn "*btcq"
13648   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13649                          (const_int 1)
13650                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13651         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13652    (clobber (reg:CC FLAGS_REG))]
13653   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13654   "btc{q} %1,%0"
13655   [(set_attr "type" "alu1")])
13656
13657 ;; Allow Nocona to avoid these instructions if a register is available.
13658
13659 (define_peephole2
13660   [(match_scratch:DI 2 "r")
13661    (parallel [(set (zero_extract:DI
13662                      (match_operand:DI 0 "register_operand" "")
13663                      (const_int 1)
13664                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13665                    (const_int 1))
13666               (clobber (reg:CC FLAGS_REG))])]
13667   "TARGET_64BIT && !TARGET_USE_BT"
13668   [(const_int 0)]
13669 {
13670   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13671   rtx op1;
13672
13673   if (HOST_BITS_PER_WIDE_INT >= 64)
13674     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13675   else if (i < HOST_BITS_PER_WIDE_INT)
13676     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13677   else
13678     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13679
13680   op1 = immed_double_const (lo, hi, DImode);
13681   if (i >= 31)
13682     {
13683       emit_move_insn (operands[2], op1);
13684       op1 = operands[2];
13685     }
13686
13687   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13688   DONE;
13689 })
13690
13691 (define_peephole2
13692   [(match_scratch:DI 2 "r")
13693    (parallel [(set (zero_extract:DI
13694                      (match_operand:DI 0 "register_operand" "")
13695                      (const_int 1)
13696                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13697                    (const_int 0))
13698               (clobber (reg:CC FLAGS_REG))])]
13699   "TARGET_64BIT && !TARGET_USE_BT"
13700   [(const_int 0)]
13701 {
13702   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13703   rtx op1;
13704
13705   if (HOST_BITS_PER_WIDE_INT >= 64)
13706     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13707   else if (i < HOST_BITS_PER_WIDE_INT)
13708     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13709   else
13710     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13711
13712   op1 = immed_double_const (~lo, ~hi, DImode);
13713   if (i >= 32)
13714     {
13715       emit_move_insn (operands[2], op1);
13716       op1 = operands[2];
13717     }
13718
13719   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13720   DONE;
13721 })
13722
13723 (define_peephole2
13724   [(match_scratch:DI 2 "r")
13725    (parallel [(set (zero_extract:DI
13726                      (match_operand:DI 0 "register_operand" "")
13727                      (const_int 1)
13728                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13729               (not:DI (zero_extract:DI
13730                         (match_dup 0) (const_int 1) (match_dup 1))))
13731               (clobber (reg:CC FLAGS_REG))])]
13732   "TARGET_64BIT && !TARGET_USE_BT"
13733   [(const_int 0)]
13734 {
13735   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13736   rtx op1;
13737
13738   if (HOST_BITS_PER_WIDE_INT >= 64)
13739     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13740   else if (i < HOST_BITS_PER_WIDE_INT)
13741     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13742   else
13743     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13744
13745   op1 = immed_double_const (lo, hi, DImode);
13746   if (i >= 31)
13747     {
13748       emit_move_insn (operands[2], op1);
13749       op1 = operands[2];
13750     }
13751
13752   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13753   DONE;
13754 })
13755 \f
13756 ;; Store-flag instructions.
13757
13758 ;; For all sCOND expanders, also expand the compare or test insn that
13759 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13760
13761 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13762 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13763 ;; way, which can later delete the movzx if only QImode is needed.
13764
13765 (define_expand "seq"
13766   [(set (match_operand:QI 0 "register_operand" "")
13767         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13768   ""
13769   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13770
13771 (define_expand "sne"
13772   [(set (match_operand:QI 0 "register_operand" "")
13773         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13774   ""
13775   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13776
13777 (define_expand "sgt"
13778   [(set (match_operand:QI 0 "register_operand" "")
13779         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13780   ""
13781   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13782
13783 (define_expand "sgtu"
13784   [(set (match_operand:QI 0 "register_operand" "")
13785         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13786   ""
13787   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13788
13789 (define_expand "slt"
13790   [(set (match_operand:QI 0 "register_operand" "")
13791         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13792   ""
13793   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13794
13795 (define_expand "sltu"
13796   [(set (match_operand:QI 0 "register_operand" "")
13797         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13798   ""
13799   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13800
13801 (define_expand "sge"
13802   [(set (match_operand:QI 0 "register_operand" "")
13803         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13804   ""
13805   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13806
13807 (define_expand "sgeu"
13808   [(set (match_operand:QI 0 "register_operand" "")
13809         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13810   ""
13811   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13812
13813 (define_expand "sle"
13814   [(set (match_operand:QI 0 "register_operand" "")
13815         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13816   ""
13817   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13818
13819 (define_expand "sleu"
13820   [(set (match_operand:QI 0 "register_operand" "")
13821         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13822   ""
13823   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13824
13825 (define_expand "sunordered"
13826   [(set (match_operand:QI 0 "register_operand" "")
13827         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13828   "TARGET_80387 || TARGET_SSE"
13829   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13830
13831 (define_expand "sordered"
13832   [(set (match_operand:QI 0 "register_operand" "")
13833         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13834   "TARGET_80387"
13835   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13836
13837 (define_expand "suneq"
13838   [(set (match_operand:QI 0 "register_operand" "")
13839         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13840   "TARGET_80387 || TARGET_SSE"
13841   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13842
13843 (define_expand "sunge"
13844   [(set (match_operand:QI 0 "register_operand" "")
13845         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13846   "TARGET_80387 || TARGET_SSE"
13847   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13848
13849 (define_expand "sungt"
13850   [(set (match_operand:QI 0 "register_operand" "")
13851         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13852   "TARGET_80387 || TARGET_SSE"
13853   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13854
13855 (define_expand "sunle"
13856   [(set (match_operand:QI 0 "register_operand" "")
13857         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13858   "TARGET_80387 || TARGET_SSE"
13859   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13860
13861 (define_expand "sunlt"
13862   [(set (match_operand:QI 0 "register_operand" "")
13863         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13864   "TARGET_80387 || TARGET_SSE"
13865   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13866
13867 (define_expand "sltgt"
13868   [(set (match_operand:QI 0 "register_operand" "")
13869         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13870   "TARGET_80387 || TARGET_SSE"
13871   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13872
13873 (define_insn "*setcc_1"
13874   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13875         (match_operator:QI 1 "ix86_comparison_operator"
13876           [(reg FLAGS_REG) (const_int 0)]))]
13877   ""
13878   "set%C1\t%0"
13879   [(set_attr "type" "setcc")
13880    (set_attr "mode" "QI")])
13881
13882 (define_insn "*setcc_2"
13883   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13884         (match_operator:QI 1 "ix86_comparison_operator"
13885           [(reg FLAGS_REG) (const_int 0)]))]
13886   ""
13887   "set%C1\t%0"
13888   [(set_attr "type" "setcc")
13889    (set_attr "mode" "QI")])
13890
13891 ;; In general it is not safe to assume too much about CCmode registers,
13892 ;; so simplify-rtx stops when it sees a second one.  Under certain
13893 ;; conditions this is safe on x86, so help combine not create
13894 ;;
13895 ;;      seta    %al
13896 ;;      testb   %al, %al
13897 ;;      sete    %al
13898
13899 (define_split
13900   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13901         (ne:QI (match_operator 1 "ix86_comparison_operator"
13902                  [(reg FLAGS_REG) (const_int 0)])
13903             (const_int 0)))]
13904   ""
13905   [(set (match_dup 0) (match_dup 1))]
13906 {
13907   PUT_MODE (operands[1], QImode);
13908 })
13909
13910 (define_split
13911   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13912         (ne:QI (match_operator 1 "ix86_comparison_operator"
13913                  [(reg FLAGS_REG) (const_int 0)])
13914             (const_int 0)))]
13915   ""
13916   [(set (match_dup 0) (match_dup 1))]
13917 {
13918   PUT_MODE (operands[1], QImode);
13919 })
13920
13921 (define_split
13922   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13923         (eq:QI (match_operator 1 "ix86_comparison_operator"
13924                  [(reg FLAGS_REG) (const_int 0)])
13925             (const_int 0)))]
13926   ""
13927   [(set (match_dup 0) (match_dup 1))]
13928 {
13929   rtx new_op1 = copy_rtx (operands[1]);
13930   operands[1] = new_op1;
13931   PUT_MODE (new_op1, QImode);
13932   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13933                                              GET_MODE (XEXP (new_op1, 0))));
13934
13935   /* Make sure that (a) the CCmode we have for the flags is strong
13936      enough for the reversed compare or (b) we have a valid FP compare.  */
13937   if (! ix86_comparison_operator (new_op1, VOIDmode))
13938     FAIL;
13939 })
13940
13941 (define_split
13942   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13943         (eq:QI (match_operator 1 "ix86_comparison_operator"
13944                  [(reg FLAGS_REG) (const_int 0)])
13945             (const_int 0)))]
13946   ""
13947   [(set (match_dup 0) (match_dup 1))]
13948 {
13949   rtx new_op1 = copy_rtx (operands[1]);
13950   operands[1] = new_op1;
13951   PUT_MODE (new_op1, QImode);
13952   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13953                                              GET_MODE (XEXP (new_op1, 0))));
13954
13955   /* Make sure that (a) the CCmode we have for the flags is strong
13956      enough for the reversed compare or (b) we have a valid FP compare.  */
13957   if (! ix86_comparison_operator (new_op1, VOIDmode))
13958     FAIL;
13959 })
13960
13961 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13962 ;; subsequent logical operations are used to imitate conditional moves.
13963 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13964 ;; it directly.
13965
13966 (define_insn "*sse_setcc<mode>"
13967   [(set (match_operand:MODEF 0 "register_operand" "=x")
13968         (match_operator:MODEF 1 "sse_comparison_operator"
13969           [(match_operand:MODEF 2 "register_operand" "0")
13970            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13971   "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
13972   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13973   [(set_attr "type" "ssecmp")
13974    (set_attr "mode" "<MODE>")])
13975
13976 (define_insn "*sse5_setcc<mode>"
13977   [(set (match_operand:MODEF 0 "register_operand" "=x")
13978         (match_operator:MODEF 1 "sse5_comparison_float_operator"
13979           [(match_operand:MODEF 2 "register_operand" "x")
13980            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13981   "TARGET_SSE5"
13982   "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13983   [(set_attr "type" "sse4arg")
13984    (set_attr "mode" "<MODE>")])
13985
13986 \f
13987 ;; Basic conditional jump instructions.
13988 ;; We ignore the overflow flag for signed branch instructions.
13989
13990 ;; For all bCOND expanders, also expand the compare or test insn that
13991 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13992
13993 (define_expand "beq"
13994   [(set (pc)
13995         (if_then_else (match_dup 1)
13996                       (label_ref (match_operand 0 "" ""))
13997                       (pc)))]
13998   ""
13999   "ix86_expand_branch (EQ, operands[0]); DONE;")
14000
14001 (define_expand "bne"
14002   [(set (pc)
14003         (if_then_else (match_dup 1)
14004                       (label_ref (match_operand 0 "" ""))
14005                       (pc)))]
14006   ""
14007   "ix86_expand_branch (NE, operands[0]); DONE;")
14008
14009 (define_expand "bgt"
14010   [(set (pc)
14011         (if_then_else (match_dup 1)
14012                       (label_ref (match_operand 0 "" ""))
14013                       (pc)))]
14014   ""
14015   "ix86_expand_branch (GT, operands[0]); DONE;")
14016
14017 (define_expand "bgtu"
14018   [(set (pc)
14019         (if_then_else (match_dup 1)
14020                       (label_ref (match_operand 0 "" ""))
14021                       (pc)))]
14022   ""
14023   "ix86_expand_branch (GTU, operands[0]); DONE;")
14024
14025 (define_expand "blt"
14026   [(set (pc)
14027         (if_then_else (match_dup 1)
14028                       (label_ref (match_operand 0 "" ""))
14029                       (pc)))]
14030   ""
14031   "ix86_expand_branch (LT, operands[0]); DONE;")
14032
14033 (define_expand "bltu"
14034   [(set (pc)
14035         (if_then_else (match_dup 1)
14036                       (label_ref (match_operand 0 "" ""))
14037                       (pc)))]
14038   ""
14039   "ix86_expand_branch (LTU, operands[0]); DONE;")
14040
14041 (define_expand "bge"
14042   [(set (pc)
14043         (if_then_else (match_dup 1)
14044                       (label_ref (match_operand 0 "" ""))
14045                       (pc)))]
14046   ""
14047   "ix86_expand_branch (GE, operands[0]); DONE;")
14048
14049 (define_expand "bgeu"
14050   [(set (pc)
14051         (if_then_else (match_dup 1)
14052                       (label_ref (match_operand 0 "" ""))
14053                       (pc)))]
14054   ""
14055   "ix86_expand_branch (GEU, operands[0]); DONE;")
14056
14057 (define_expand "ble"
14058   [(set (pc)
14059         (if_then_else (match_dup 1)
14060                       (label_ref (match_operand 0 "" ""))
14061                       (pc)))]
14062   ""
14063   "ix86_expand_branch (LE, operands[0]); DONE;")
14064
14065 (define_expand "bleu"
14066   [(set (pc)
14067         (if_then_else (match_dup 1)
14068                       (label_ref (match_operand 0 "" ""))
14069                       (pc)))]
14070   ""
14071   "ix86_expand_branch (LEU, operands[0]); DONE;")
14072
14073 (define_expand "bunordered"
14074   [(set (pc)
14075         (if_then_else (match_dup 1)
14076                       (label_ref (match_operand 0 "" ""))
14077                       (pc)))]
14078   "TARGET_80387 || TARGET_SSE_MATH"
14079   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
14080
14081 (define_expand "bordered"
14082   [(set (pc)
14083         (if_then_else (match_dup 1)
14084                       (label_ref (match_operand 0 "" ""))
14085                       (pc)))]
14086   "TARGET_80387 || TARGET_SSE_MATH"
14087   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
14088
14089 (define_expand "buneq"
14090   [(set (pc)
14091         (if_then_else (match_dup 1)
14092                       (label_ref (match_operand 0 "" ""))
14093                       (pc)))]
14094   "TARGET_80387 || TARGET_SSE_MATH"
14095   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
14096
14097 (define_expand "bunge"
14098   [(set (pc)
14099         (if_then_else (match_dup 1)
14100                       (label_ref (match_operand 0 "" ""))
14101                       (pc)))]
14102   "TARGET_80387 || TARGET_SSE_MATH"
14103   "ix86_expand_branch (UNGE, operands[0]); DONE;")
14104
14105 (define_expand "bungt"
14106   [(set (pc)
14107         (if_then_else (match_dup 1)
14108                       (label_ref (match_operand 0 "" ""))
14109                       (pc)))]
14110   "TARGET_80387 || TARGET_SSE_MATH"
14111   "ix86_expand_branch (UNGT, operands[0]); DONE;")
14112
14113 (define_expand "bunle"
14114   [(set (pc)
14115         (if_then_else (match_dup 1)
14116                       (label_ref (match_operand 0 "" ""))
14117                       (pc)))]
14118   "TARGET_80387 || TARGET_SSE_MATH"
14119   "ix86_expand_branch (UNLE, operands[0]); DONE;")
14120
14121 (define_expand "bunlt"
14122   [(set (pc)
14123         (if_then_else (match_dup 1)
14124                       (label_ref (match_operand 0 "" ""))
14125                       (pc)))]
14126   "TARGET_80387 || TARGET_SSE_MATH"
14127   "ix86_expand_branch (UNLT, operands[0]); DONE;")
14128
14129 (define_expand "bltgt"
14130   [(set (pc)
14131         (if_then_else (match_dup 1)
14132                       (label_ref (match_operand 0 "" ""))
14133                       (pc)))]
14134   "TARGET_80387 || TARGET_SSE_MATH"
14135   "ix86_expand_branch (LTGT, operands[0]); DONE;")
14136
14137 (define_insn "*jcc_1"
14138   [(set (pc)
14139         (if_then_else (match_operator 1 "ix86_comparison_operator"
14140                                       [(reg FLAGS_REG) (const_int 0)])
14141                       (label_ref (match_operand 0 "" ""))
14142                       (pc)))]
14143   ""
14144   "%+j%C1\t%l0"
14145   [(set_attr "type" "ibr")
14146    (set_attr "modrm" "0")
14147    (set (attr "length")
14148            (if_then_else (and (ge (minus (match_dup 0) (pc))
14149                                   (const_int -126))
14150                               (lt (minus (match_dup 0) (pc))
14151                                   (const_int 128)))
14152              (const_int 2)
14153              (const_int 6)))])
14154
14155 (define_insn "*jcc_2"
14156   [(set (pc)
14157         (if_then_else (match_operator 1 "ix86_comparison_operator"
14158                                       [(reg FLAGS_REG) (const_int 0)])
14159                       (pc)
14160                       (label_ref (match_operand 0 "" ""))))]
14161   ""
14162   "%+j%c1\t%l0"
14163   [(set_attr "type" "ibr")
14164    (set_attr "modrm" "0")
14165    (set (attr "length")
14166            (if_then_else (and (ge (minus (match_dup 0) (pc))
14167                                   (const_int -126))
14168                               (lt (minus (match_dup 0) (pc))
14169                                   (const_int 128)))
14170              (const_int 2)
14171              (const_int 6)))])
14172
14173 ;; In general it is not safe to assume too much about CCmode registers,
14174 ;; so simplify-rtx stops when it sees a second one.  Under certain
14175 ;; conditions this is safe on x86, so help combine not create
14176 ;;
14177 ;;      seta    %al
14178 ;;      testb   %al, %al
14179 ;;      je      Lfoo
14180
14181 (define_split
14182   [(set (pc)
14183         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14184                                       [(reg FLAGS_REG) (const_int 0)])
14185                           (const_int 0))
14186                       (label_ref (match_operand 1 "" ""))
14187                       (pc)))]
14188   ""
14189   [(set (pc)
14190         (if_then_else (match_dup 0)
14191                       (label_ref (match_dup 1))
14192                       (pc)))]
14193 {
14194   PUT_MODE (operands[0], VOIDmode);
14195 })
14196
14197 (define_split
14198   [(set (pc)
14199         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14200                                       [(reg FLAGS_REG) (const_int 0)])
14201                           (const_int 0))
14202                       (label_ref (match_operand 1 "" ""))
14203                       (pc)))]
14204   ""
14205   [(set (pc)
14206         (if_then_else (match_dup 0)
14207                       (label_ref (match_dup 1))
14208                       (pc)))]
14209 {
14210   rtx new_op0 = copy_rtx (operands[0]);
14211   operands[0] = new_op0;
14212   PUT_MODE (new_op0, VOIDmode);
14213   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14214                                              GET_MODE (XEXP (new_op0, 0))));
14215
14216   /* Make sure that (a) the CCmode we have for the flags is strong
14217      enough for the reversed compare or (b) we have a valid FP compare.  */
14218   if (! ix86_comparison_operator (new_op0, VOIDmode))
14219     FAIL;
14220 })
14221
14222 ;; Define combination compare-and-branch fp compare instructions to use
14223 ;; during early optimization.  Splitting the operation apart early makes
14224 ;; for bad code when we want to reverse the operation.
14225
14226 (define_insn "*fp_jcc_1_mixed"
14227   [(set (pc)
14228         (if_then_else (match_operator 0 "comparison_operator"
14229                         [(match_operand 1 "register_operand" "f,x")
14230                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14231           (label_ref (match_operand 3 "" ""))
14232           (pc)))
14233    (clobber (reg:CCFP FPSR_REG))
14234    (clobber (reg:CCFP FLAGS_REG))]
14235   "TARGET_MIX_SSE_I387
14236    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14237    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14238    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14239   "#")
14240
14241 (define_insn "*fp_jcc_1_sse"
14242   [(set (pc)
14243         (if_then_else (match_operator 0 "comparison_operator"
14244                         [(match_operand 1 "register_operand" "x")
14245                          (match_operand 2 "nonimmediate_operand" "xm")])
14246           (label_ref (match_operand 3 "" ""))
14247           (pc)))
14248    (clobber (reg:CCFP FPSR_REG))
14249    (clobber (reg:CCFP FLAGS_REG))]
14250   "TARGET_SSE_MATH
14251    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14252    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14253    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14254   "#")
14255
14256 (define_insn "*fp_jcc_1_387"
14257   [(set (pc)
14258         (if_then_else (match_operator 0 "comparison_operator"
14259                         [(match_operand 1 "register_operand" "f")
14260                          (match_operand 2 "register_operand" "f")])
14261           (label_ref (match_operand 3 "" ""))
14262           (pc)))
14263    (clobber (reg:CCFP FPSR_REG))
14264    (clobber (reg:CCFP FLAGS_REG))]
14265   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14266    && TARGET_CMOVE
14267    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14268    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14269   "#")
14270
14271 (define_insn "*fp_jcc_2_mixed"
14272   [(set (pc)
14273         (if_then_else (match_operator 0 "comparison_operator"
14274                         [(match_operand 1 "register_operand" "f,x")
14275                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14276           (pc)
14277           (label_ref (match_operand 3 "" ""))))
14278    (clobber (reg:CCFP FPSR_REG))
14279    (clobber (reg:CCFP FLAGS_REG))]
14280   "TARGET_MIX_SSE_I387
14281    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14282    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14283    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14284   "#")
14285
14286 (define_insn "*fp_jcc_2_sse"
14287   [(set (pc)
14288         (if_then_else (match_operator 0 "comparison_operator"
14289                         [(match_operand 1 "register_operand" "x")
14290                          (match_operand 2 "nonimmediate_operand" "xm")])
14291           (pc)
14292           (label_ref (match_operand 3 "" ""))))
14293    (clobber (reg:CCFP FPSR_REG))
14294    (clobber (reg:CCFP FLAGS_REG))]
14295   "TARGET_SSE_MATH
14296    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14297    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14298    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14299   "#")
14300
14301 (define_insn "*fp_jcc_2_387"
14302   [(set (pc)
14303         (if_then_else (match_operator 0 "comparison_operator"
14304                         [(match_operand 1 "register_operand" "f")
14305                          (match_operand 2 "register_operand" "f")])
14306           (pc)
14307           (label_ref (match_operand 3 "" ""))))
14308    (clobber (reg:CCFP FPSR_REG))
14309    (clobber (reg:CCFP FLAGS_REG))]
14310   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14311    && TARGET_CMOVE
14312    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14313    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14314   "#")
14315
14316 (define_insn "*fp_jcc_3_387"
14317   [(set (pc)
14318         (if_then_else (match_operator 0 "comparison_operator"
14319                         [(match_operand 1 "register_operand" "f")
14320                          (match_operand 2 "nonimmediate_operand" "fm")])
14321           (label_ref (match_operand 3 "" ""))
14322           (pc)))
14323    (clobber (reg:CCFP FPSR_REG))
14324    (clobber (reg:CCFP FLAGS_REG))
14325    (clobber (match_scratch:HI 4 "=a"))]
14326   "TARGET_80387
14327    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14328    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14329    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14330    && SELECT_CC_MODE (GET_CODE (operands[0]),
14331                       operands[1], operands[2]) == CCFPmode
14332    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14333   "#")
14334
14335 (define_insn "*fp_jcc_4_387"
14336   [(set (pc)
14337         (if_then_else (match_operator 0 "comparison_operator"
14338                         [(match_operand 1 "register_operand" "f")
14339                          (match_operand 2 "nonimmediate_operand" "fm")])
14340           (pc)
14341           (label_ref (match_operand 3 "" ""))))
14342    (clobber (reg:CCFP FPSR_REG))
14343    (clobber (reg:CCFP FLAGS_REG))
14344    (clobber (match_scratch:HI 4 "=a"))]
14345   "TARGET_80387
14346    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14347    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14348    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14349    && SELECT_CC_MODE (GET_CODE (operands[0]),
14350                       operands[1], operands[2]) == CCFPmode
14351    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14352   "#")
14353
14354 (define_insn "*fp_jcc_5_387"
14355   [(set (pc)
14356         (if_then_else (match_operator 0 "comparison_operator"
14357                         [(match_operand 1 "register_operand" "f")
14358                          (match_operand 2 "register_operand" "f")])
14359           (label_ref (match_operand 3 "" ""))
14360           (pc)))
14361    (clobber (reg:CCFP FPSR_REG))
14362    (clobber (reg:CCFP FLAGS_REG))
14363    (clobber (match_scratch:HI 4 "=a"))]
14364   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14365    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14366    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14367   "#")
14368
14369 (define_insn "*fp_jcc_6_387"
14370   [(set (pc)
14371         (if_then_else (match_operator 0 "comparison_operator"
14372                         [(match_operand 1 "register_operand" "f")
14373                          (match_operand 2 "register_operand" "f")])
14374           (pc)
14375           (label_ref (match_operand 3 "" ""))))
14376    (clobber (reg:CCFP FPSR_REG))
14377    (clobber (reg:CCFP FLAGS_REG))
14378    (clobber (match_scratch:HI 4 "=a"))]
14379   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14380    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14381    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14382   "#")
14383
14384 (define_insn "*fp_jcc_7_387"
14385   [(set (pc)
14386         (if_then_else (match_operator 0 "comparison_operator"
14387                         [(match_operand 1 "register_operand" "f")
14388                          (match_operand 2 "const0_operand" "X")])
14389           (label_ref (match_operand 3 "" ""))
14390           (pc)))
14391    (clobber (reg:CCFP FPSR_REG))
14392    (clobber (reg:CCFP FLAGS_REG))
14393    (clobber (match_scratch:HI 4 "=a"))]
14394   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14395    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14396    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14397    && SELECT_CC_MODE (GET_CODE (operands[0]),
14398                       operands[1], operands[2]) == CCFPmode
14399    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14400   "#")
14401
14402 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14403 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14404 ;; with a precedence over other operators and is always put in the first
14405 ;; place. Swap condition and operands to match ficom instruction.
14406
14407 (define_insn "*fp_jcc_8<mode>_387"
14408   [(set (pc)
14409         (if_then_else (match_operator 0 "comparison_operator"
14410                         [(match_operator 1 "float_operator"
14411                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14412                            (match_operand 3 "register_operand" "f,f")])
14413           (label_ref (match_operand 4 "" ""))
14414           (pc)))
14415    (clobber (reg:CCFP FPSR_REG))
14416    (clobber (reg:CCFP FLAGS_REG))
14417    (clobber (match_scratch:HI 5 "=a,a"))]
14418   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14419    && TARGET_USE_<MODE>MODE_FIOP
14420    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14421    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14422    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14423    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14424   "#")
14425
14426 (define_split
14427   [(set (pc)
14428         (if_then_else (match_operator 0 "comparison_operator"
14429                         [(match_operand 1 "register_operand" "")
14430                          (match_operand 2 "nonimmediate_operand" "")])
14431           (match_operand 3 "" "")
14432           (match_operand 4 "" "")))
14433    (clobber (reg:CCFP FPSR_REG))
14434    (clobber (reg:CCFP FLAGS_REG))]
14435   "reload_completed"
14436   [(const_int 0)]
14437 {
14438   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14439                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14440   DONE;
14441 })
14442
14443 (define_split
14444   [(set (pc)
14445         (if_then_else (match_operator 0 "comparison_operator"
14446                         [(match_operand 1 "register_operand" "")
14447                          (match_operand 2 "general_operand" "")])
14448           (match_operand 3 "" "")
14449           (match_operand 4 "" "")))
14450    (clobber (reg:CCFP FPSR_REG))
14451    (clobber (reg:CCFP FLAGS_REG))
14452    (clobber (match_scratch:HI 5 "=a"))]
14453   "reload_completed"
14454   [(const_int 0)]
14455 {
14456   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14457                         operands[3], operands[4], operands[5], NULL_RTX);
14458   DONE;
14459 })
14460
14461 (define_split
14462   [(set (pc)
14463         (if_then_else (match_operator 0 "comparison_operator"
14464                         [(match_operator 1 "float_operator"
14465                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14466                            (match_operand 3 "register_operand" "")])
14467           (match_operand 4 "" "")
14468           (match_operand 5 "" "")))
14469    (clobber (reg:CCFP FPSR_REG))
14470    (clobber (reg:CCFP FLAGS_REG))
14471    (clobber (match_scratch:HI 6 "=a"))]
14472   "reload_completed"
14473   [(const_int 0)]
14474 {
14475   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14476   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14477                         operands[3], operands[7],
14478                         operands[4], operands[5], operands[6], NULL_RTX);
14479   DONE;
14480 })
14481
14482 ;; %%% Kill this when reload knows how to do it.
14483 (define_split
14484   [(set (pc)
14485         (if_then_else (match_operator 0 "comparison_operator"
14486                         [(match_operator 1 "float_operator"
14487                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14488                            (match_operand 3 "register_operand" "")])
14489           (match_operand 4 "" "")
14490           (match_operand 5 "" "")))
14491    (clobber (reg:CCFP FPSR_REG))
14492    (clobber (reg:CCFP FLAGS_REG))
14493    (clobber (match_scratch:HI 6 "=a"))]
14494   "reload_completed"
14495   [(const_int 0)]
14496 {
14497   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14498   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14499   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14500                         operands[3], operands[7],
14501                         operands[4], operands[5], operands[6], operands[2]);
14502   DONE;
14503 })
14504 \f
14505 ;; Unconditional and other jump instructions
14506
14507 (define_insn "jump"
14508   [(set (pc)
14509         (label_ref (match_operand 0 "" "")))]
14510   ""
14511   "jmp\t%l0"
14512   [(set_attr "type" "ibr")
14513    (set (attr "length")
14514            (if_then_else (and (ge (minus (match_dup 0) (pc))
14515                                   (const_int -126))
14516                               (lt (minus (match_dup 0) (pc))
14517                                   (const_int 128)))
14518              (const_int 2)
14519              (const_int 5)))
14520    (set_attr "modrm" "0")])
14521
14522 (define_expand "indirect_jump"
14523   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14524   ""
14525   "")
14526
14527 (define_insn "*indirect_jump"
14528   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14529   "!TARGET_64BIT"
14530   "jmp\t%A0"
14531   [(set_attr "type" "ibr")
14532    (set_attr "length_immediate" "0")])
14533
14534 (define_insn "*indirect_jump_rtx64"
14535   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14536   "TARGET_64BIT"
14537   "jmp\t%A0"
14538   [(set_attr "type" "ibr")
14539    (set_attr "length_immediate" "0")])
14540
14541 (define_expand "tablejump"
14542   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14543               (use (label_ref (match_operand 1 "" "")))])]
14544   ""
14545 {
14546   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14547      relative.  Convert the relative address to an absolute address.  */
14548   if (flag_pic)
14549     {
14550       rtx op0, op1;
14551       enum rtx_code code;
14552
14553       /* We can't use @GOTOFF for text labels on VxWorks;
14554          see gotoff_operand.  */
14555       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14556         {
14557           code = PLUS;
14558           op0 = operands[0];
14559           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14560         }
14561       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14562         {
14563           code = PLUS;
14564           op0 = operands[0];
14565           op1 = pic_offset_table_rtx;
14566         }
14567       else
14568         {
14569           code = MINUS;
14570           op0 = pic_offset_table_rtx;
14571           op1 = operands[0];
14572         }
14573
14574       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14575                                          OPTAB_DIRECT);
14576     }
14577 })
14578
14579 (define_insn "*tablejump_1"
14580   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14581    (use (label_ref (match_operand 1 "" "")))]
14582   "!TARGET_64BIT"
14583   "jmp\t%A0"
14584   [(set_attr "type" "ibr")
14585    (set_attr "length_immediate" "0")])
14586
14587 (define_insn "*tablejump_1_rtx64"
14588   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14589    (use (label_ref (match_operand 1 "" "")))]
14590   "TARGET_64BIT"
14591   "jmp\t%A0"
14592   [(set_attr "type" "ibr")
14593    (set_attr "length_immediate" "0")])
14594 \f
14595 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14596
14597 (define_peephole2
14598   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14599    (set (match_operand:QI 1 "register_operand" "")
14600         (match_operator:QI 2 "ix86_comparison_operator"
14601           [(reg FLAGS_REG) (const_int 0)]))
14602    (set (match_operand 3 "q_regs_operand" "")
14603         (zero_extend (match_dup 1)))]
14604   "(peep2_reg_dead_p (3, operands[1])
14605     || operands_match_p (operands[1], operands[3]))
14606    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14607   [(set (match_dup 4) (match_dup 0))
14608    (set (strict_low_part (match_dup 5))
14609         (match_dup 2))]
14610 {
14611   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14612   operands[5] = gen_lowpart (QImode, operands[3]);
14613   ix86_expand_clear (operands[3]);
14614 })
14615
14616 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14617
14618 (define_peephole2
14619   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14620    (set (match_operand:QI 1 "register_operand" "")
14621         (match_operator:QI 2 "ix86_comparison_operator"
14622           [(reg FLAGS_REG) (const_int 0)]))
14623    (parallel [(set (match_operand 3 "q_regs_operand" "")
14624                    (zero_extend (match_dup 1)))
14625               (clobber (reg:CC FLAGS_REG))])]
14626   "(peep2_reg_dead_p (3, operands[1])
14627     || operands_match_p (operands[1], operands[3]))
14628    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14629   [(set (match_dup 4) (match_dup 0))
14630    (set (strict_low_part (match_dup 5))
14631         (match_dup 2))]
14632 {
14633   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14634   operands[5] = gen_lowpart (QImode, operands[3]);
14635   ix86_expand_clear (operands[3]);
14636 })
14637 \f
14638 ;; Call instructions.
14639
14640 ;; The predicates normally associated with named expanders are not properly
14641 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14642 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14643
14644 ;; Call subroutine returning no value.
14645
14646 (define_expand "call_pop"
14647   [(parallel [(call (match_operand:QI 0 "" "")
14648                     (match_operand:SI 1 "" ""))
14649               (set (reg:SI SP_REG)
14650                    (plus:SI (reg:SI SP_REG)
14651                             (match_operand:SI 3 "" "")))])]
14652   "!TARGET_64BIT"
14653 {
14654   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14655   DONE;
14656 })
14657
14658 (define_insn "*call_pop_0"
14659   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14660          (match_operand:SI 1 "" ""))
14661    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14662                             (match_operand:SI 2 "immediate_operand" "")))]
14663   "!TARGET_64BIT"
14664 {
14665   if (SIBLING_CALL_P (insn))
14666     return "jmp\t%P0";
14667   else
14668     return "call\t%P0";
14669 }
14670   [(set_attr "type" "call")])
14671
14672 (define_insn "*call_pop_1"
14673   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14674          (match_operand:SI 1 "" ""))
14675    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14676                             (match_operand:SI 2 "immediate_operand" "i")))]
14677   "!TARGET_64BIT"
14678 {
14679   if (constant_call_address_operand (operands[0], Pmode))
14680     {
14681       if (SIBLING_CALL_P (insn))
14682         return "jmp\t%P0";
14683       else
14684         return "call\t%P0";
14685     }
14686   if (SIBLING_CALL_P (insn))
14687     return "jmp\t%A0";
14688   else
14689     return "call\t%A0";
14690 }
14691   [(set_attr "type" "call")])
14692
14693 (define_expand "call"
14694   [(call (match_operand:QI 0 "" "")
14695          (match_operand 1 "" ""))
14696    (use (match_operand 2 "" ""))]
14697   ""
14698 {
14699   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14700   DONE;
14701 })
14702
14703 (define_expand "sibcall"
14704   [(call (match_operand:QI 0 "" "")
14705          (match_operand 1 "" ""))
14706    (use (match_operand 2 "" ""))]
14707   ""
14708 {
14709   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14710   DONE;
14711 })
14712
14713 (define_insn "*call_0"
14714   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14715          (match_operand 1 "" ""))]
14716   ""
14717 {
14718   if (SIBLING_CALL_P (insn))
14719     return "jmp\t%P0";
14720   else
14721     return "call\t%P0";
14722 }
14723   [(set_attr "type" "call")])
14724
14725 (define_insn "*call_1"
14726   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14727          (match_operand 1 "" ""))]
14728   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14729 {
14730   if (constant_call_address_operand (operands[0], Pmode))
14731     return "call\t%P0";
14732   return "call\t%A0";
14733 }
14734   [(set_attr "type" "call")])
14735
14736 (define_insn "*sibcall_1"
14737   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14738          (match_operand 1 "" ""))]
14739   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14740 {
14741   if (constant_call_address_operand (operands[0], Pmode))
14742     return "jmp\t%P0";
14743   return "jmp\t%A0";
14744 }
14745   [(set_attr "type" "call")])
14746
14747 (define_insn "*call_1_rex64"
14748   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14749          (match_operand 1 "" ""))]
14750   "!SIBLING_CALL_P (insn) && TARGET_64BIT
14751    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14752 {
14753   if (constant_call_address_operand (operands[0], Pmode))
14754     return "call\t%P0";
14755   return "call\t%A0";
14756 }
14757   [(set_attr "type" "call")])
14758
14759 (define_insn "*call_1_rex64_large"
14760   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14761          (match_operand 1 "" ""))]
14762   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14763   "call\t%A0"
14764   [(set_attr "type" "call")])
14765
14766 (define_insn "*sibcall_1_rex64"
14767   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14768          (match_operand 1 "" ""))]
14769   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14770   "jmp\t%P0"
14771   [(set_attr "type" "call")])
14772
14773 (define_insn "*sibcall_1_rex64_v"
14774   [(call (mem:QI (reg:DI R11_REG))
14775          (match_operand 0 "" ""))]
14776   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14777   "jmp\t{*%%}r11"
14778   [(set_attr "type" "call")])
14779
14780
14781 ;; Call subroutine, returning value in operand 0
14782
14783 (define_expand "call_value_pop"
14784   [(parallel [(set (match_operand 0 "" "")
14785                    (call (match_operand:QI 1 "" "")
14786                          (match_operand:SI 2 "" "")))
14787               (set (reg:SI SP_REG)
14788                    (plus:SI (reg:SI SP_REG)
14789                             (match_operand:SI 4 "" "")))])]
14790   "!TARGET_64BIT"
14791 {
14792   ix86_expand_call (operands[0], operands[1], operands[2],
14793                     operands[3], operands[4], 0);
14794   DONE;
14795 })
14796
14797 (define_expand "call_value"
14798   [(set (match_operand 0 "" "")
14799         (call (match_operand:QI 1 "" "")
14800               (match_operand:SI 2 "" "")))
14801    (use (match_operand:SI 3 "" ""))]
14802   ;; Operand 2 not used on the i386.
14803   ""
14804 {
14805   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14806   DONE;
14807 })
14808
14809 (define_expand "sibcall_value"
14810   [(set (match_operand 0 "" "")
14811         (call (match_operand:QI 1 "" "")
14812               (match_operand:SI 2 "" "")))
14813    (use (match_operand:SI 3 "" ""))]
14814   ;; Operand 2 not used on the i386.
14815   ""
14816 {
14817   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14818   DONE;
14819 })
14820
14821 ;; Call subroutine returning any type.
14822
14823 (define_expand "untyped_call"
14824   [(parallel [(call (match_operand 0 "" "")
14825                     (const_int 0))
14826               (match_operand 1 "" "")
14827               (match_operand 2 "" "")])]
14828   ""
14829 {
14830   int i;
14831
14832   /* In order to give reg-stack an easier job in validating two
14833      coprocessor registers as containing a possible return value,
14834      simply pretend the untyped call returns a complex long double
14835      value.  */
14836
14837   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14838                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14839                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14840                     NULL, 0);
14841
14842   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14843     {
14844       rtx set = XVECEXP (operands[2], 0, i);
14845       emit_move_insn (SET_DEST (set), SET_SRC (set));
14846     }
14847
14848   /* The optimizer does not know that the call sets the function value
14849      registers we stored in the result block.  We avoid problems by
14850      claiming that all hard registers are used and clobbered at this
14851      point.  */
14852   emit_insn (gen_blockage ());
14853
14854   DONE;
14855 })
14856 \f
14857 ;; Prologue and epilogue instructions
14858
14859 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14860 ;; all of memory.  This blocks insns from being moved across this point.
14861
14862 (define_insn "blockage"
14863   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14864   ""
14865   ""
14866   [(set_attr "length" "0")])
14867
14868 ;; As USE insns aren't meaningful after reload, this is used instead
14869 ;; to prevent deleting instructions setting registers for PIC code
14870 (define_insn "prologue_use"
14871   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14872   ""
14873   ""
14874   [(set_attr "length" "0")])
14875
14876 ;; Insn emitted into the body of a function to return from a function.
14877 ;; This is only done if the function's epilogue is known to be simple.
14878 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14879
14880 (define_expand "return"
14881   [(return)]
14882   "ix86_can_use_return_insn_p ()"
14883 {
14884   if (current_function_pops_args)
14885     {
14886       rtx popc = GEN_INT (current_function_pops_args);
14887       emit_jump_insn (gen_return_pop_internal (popc));
14888       DONE;
14889     }
14890 })
14891
14892 (define_insn "return_internal"
14893   [(return)]
14894   "reload_completed"
14895   "ret"
14896   [(set_attr "length" "1")
14897    (set_attr "length_immediate" "0")
14898    (set_attr "modrm" "0")])
14899
14900 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14901 ;; instruction Athlon and K8 have.
14902
14903 (define_insn "return_internal_long"
14904   [(return)
14905    (unspec [(const_int 0)] UNSPEC_REP)]
14906   "reload_completed"
14907   "rep\;ret"
14908   [(set_attr "length" "1")
14909    (set_attr "length_immediate" "0")
14910    (set_attr "prefix_rep" "1")
14911    (set_attr "modrm" "0")])
14912
14913 (define_insn "return_pop_internal"
14914   [(return)
14915    (use (match_operand:SI 0 "const_int_operand" ""))]
14916   "reload_completed"
14917   "ret\t%0"
14918   [(set_attr "length" "3")
14919    (set_attr "length_immediate" "2")
14920    (set_attr "modrm" "0")])
14921
14922 (define_insn "return_indirect_internal"
14923   [(return)
14924    (use (match_operand:SI 0 "register_operand" "r"))]
14925   "reload_completed"
14926   "jmp\t%A0"
14927   [(set_attr "type" "ibr")
14928    (set_attr "length_immediate" "0")])
14929
14930 (define_insn "nop"
14931   [(const_int 0)]
14932   ""
14933   "nop"
14934   [(set_attr "length" "1")
14935    (set_attr "length_immediate" "0")
14936    (set_attr "modrm" "0")])
14937
14938 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14939 ;; branch prediction penalty for the third jump in a 16-byte
14940 ;; block on K8.
14941
14942 (define_insn "align"
14943   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14944   ""
14945 {
14946 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14947   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14948 #else
14949   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14950      The align insn is used to avoid 3 jump instructions in the row to improve
14951      branch prediction and the benefits hardly outweigh the cost of extra 8
14952      nops on the average inserted by full alignment pseudo operation.  */
14953 #endif
14954   return "";
14955 }
14956   [(set_attr "length" "16")])
14957
14958 (define_expand "prologue"
14959   [(const_int 0)]
14960   ""
14961   "ix86_expand_prologue (); DONE;")
14962
14963 (define_insn "set_got"
14964   [(set (match_operand:SI 0 "register_operand" "=r")
14965         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14966    (clobber (reg:CC FLAGS_REG))]
14967   "!TARGET_64BIT"
14968   { return output_set_got (operands[0], NULL_RTX); }
14969   [(set_attr "type" "multi")
14970    (set_attr "length" "12")])
14971
14972 (define_insn "set_got_labelled"
14973   [(set (match_operand:SI 0 "register_operand" "=r")
14974         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14975          UNSPEC_SET_GOT))
14976    (clobber (reg:CC FLAGS_REG))]
14977   "!TARGET_64BIT"
14978   { return output_set_got (operands[0], operands[1]); }
14979   [(set_attr "type" "multi")
14980    (set_attr "length" "12")])
14981
14982 (define_insn "set_got_rex64"
14983   [(set (match_operand:DI 0 "register_operand" "=r")
14984         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14985   "TARGET_64BIT"
14986   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14987   [(set_attr "type" "lea")
14988    (set_attr "length" "6")])
14989
14990 (define_insn "set_rip_rex64"
14991   [(set (match_operand:DI 0 "register_operand" "=r")
14992         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14993   "TARGET_64BIT"
14994   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
14995   [(set_attr "type" "lea")
14996    (set_attr "length" "6")])
14997
14998 (define_insn "set_got_offset_rex64"
14999   [(set (match_operand:DI 0 "register_operand" "=r")
15000         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
15001   "TARGET_64BIT"
15002   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15003   [(set_attr "type" "imov")
15004    (set_attr "length" "11")])
15005
15006 (define_expand "epilogue"
15007   [(const_int 0)]
15008   ""
15009   "ix86_expand_epilogue (1); DONE;")
15010
15011 (define_expand "sibcall_epilogue"
15012   [(const_int 0)]
15013   ""
15014   "ix86_expand_epilogue (0); DONE;")
15015
15016 (define_expand "eh_return"
15017   [(use (match_operand 0 "register_operand" ""))]
15018   ""
15019 {
15020   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15021
15022   /* Tricky bit: we write the address of the handler to which we will
15023      be returning into someone else's stack frame, one word below the
15024      stack address we wish to restore.  */
15025   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15026   tmp = plus_constant (tmp, -UNITS_PER_WORD);
15027   tmp = gen_rtx_MEM (Pmode, tmp);
15028   emit_move_insn (tmp, ra);
15029
15030   if (Pmode == SImode)
15031     emit_jump_insn (gen_eh_return_si (sa));
15032   else
15033     emit_jump_insn (gen_eh_return_di (sa));
15034   emit_barrier ();
15035   DONE;
15036 })
15037
15038 (define_insn_and_split "eh_return_si"
15039   [(set (pc)
15040         (unspec [(match_operand:SI 0 "register_operand" "c")]
15041                  UNSPEC_EH_RETURN))]
15042   "!TARGET_64BIT"
15043   "#"
15044   "reload_completed"
15045   [(const_int 0)]
15046   "ix86_expand_epilogue (2); DONE;")
15047
15048 (define_insn_and_split "eh_return_di"
15049   [(set (pc)
15050         (unspec [(match_operand:DI 0 "register_operand" "c")]
15051                  UNSPEC_EH_RETURN))]
15052   "TARGET_64BIT"
15053   "#"
15054   "reload_completed"
15055   [(const_int 0)]
15056   "ix86_expand_epilogue (2); DONE;")
15057
15058 (define_insn "leave"
15059   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15060    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15061    (clobber (mem:BLK (scratch)))]
15062   "!TARGET_64BIT"
15063   "leave"
15064   [(set_attr "type" "leave")])
15065
15066 (define_insn "leave_rex64"
15067   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15068    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15069    (clobber (mem:BLK (scratch)))]
15070   "TARGET_64BIT"
15071   "leave"
15072   [(set_attr "type" "leave")])
15073 \f
15074 (define_expand "ffssi2"
15075   [(parallel
15076      [(set (match_operand:SI 0 "register_operand" "")
15077            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15078       (clobber (match_scratch:SI 2 ""))
15079       (clobber (reg:CC FLAGS_REG))])]
15080   ""
15081 {
15082   if (TARGET_CMOVE)
15083     {
15084       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15085       DONE;
15086     }
15087 })
15088
15089 (define_expand "ffs_cmove"
15090   [(set (match_dup 2) (const_int -1))
15091    (parallel [(set (reg:CCZ FLAGS_REG)
15092                    (compare:CCZ (match_operand:SI 1 "register_operand" "")
15093                                 (const_int 0)))
15094               (set (match_operand:SI 0 "nonimmediate_operand" "")
15095                    (ctz:SI (match_dup 1)))])
15096    (set (match_dup 0) (if_then_else:SI
15097                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15098                         (match_dup 2)
15099                         (match_dup 0)))
15100    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15101               (clobber (reg:CC FLAGS_REG))])]
15102   "TARGET_CMOVE"
15103   "operands[2] = gen_reg_rtx (SImode);")
15104
15105 (define_insn_and_split "*ffs_no_cmove"
15106   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
15107         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15108    (clobber (match_scratch:SI 2 "=&q"))
15109    (clobber (reg:CC FLAGS_REG))]
15110   "!TARGET_CMOVE"
15111   "#"
15112   "&& reload_completed"
15113   [(parallel [(set (reg:CCZ FLAGS_REG)
15114                    (compare:CCZ (match_dup 1) (const_int 0)))
15115               (set (match_dup 0) (ctz:SI (match_dup 1)))])
15116    (set (strict_low_part (match_dup 3))
15117         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15118    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15119               (clobber (reg:CC FLAGS_REG))])
15120    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15121               (clobber (reg:CC FLAGS_REG))])
15122    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15123               (clobber (reg:CC FLAGS_REG))])]
15124 {
15125   operands[3] = gen_lowpart (QImode, operands[2]);
15126   ix86_expand_clear (operands[2]);
15127 })
15128
15129 (define_insn "*ffssi_1"
15130   [(set (reg:CCZ FLAGS_REG)
15131         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15132                      (const_int 0)))
15133    (set (match_operand:SI 0 "register_operand" "=r")
15134         (ctz:SI (match_dup 1)))]
15135   ""
15136   "bsf{l}\t{%1, %0|%0, %1}"
15137   [(set_attr "prefix_0f" "1")])
15138
15139 (define_expand "ffsdi2"
15140   [(set (match_dup 2) (const_int -1))
15141    (parallel [(set (reg:CCZ FLAGS_REG)
15142                    (compare:CCZ (match_operand:DI 1 "register_operand" "")
15143                                 (const_int 0)))
15144               (set (match_operand:DI 0 "nonimmediate_operand" "")
15145                    (ctz:DI (match_dup 1)))])
15146    (set (match_dup 0) (if_then_else:DI
15147                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15148                         (match_dup 2)
15149                         (match_dup 0)))
15150    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15151               (clobber (reg:CC FLAGS_REG))])]
15152   "TARGET_64BIT"
15153   "operands[2] = gen_reg_rtx (DImode);")
15154
15155 (define_insn "*ffsdi_1"
15156   [(set (reg:CCZ FLAGS_REG)
15157         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15158                      (const_int 0)))
15159    (set (match_operand:DI 0 "register_operand" "=r")
15160         (ctz:DI (match_dup 1)))]
15161   "TARGET_64BIT"
15162   "bsf{q}\t{%1, %0|%0, %1}"
15163   [(set_attr "prefix_0f" "1")])
15164
15165 (define_insn "ctzsi2"
15166   [(set (match_operand:SI 0 "register_operand" "=r")
15167         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15168    (clobber (reg:CC FLAGS_REG))]
15169   ""
15170   "bsf{l}\t{%1, %0|%0, %1}"
15171   [(set_attr "prefix_0f" "1")])
15172
15173 (define_insn "ctzdi2"
15174   [(set (match_operand:DI 0 "register_operand" "=r")
15175         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15176    (clobber (reg:CC FLAGS_REG))]
15177   "TARGET_64BIT"
15178   "bsf{q}\t{%1, %0|%0, %1}"
15179   [(set_attr "prefix_0f" "1")])
15180
15181 (define_expand "clzsi2"
15182   [(parallel
15183      [(set (match_operand:SI 0 "register_operand" "")
15184            (minus:SI (const_int 31)
15185                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15186       (clobber (reg:CC FLAGS_REG))])
15187    (parallel
15188      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15189       (clobber (reg:CC FLAGS_REG))])]
15190   ""
15191 {
15192   if (TARGET_ABM)
15193     {
15194       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15195       DONE;
15196     }
15197 })
15198
15199 (define_insn "clzsi2_abm"
15200   [(set (match_operand:SI 0 "register_operand" "=r")
15201         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15202    (clobber (reg:CC FLAGS_REG))]
15203   "TARGET_ABM"
15204   "lzcnt{l}\t{%1, %0|%0, %1}"
15205   [(set_attr "prefix_rep" "1")
15206    (set_attr "type" "bitmanip")
15207    (set_attr "mode" "SI")])
15208
15209 (define_insn "*bsr"
15210   [(set (match_operand:SI 0 "register_operand" "=r")
15211         (minus:SI (const_int 31)
15212                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15213    (clobber (reg:CC FLAGS_REG))]
15214   ""
15215   "bsr{l}\t{%1, %0|%0, %1}"
15216   [(set_attr "prefix_0f" "1")
15217    (set_attr "mode" "SI")])
15218
15219 (define_insn "popcountsi2"
15220   [(set (match_operand:SI 0 "register_operand" "=r")
15221         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15222    (clobber (reg:CC FLAGS_REG))]
15223   "TARGET_POPCNT"
15224   "popcnt{l}\t{%1, %0|%0, %1}"
15225   [(set_attr "prefix_rep" "1")
15226    (set_attr "type" "bitmanip")
15227    (set_attr "mode" "SI")])
15228
15229 (define_insn "*popcountsi2_cmp"
15230   [(set (reg FLAGS_REG)
15231         (compare
15232           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15233           (const_int 0)))
15234    (set (match_operand:SI 0 "register_operand" "=r")
15235         (popcount:SI (match_dup 1)))]
15236   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15237   "popcnt{l}\t{%1, %0|%0, %1}"
15238   [(set_attr "prefix_rep" "1")
15239    (set_attr "type" "bitmanip")
15240    (set_attr "mode" "SI")])
15241
15242 (define_insn "*popcountsi2_cmp_zext"
15243   [(set (reg FLAGS_REG)
15244         (compare
15245           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15246           (const_int 0)))
15247    (set (match_operand:DI 0 "register_operand" "=r")
15248         (zero_extend:DI(popcount:SI (match_dup 1))))]
15249   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15250   "popcnt{l}\t{%1, %0|%0, %1}"
15251   [(set_attr "prefix_rep" "1")
15252    (set_attr "type" "bitmanip")
15253    (set_attr "mode" "SI")])
15254
15255 (define_expand "bswapsi2"
15256   [(set (match_operand:SI 0 "register_operand" "")
15257         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15258   ""
15259 {
15260   if (!TARGET_BSWAP)
15261     {
15262       rtx x = operands[0];
15263
15264       emit_move_insn (x, operands[1]);
15265       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15266       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15267       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15268       DONE;
15269     }
15270 })
15271
15272 (define_insn "*bswapsi_1"
15273   [(set (match_operand:SI 0 "register_operand" "=r")
15274         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15275   "TARGET_BSWAP"
15276   "bswap\t%0"
15277   [(set_attr "prefix_0f" "1")
15278    (set_attr "length" "2")])
15279
15280 (define_insn "*bswaphi_lowpart_1"
15281   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15282         (bswap:HI (match_dup 0)))
15283    (clobber (reg:CC FLAGS_REG))]
15284   "TARGET_USE_XCHGB || optimize_size"
15285   "@
15286     xchg{b}\t{%h0, %b0|%b0, %h0}
15287     rol{w}\t{$8, %0|%0, 8}"
15288   [(set_attr "length" "2,4")
15289    (set_attr "mode" "QI,HI")])
15290
15291 (define_insn "bswaphi_lowpart"
15292   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15293         (bswap:HI (match_dup 0)))
15294    (clobber (reg:CC FLAGS_REG))]
15295   ""
15296   "rol{w}\t{$8, %0|%0, 8}"
15297   [(set_attr "length" "4")
15298    (set_attr "mode" "HI")])
15299
15300 (define_insn "bswapdi2"
15301   [(set (match_operand:DI 0 "register_operand" "=r")
15302         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15303   "TARGET_64BIT"
15304   "bswap\t%0"
15305   [(set_attr "prefix_0f" "1")
15306    (set_attr "length" "3")])
15307
15308 (define_expand "clzdi2"
15309   [(parallel
15310      [(set (match_operand:DI 0 "register_operand" "")
15311            (minus:DI (const_int 63)
15312                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15313       (clobber (reg:CC FLAGS_REG))])
15314    (parallel
15315      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15316       (clobber (reg:CC FLAGS_REG))])]
15317   "TARGET_64BIT"
15318 {
15319   if (TARGET_ABM)
15320     {
15321       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15322       DONE;
15323     }
15324 })
15325
15326 (define_insn "clzdi2_abm"
15327   [(set (match_operand:DI 0 "register_operand" "=r")
15328         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15329    (clobber (reg:CC FLAGS_REG))]
15330   "TARGET_64BIT && TARGET_ABM"
15331   "lzcnt{q}\t{%1, %0|%0, %1}"
15332   [(set_attr "prefix_rep" "1")
15333    (set_attr "type" "bitmanip")
15334    (set_attr "mode" "DI")])
15335
15336 (define_insn "*bsr_rex64"
15337   [(set (match_operand:DI 0 "register_operand" "=r")
15338         (minus:DI (const_int 63)
15339                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15340    (clobber (reg:CC FLAGS_REG))]
15341   "TARGET_64BIT"
15342   "bsr{q}\t{%1, %0|%0, %1}"
15343   [(set_attr "prefix_0f" "1")
15344    (set_attr "mode" "DI")])
15345
15346 (define_insn "popcountdi2"
15347   [(set (match_operand:DI 0 "register_operand" "=r")
15348         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15349    (clobber (reg:CC FLAGS_REG))]
15350   "TARGET_64BIT && TARGET_POPCNT"
15351   "popcnt{q}\t{%1, %0|%0, %1}"
15352   [(set_attr "prefix_rep" "1")
15353    (set_attr "type" "bitmanip")
15354    (set_attr "mode" "DI")])
15355
15356 (define_insn "*popcountdi2_cmp"
15357   [(set (reg FLAGS_REG)
15358         (compare
15359           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15360           (const_int 0)))
15361    (set (match_operand:DI 0 "register_operand" "=r")
15362         (popcount:DI (match_dup 1)))]
15363   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15364   "popcnt{q}\t{%1, %0|%0, %1}"
15365   [(set_attr "prefix_rep" "1")
15366    (set_attr "type" "bitmanip")
15367    (set_attr "mode" "DI")])
15368
15369 (define_expand "clzhi2"
15370   [(parallel
15371      [(set (match_operand:HI 0 "register_operand" "")
15372            (minus:HI (const_int 15)
15373                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15374       (clobber (reg:CC FLAGS_REG))])
15375    (parallel
15376      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15377       (clobber (reg:CC FLAGS_REG))])]
15378   ""
15379 {
15380   if (TARGET_ABM)
15381     {
15382       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15383       DONE;
15384     }
15385 })
15386
15387 (define_insn "clzhi2_abm"
15388   [(set (match_operand:HI 0 "register_operand" "=r")
15389         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15390    (clobber (reg:CC FLAGS_REG))]
15391   "TARGET_ABM"
15392   "lzcnt{w}\t{%1, %0|%0, %1}"
15393   [(set_attr "prefix_rep" "1")
15394    (set_attr "type" "bitmanip")
15395    (set_attr "mode" "HI")])
15396
15397 (define_insn "*bsrhi"
15398   [(set (match_operand:HI 0 "register_operand" "=r")
15399         (minus:HI (const_int 15)
15400                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15401    (clobber (reg:CC FLAGS_REG))]
15402   ""
15403   "bsr{w}\t{%1, %0|%0, %1}"
15404   [(set_attr "prefix_0f" "1")
15405    (set_attr "mode" "HI")])
15406
15407 (define_insn "popcounthi2"
15408   [(set (match_operand:HI 0 "register_operand" "=r")
15409         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15410    (clobber (reg:CC FLAGS_REG))]
15411   "TARGET_POPCNT"
15412   "popcnt{w}\t{%1, %0|%0, %1}"
15413   [(set_attr "prefix_rep" "1")
15414    (set_attr "type" "bitmanip")
15415    (set_attr "mode" "HI")])
15416
15417 (define_insn "*popcounthi2_cmp"
15418   [(set (reg FLAGS_REG)
15419         (compare
15420           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15421           (const_int 0)))
15422    (set (match_operand:HI 0 "register_operand" "=r")
15423         (popcount:HI (match_dup 1)))]
15424   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15425   "popcnt{w}\t{%1, %0|%0, %1}"
15426   [(set_attr "prefix_rep" "1")
15427    (set_attr "type" "bitmanip")
15428    (set_attr "mode" "HI")])
15429
15430 (define_expand "paritydi2"
15431   [(set (match_operand:DI 0 "register_operand" "")
15432         (parity:DI (match_operand:DI 1 "register_operand" "")))]
15433   "! TARGET_POPCNT"
15434 {
15435   rtx scratch = gen_reg_rtx (QImode);
15436   rtx cond;
15437
15438   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15439                                 NULL_RTX, operands[1]));
15440
15441   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15442                          gen_rtx_REG (CCmode, FLAGS_REG),
15443                          const0_rtx);
15444   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15445
15446   if (TARGET_64BIT)
15447     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15448   else
15449     {
15450       rtx tmp = gen_reg_rtx (SImode);
15451
15452       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15453       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15454     }
15455   DONE;
15456 })
15457
15458 (define_insn_and_split "paritydi2_cmp"
15459   [(set (reg:CC FLAGS_REG)
15460         (parity:CC (match_operand:DI 3 "register_operand" "0")))
15461    (clobber (match_scratch:DI 0 "=r"))
15462    (clobber (match_scratch:SI 1 "=&r"))
15463    (clobber (match_scratch:HI 2 "=Q"))]
15464   "! TARGET_POPCNT"
15465   "#"
15466   "&& reload_completed"
15467   [(parallel
15468      [(set (match_dup 1)
15469            (xor:SI (match_dup 1) (match_dup 4)))
15470       (clobber (reg:CC FLAGS_REG))])
15471    (parallel
15472      [(set (reg:CC FLAGS_REG)
15473            (parity:CC (match_dup 1)))
15474       (clobber (match_dup 1))
15475       (clobber (match_dup 2))])]
15476 {
15477   operands[4] = gen_lowpart (SImode, operands[3]);
15478
15479   if (TARGET_64BIT)
15480     {
15481       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15482       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15483     }
15484   else
15485     operands[1] = gen_highpart (SImode, operands[3]);
15486 })
15487
15488 (define_expand "paritysi2"
15489   [(set (match_operand:SI 0 "register_operand" "")
15490         (parity:SI (match_operand:SI 1 "register_operand" "")))]
15491   "! TARGET_POPCNT"
15492 {
15493   rtx scratch = gen_reg_rtx (QImode);
15494   rtx cond;
15495
15496   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15497
15498   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15499                          gen_rtx_REG (CCmode, FLAGS_REG),
15500                          const0_rtx);
15501   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15502
15503   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15504   DONE;
15505 })
15506
15507 (define_insn_and_split "paritysi2_cmp"
15508   [(set (reg:CC FLAGS_REG)
15509         (parity:CC (match_operand:SI 2 "register_operand" "0")))
15510    (clobber (match_scratch:SI 0 "=r"))
15511    (clobber (match_scratch:HI 1 "=&Q"))]
15512   "! TARGET_POPCNT"
15513   "#"
15514   "&& reload_completed"
15515   [(parallel
15516      [(set (match_dup 1)
15517            (xor:HI (match_dup 1) (match_dup 3)))
15518       (clobber (reg:CC FLAGS_REG))])
15519    (parallel
15520      [(set (reg:CC FLAGS_REG)
15521            (parity:CC (match_dup 1)))
15522       (clobber (match_dup 1))])]
15523 {
15524   operands[3] = gen_lowpart (HImode, operands[2]);
15525
15526   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15527   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15528 })
15529
15530 (define_insn "*parityhi2_cmp"
15531   [(set (reg:CC FLAGS_REG)
15532         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15533    (clobber (match_scratch:HI 0 "=Q"))]
15534   "! TARGET_POPCNT"
15535   "xor{b}\t{%h0, %b0|%b0, %h0}"
15536   [(set_attr "length" "2")
15537    (set_attr "mode" "HI")])
15538
15539 (define_insn "*parityqi2_cmp"
15540   [(set (reg:CC FLAGS_REG)
15541         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15542   "! TARGET_POPCNT"
15543   "test{b}\t%0, %0"
15544   [(set_attr "length" "2")
15545    (set_attr "mode" "QI")])
15546 \f
15547 ;; Thread-local storage patterns for ELF.
15548 ;;
15549 ;; Note that these code sequences must appear exactly as shown
15550 ;; in order to allow linker relaxation.
15551
15552 (define_insn "*tls_global_dynamic_32_gnu"
15553   [(set (match_operand:SI 0 "register_operand" "=a")
15554         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15555                     (match_operand:SI 2 "tls_symbolic_operand" "")
15556                     (match_operand:SI 3 "call_insn_operand" "")]
15557                     UNSPEC_TLS_GD))
15558    (clobber (match_scratch:SI 4 "=d"))
15559    (clobber (match_scratch:SI 5 "=c"))
15560    (clobber (reg:CC FLAGS_REG))]
15561   "!TARGET_64BIT && TARGET_GNU_TLS"
15562   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15563   [(set_attr "type" "multi")
15564    (set_attr "length" "12")])
15565
15566 (define_insn "*tls_global_dynamic_32_sun"
15567   [(set (match_operand:SI 0 "register_operand" "=a")
15568         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15569                     (match_operand:SI 2 "tls_symbolic_operand" "")
15570                     (match_operand:SI 3 "call_insn_operand" "")]
15571                     UNSPEC_TLS_GD))
15572    (clobber (match_scratch:SI 4 "=d"))
15573    (clobber (match_scratch:SI 5 "=c"))
15574    (clobber (reg:CC FLAGS_REG))]
15575   "!TARGET_64BIT && TARGET_SUN_TLS"
15576   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15577         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15578   [(set_attr "type" "multi")
15579    (set_attr "length" "14")])
15580
15581 (define_expand "tls_global_dynamic_32"
15582   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15583                    (unspec:SI
15584                     [(match_dup 2)
15585                      (match_operand:SI 1 "tls_symbolic_operand" "")
15586                      (match_dup 3)]
15587                     UNSPEC_TLS_GD))
15588               (clobber (match_scratch:SI 4 ""))
15589               (clobber (match_scratch:SI 5 ""))
15590               (clobber (reg:CC FLAGS_REG))])]
15591   ""
15592 {
15593   if (flag_pic)
15594     operands[2] = pic_offset_table_rtx;
15595   else
15596     {
15597       operands[2] = gen_reg_rtx (Pmode);
15598       emit_insn (gen_set_got (operands[2]));
15599     }
15600   if (TARGET_GNU2_TLS)
15601     {
15602        emit_insn (gen_tls_dynamic_gnu2_32
15603                   (operands[0], operands[1], operands[2]));
15604        DONE;
15605     }
15606   operands[3] = ix86_tls_get_addr ();
15607 })
15608
15609 (define_insn "*tls_global_dynamic_64"
15610   [(set (match_operand:DI 0 "register_operand" "=a")
15611         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15612                  (match_operand:DI 3 "" "")))
15613    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15614               UNSPEC_TLS_GD)]
15615   "TARGET_64BIT"
15616   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15617   [(set_attr "type" "multi")
15618    (set_attr "length" "16")])
15619
15620 (define_expand "tls_global_dynamic_64"
15621   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15622                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15623               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15624                          UNSPEC_TLS_GD)])]
15625   ""
15626 {
15627   if (TARGET_GNU2_TLS)
15628     {
15629        emit_insn (gen_tls_dynamic_gnu2_64
15630                   (operands[0], operands[1]));
15631        DONE;
15632     }
15633   operands[2] = ix86_tls_get_addr ();
15634 })
15635
15636 (define_insn "*tls_local_dynamic_base_32_gnu"
15637   [(set (match_operand:SI 0 "register_operand" "=a")
15638         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15639                     (match_operand:SI 2 "call_insn_operand" "")]
15640                    UNSPEC_TLS_LD_BASE))
15641    (clobber (match_scratch:SI 3 "=d"))
15642    (clobber (match_scratch:SI 4 "=c"))
15643    (clobber (reg:CC FLAGS_REG))]
15644   "!TARGET_64BIT && TARGET_GNU_TLS"
15645   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15646   [(set_attr "type" "multi")
15647    (set_attr "length" "11")])
15648
15649 (define_insn "*tls_local_dynamic_base_32_sun"
15650   [(set (match_operand:SI 0 "register_operand" "=a")
15651         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15652                     (match_operand:SI 2 "call_insn_operand" "")]
15653                    UNSPEC_TLS_LD_BASE))
15654    (clobber (match_scratch:SI 3 "=d"))
15655    (clobber (match_scratch:SI 4 "=c"))
15656    (clobber (reg:CC FLAGS_REG))]
15657   "!TARGET_64BIT && TARGET_SUN_TLS"
15658   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15659         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15660   [(set_attr "type" "multi")
15661    (set_attr "length" "13")])
15662
15663 (define_expand "tls_local_dynamic_base_32"
15664   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15665                    (unspec:SI [(match_dup 1) (match_dup 2)]
15666                               UNSPEC_TLS_LD_BASE))
15667               (clobber (match_scratch:SI 3 ""))
15668               (clobber (match_scratch:SI 4 ""))
15669               (clobber (reg:CC FLAGS_REG))])]
15670   ""
15671 {
15672   if (flag_pic)
15673     operands[1] = pic_offset_table_rtx;
15674   else
15675     {
15676       operands[1] = gen_reg_rtx (Pmode);
15677       emit_insn (gen_set_got (operands[1]));
15678     }
15679   if (TARGET_GNU2_TLS)
15680     {
15681        emit_insn (gen_tls_dynamic_gnu2_32
15682                   (operands[0], ix86_tls_module_base (), operands[1]));
15683        DONE;
15684     }
15685   operands[2] = ix86_tls_get_addr ();
15686 })
15687
15688 (define_insn "*tls_local_dynamic_base_64"
15689   [(set (match_operand:DI 0 "register_operand" "=a")
15690         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15691                  (match_operand:DI 2 "" "")))
15692    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15693   "TARGET_64BIT"
15694   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15695   [(set_attr "type" "multi")
15696    (set_attr "length" "12")])
15697
15698 (define_expand "tls_local_dynamic_base_64"
15699   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15700                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15701               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15702   ""
15703 {
15704   if (TARGET_GNU2_TLS)
15705     {
15706        emit_insn (gen_tls_dynamic_gnu2_64
15707                   (operands[0], ix86_tls_module_base ()));
15708        DONE;
15709     }
15710   operands[1] = ix86_tls_get_addr ();
15711 })
15712
15713 ;; Local dynamic of a single variable is a lose.  Show combine how
15714 ;; to convert that back to global dynamic.
15715
15716 (define_insn_and_split "*tls_local_dynamic_32_once"
15717   [(set (match_operand:SI 0 "register_operand" "=a")
15718         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15719                              (match_operand:SI 2 "call_insn_operand" "")]
15720                             UNSPEC_TLS_LD_BASE)
15721                  (const:SI (unspec:SI
15722                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15723                             UNSPEC_DTPOFF))))
15724    (clobber (match_scratch:SI 4 "=d"))
15725    (clobber (match_scratch:SI 5 "=c"))
15726    (clobber (reg:CC FLAGS_REG))]
15727   ""
15728   "#"
15729   ""
15730   [(parallel [(set (match_dup 0)
15731                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15732                               UNSPEC_TLS_GD))
15733               (clobber (match_dup 4))
15734               (clobber (match_dup 5))
15735               (clobber (reg:CC FLAGS_REG))])]
15736   "")
15737
15738 ;; Load and add the thread base pointer from %gs:0.
15739
15740 (define_insn "*load_tp_si"
15741   [(set (match_operand:SI 0 "register_operand" "=r")
15742         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15743   "!TARGET_64BIT"
15744   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15745   [(set_attr "type" "imov")
15746    (set_attr "modrm" "0")
15747    (set_attr "length" "7")
15748    (set_attr "memory" "load")
15749    (set_attr "imm_disp" "false")])
15750
15751 (define_insn "*add_tp_si"
15752   [(set (match_operand:SI 0 "register_operand" "=r")
15753         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15754                  (match_operand:SI 1 "register_operand" "0")))
15755    (clobber (reg:CC FLAGS_REG))]
15756   "!TARGET_64BIT"
15757   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15758   [(set_attr "type" "alu")
15759    (set_attr "modrm" "0")
15760    (set_attr "length" "7")
15761    (set_attr "memory" "load")
15762    (set_attr "imm_disp" "false")])
15763
15764 (define_insn "*load_tp_di"
15765   [(set (match_operand:DI 0 "register_operand" "=r")
15766         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15767   "TARGET_64BIT"
15768   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15769   [(set_attr "type" "imov")
15770    (set_attr "modrm" "0")
15771    (set_attr "length" "7")
15772    (set_attr "memory" "load")
15773    (set_attr "imm_disp" "false")])
15774
15775 (define_insn "*add_tp_di"
15776   [(set (match_operand:DI 0 "register_operand" "=r")
15777         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15778                  (match_operand:DI 1 "register_operand" "0")))
15779    (clobber (reg:CC FLAGS_REG))]
15780   "TARGET_64BIT"
15781   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15782   [(set_attr "type" "alu")
15783    (set_attr "modrm" "0")
15784    (set_attr "length" "7")
15785    (set_attr "memory" "load")
15786    (set_attr "imm_disp" "false")])
15787
15788 ;; GNU2 TLS patterns can be split.
15789
15790 (define_expand "tls_dynamic_gnu2_32"
15791   [(set (match_dup 3)
15792         (plus:SI (match_operand:SI 2 "register_operand" "")
15793                  (const:SI
15794                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15795                              UNSPEC_TLSDESC))))
15796    (parallel
15797     [(set (match_operand:SI 0 "register_operand" "")
15798           (unspec:SI [(match_dup 1) (match_dup 3)
15799                       (match_dup 2) (reg:SI SP_REG)]
15800                       UNSPEC_TLSDESC))
15801      (clobber (reg:CC FLAGS_REG))])]
15802   "!TARGET_64BIT && TARGET_GNU2_TLS"
15803 {
15804   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15805   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15806 })
15807
15808 (define_insn "*tls_dynamic_lea_32"
15809   [(set (match_operand:SI 0 "register_operand" "=r")
15810         (plus:SI (match_operand:SI 1 "register_operand" "b")
15811                  (const:SI
15812                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15813                               UNSPEC_TLSDESC))))]
15814   "!TARGET_64BIT && TARGET_GNU2_TLS"
15815   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15816   [(set_attr "type" "lea")
15817    (set_attr "mode" "SI")
15818    (set_attr "length" "6")
15819    (set_attr "length_address" "4")])
15820
15821 (define_insn "*tls_dynamic_call_32"
15822   [(set (match_operand:SI 0 "register_operand" "=a")
15823         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15824                     (match_operand:SI 2 "register_operand" "0")
15825                     ;; we have to make sure %ebx still points to the GOT
15826                     (match_operand:SI 3 "register_operand" "b")
15827                     (reg:SI SP_REG)]
15828                    UNSPEC_TLSDESC))
15829    (clobber (reg:CC FLAGS_REG))]
15830   "!TARGET_64BIT && TARGET_GNU2_TLS"
15831   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15832   [(set_attr "type" "call")
15833    (set_attr "length" "2")
15834    (set_attr "length_address" "0")])
15835
15836 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15837   [(set (match_operand:SI 0 "register_operand" "=&a")
15838         (plus:SI
15839          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15840                      (match_operand:SI 4 "" "")
15841                      (match_operand:SI 2 "register_operand" "b")
15842                      (reg:SI SP_REG)]
15843                     UNSPEC_TLSDESC)
15844          (const:SI (unspec:SI
15845                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15846                     UNSPEC_DTPOFF))))
15847    (clobber (reg:CC FLAGS_REG))]
15848   "!TARGET_64BIT && TARGET_GNU2_TLS"
15849   "#"
15850   ""
15851   [(set (match_dup 0) (match_dup 5))]
15852 {
15853   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15854   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15855 })
15856
15857 (define_expand "tls_dynamic_gnu2_64"
15858   [(set (match_dup 2)
15859         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15860                    UNSPEC_TLSDESC))
15861    (parallel
15862     [(set (match_operand:DI 0 "register_operand" "")
15863           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15864                      UNSPEC_TLSDESC))
15865      (clobber (reg:CC FLAGS_REG))])]
15866   "TARGET_64BIT && TARGET_GNU2_TLS"
15867 {
15868   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15869   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15870 })
15871
15872 (define_insn "*tls_dynamic_lea_64"
15873   [(set (match_operand:DI 0 "register_operand" "=r")
15874         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15875                    UNSPEC_TLSDESC))]
15876   "TARGET_64BIT && TARGET_GNU2_TLS"
15877   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15878   [(set_attr "type" "lea")
15879    (set_attr "mode" "DI")
15880    (set_attr "length" "7")
15881    (set_attr "length_address" "4")])
15882
15883 (define_insn "*tls_dynamic_call_64"
15884   [(set (match_operand:DI 0 "register_operand" "=a")
15885         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15886                     (match_operand:DI 2 "register_operand" "0")
15887                     (reg:DI SP_REG)]
15888                    UNSPEC_TLSDESC))
15889    (clobber (reg:CC FLAGS_REG))]
15890   "TARGET_64BIT && TARGET_GNU2_TLS"
15891   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15892   [(set_attr "type" "call")
15893    (set_attr "length" "2")
15894    (set_attr "length_address" "0")])
15895
15896 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15897   [(set (match_operand:DI 0 "register_operand" "=&a")
15898         (plus:DI
15899          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15900                      (match_operand:DI 3 "" "")
15901                      (reg:DI SP_REG)]
15902                     UNSPEC_TLSDESC)
15903          (const:DI (unspec:DI
15904                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15905                     UNSPEC_DTPOFF))))
15906    (clobber (reg:CC FLAGS_REG))]
15907   "TARGET_64BIT && TARGET_GNU2_TLS"
15908   "#"
15909   ""
15910   [(set (match_dup 0) (match_dup 4))]
15911 {
15912   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15913   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15914 })
15915
15916 ;;
15917 \f
15918 ;; These patterns match the binary 387 instructions for addM3, subM3,
15919 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15920 ;; SFmode.  The first is the normal insn, the second the same insn but
15921 ;; with one operand a conversion, and the third the same insn but with
15922 ;; the other operand a conversion.  The conversion may be SFmode or
15923 ;; SImode if the target mode DFmode, but only SImode if the target mode
15924 ;; is SFmode.
15925
15926 ;; Gcc is slightly more smart about handling normal two address instructions
15927 ;; so use special patterns for add and mull.
15928
15929 (define_insn "*fop_sf_comm_mixed"
15930   [(set (match_operand:SF 0 "register_operand" "=f,x")
15931         (match_operator:SF 3 "binary_fp_operator"
15932                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15933                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15934   "TARGET_MIX_SSE_I387
15935    && COMMUTATIVE_ARITH_P (operands[3])
15936    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15937   "* return output_387_binary_op (insn, operands);"
15938   [(set (attr "type")
15939         (if_then_else (eq_attr "alternative" "1")
15940            (if_then_else (match_operand:SF 3 "mult_operator" "")
15941               (const_string "ssemul")
15942               (const_string "sseadd"))
15943            (if_then_else (match_operand:SF 3 "mult_operator" "")
15944               (const_string "fmul")
15945               (const_string "fop"))))
15946    (set_attr "mode" "SF")])
15947
15948 (define_insn "*fop_sf_comm_sse"
15949   [(set (match_operand:SF 0 "register_operand" "=x")
15950         (match_operator:SF 3 "binary_fp_operator"
15951                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15952                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15953   "TARGET_SSE_MATH
15954    && COMMUTATIVE_ARITH_P (operands[3])
15955    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15956   "* return output_387_binary_op (insn, operands);"
15957   [(set (attr "type")
15958         (if_then_else (match_operand:SF 3 "mult_operator" "")
15959            (const_string "ssemul")
15960            (const_string "sseadd")))
15961    (set_attr "mode" "SF")])
15962
15963 (define_insn "*fop_sf_comm_i387"
15964   [(set (match_operand:SF 0 "register_operand" "=f")
15965         (match_operator:SF 3 "binary_fp_operator"
15966                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15967                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15968   "TARGET_80387
15969    && COMMUTATIVE_ARITH_P (operands[3])
15970    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15971   "* return output_387_binary_op (insn, operands);"
15972   [(set (attr "type")
15973         (if_then_else (match_operand:SF 3 "mult_operator" "")
15974            (const_string "fmul")
15975            (const_string "fop")))
15976    (set_attr "mode" "SF")])
15977
15978 (define_insn "*fop_sf_1_mixed"
15979   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15980         (match_operator:SF 3 "binary_fp_operator"
15981                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15982                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15983   "TARGET_MIX_SSE_I387
15984    && !COMMUTATIVE_ARITH_P (operands[3])
15985    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15986   "* return output_387_binary_op (insn, operands);"
15987   [(set (attr "type")
15988         (cond [(and (eq_attr "alternative" "2")
15989                     (match_operand:SF 3 "mult_operator" ""))
15990                  (const_string "ssemul")
15991                (and (eq_attr "alternative" "2")
15992                     (match_operand:SF 3 "div_operator" ""))
15993                  (const_string "ssediv")
15994                (eq_attr "alternative" "2")
15995                  (const_string "sseadd")
15996                (match_operand:SF 3 "mult_operator" "")
15997                  (const_string "fmul")
15998                (match_operand:SF 3 "div_operator" "")
15999                  (const_string "fdiv")
16000               ]
16001               (const_string "fop")))
16002    (set_attr "mode" "SF")])
16003
16004 (define_insn "*rcpsf2_sse"
16005   [(set (match_operand:SF 0 "register_operand" "=x")
16006         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16007                    UNSPEC_RCP))]
16008   "TARGET_SSE_MATH"
16009   "rcpss\t{%1, %0|%0, %1}"
16010   [(set_attr "type" "sse")
16011    (set_attr "mode" "SF")])
16012
16013 (define_insn "*fop_sf_1_sse"
16014   [(set (match_operand:SF 0 "register_operand" "=x")
16015         (match_operator:SF 3 "binary_fp_operator"
16016                         [(match_operand:SF 1 "register_operand" "0")
16017                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
16018   "TARGET_SSE_MATH
16019    && !COMMUTATIVE_ARITH_P (operands[3])"
16020   "* return output_387_binary_op (insn, operands);"
16021   [(set (attr "type")
16022         (cond [(match_operand:SF 3 "mult_operator" "")
16023                  (const_string "ssemul")
16024                (match_operand:SF 3 "div_operator" "")
16025                  (const_string "ssediv")
16026               ]
16027               (const_string "sseadd")))
16028    (set_attr "mode" "SF")])
16029
16030 ;; This pattern is not fully shadowed by the pattern above.
16031 (define_insn "*fop_sf_1_i387"
16032   [(set (match_operand:SF 0 "register_operand" "=f,f")
16033         (match_operator:SF 3 "binary_fp_operator"
16034                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
16035                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
16036   "TARGET_80387 && !TARGET_SSE_MATH
16037    && !COMMUTATIVE_ARITH_P (operands[3])
16038    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16039   "* return output_387_binary_op (insn, operands);"
16040   [(set (attr "type")
16041         (cond [(match_operand:SF 3 "mult_operator" "")
16042                  (const_string "fmul")
16043                (match_operand:SF 3 "div_operator" "")
16044                  (const_string "fdiv")
16045               ]
16046               (const_string "fop")))
16047    (set_attr "mode" "SF")])
16048
16049 ;; ??? Add SSE splitters for these!
16050 (define_insn "*fop_sf_2<mode>_i387"
16051   [(set (match_operand:SF 0 "register_operand" "=f,f")
16052         (match_operator:SF 3 "binary_fp_operator"
16053           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16054            (match_operand:SF 2 "register_operand" "0,0")]))]
16055   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16056   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16057   [(set (attr "type")
16058         (cond [(match_operand:SF 3 "mult_operator" "")
16059                  (const_string "fmul")
16060                (match_operand:SF 3 "div_operator" "")
16061                  (const_string "fdiv")
16062               ]
16063               (const_string "fop")))
16064    (set_attr "fp_int_src" "true")
16065    (set_attr "mode" "<MODE>")])
16066
16067 (define_insn "*fop_sf_3<mode>_i387"
16068   [(set (match_operand:SF 0 "register_operand" "=f,f")
16069         (match_operator:SF 3 "binary_fp_operator"
16070           [(match_operand:SF 1 "register_operand" "0,0")
16071            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16072   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16073   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16074   [(set (attr "type")
16075         (cond [(match_operand:SF 3 "mult_operator" "")
16076                  (const_string "fmul")
16077                (match_operand:SF 3 "div_operator" "")
16078                  (const_string "fdiv")
16079               ]
16080               (const_string "fop")))
16081    (set_attr "fp_int_src" "true")
16082    (set_attr "mode" "<MODE>")])
16083
16084 (define_insn "*fop_df_comm_mixed"
16085   [(set (match_operand:DF 0 "register_operand" "=f,x")
16086         (match_operator:DF 3 "binary_fp_operator"
16087           [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
16088            (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
16089   "TARGET_SSE2 && TARGET_MIX_SSE_I387
16090    && COMMUTATIVE_ARITH_P (operands[3])
16091    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16092   "* return output_387_binary_op (insn, operands);"
16093   [(set (attr "type")
16094         (if_then_else (eq_attr "alternative" "1")
16095            (if_then_else (match_operand:DF 3 "mult_operator" "")
16096               (const_string "ssemul")
16097               (const_string "sseadd"))
16098            (if_then_else (match_operand:DF 3 "mult_operator" "")
16099               (const_string "fmul")
16100               (const_string "fop"))))
16101    (set_attr "mode" "DF")])
16102
16103 (define_insn "*fop_df_comm_sse"
16104   [(set (match_operand:DF 0 "register_operand" "=x")
16105         (match_operator:DF 3 "binary_fp_operator"
16106           [(match_operand:DF 1 "nonimmediate_operand" "%0")
16107            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16108   "TARGET_SSE2 && TARGET_SSE_MATH
16109    && COMMUTATIVE_ARITH_P (operands[3])
16110    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16111   "* return output_387_binary_op (insn, operands);"
16112   [(set (attr "type")
16113         (if_then_else (match_operand:DF 3 "mult_operator" "")
16114            (const_string "ssemul")
16115            (const_string "sseadd")))
16116    (set_attr "mode" "DF")])
16117
16118 (define_insn "*fop_df_comm_i387"
16119   [(set (match_operand:DF 0 "register_operand" "=f")
16120         (match_operator:DF 3 "binary_fp_operator"
16121                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
16122                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
16123   "TARGET_80387
16124    && COMMUTATIVE_ARITH_P (operands[3])
16125    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16126   "* return output_387_binary_op (insn, operands);"
16127   [(set (attr "type")
16128         (if_then_else (match_operand:DF 3 "mult_operator" "")
16129            (const_string "fmul")
16130            (const_string "fop")))
16131    (set_attr "mode" "DF")])
16132
16133 (define_insn "*fop_df_1_mixed"
16134   [(set (match_operand:DF 0 "register_operand" "=f,f,x")
16135         (match_operator:DF 3 "binary_fp_operator"
16136           [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
16137            (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
16138   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
16139    && !COMMUTATIVE_ARITH_P (operands[3])
16140    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16141   "* return output_387_binary_op (insn, operands);"
16142   [(set (attr "type")
16143         (cond [(and (eq_attr "alternative" "2")
16144                     (match_operand:DF 3 "mult_operator" ""))
16145                  (const_string "ssemul")
16146                (and (eq_attr "alternative" "2")
16147                     (match_operand:DF 3 "div_operator" ""))
16148                  (const_string "ssediv")
16149                (eq_attr "alternative" "2")
16150                  (const_string "sseadd")
16151                (match_operand:DF 3 "mult_operator" "")
16152                  (const_string "fmul")
16153                (match_operand:DF 3 "div_operator" "")
16154                  (const_string "fdiv")
16155               ]
16156               (const_string "fop")))
16157    (set_attr "mode" "DF")])
16158
16159 (define_insn "*fop_df_1_sse"
16160   [(set (match_operand:DF 0 "register_operand" "=x")
16161         (match_operator:DF 3 "binary_fp_operator"
16162           [(match_operand:DF 1 "register_operand" "0")
16163            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16164   "TARGET_SSE2 && TARGET_SSE_MATH
16165    && !COMMUTATIVE_ARITH_P (operands[3])"
16166   "* return output_387_binary_op (insn, operands);"
16167   [(set_attr "mode" "DF")
16168    (set (attr "type")
16169         (cond [(match_operand:DF 3 "mult_operator" "")
16170                  (const_string "ssemul")
16171                (match_operand:DF 3 "div_operator" "")
16172                  (const_string "ssediv")
16173               ]
16174               (const_string "sseadd")))])
16175
16176 ;; This pattern is not fully shadowed by the pattern above.
16177 (define_insn "*fop_df_1_i387"
16178   [(set (match_operand:DF 0 "register_operand" "=f,f")
16179         (match_operator:DF 3 "binary_fp_operator"
16180                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
16181                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
16182   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16183    && !COMMUTATIVE_ARITH_P (operands[3])
16184    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16185   "* return output_387_binary_op (insn, operands);"
16186   [(set (attr "type")
16187         (cond [(match_operand:DF 3 "mult_operator" "")
16188                  (const_string "fmul")
16189                (match_operand:DF 3 "div_operator" "")
16190                  (const_string "fdiv")
16191               ]
16192               (const_string "fop")))
16193    (set_attr "mode" "DF")])
16194
16195 ;; ??? Add SSE splitters for these!
16196 (define_insn "*fop_df_2<mode>_i387"
16197   [(set (match_operand:DF 0 "register_operand" "=f,f")
16198         (match_operator:DF 3 "binary_fp_operator"
16199            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16200             (match_operand:DF 2 "register_operand" "0,0")]))]
16201   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16202    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16203   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16204   [(set (attr "type")
16205         (cond [(match_operand:DF 3 "mult_operator" "")
16206                  (const_string "fmul")
16207                (match_operand:DF 3 "div_operator" "")
16208                  (const_string "fdiv")
16209               ]
16210               (const_string "fop")))
16211    (set_attr "fp_int_src" "true")
16212    (set_attr "mode" "<MODE>")])
16213
16214 (define_insn "*fop_df_3<mode>_i387"
16215   [(set (match_operand:DF 0 "register_operand" "=f,f")
16216         (match_operator:DF 3 "binary_fp_operator"
16217            [(match_operand:DF 1 "register_operand" "0,0")
16218             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16219   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16220    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16221   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16222   [(set (attr "type")
16223         (cond [(match_operand:DF 3 "mult_operator" "")
16224                  (const_string "fmul")
16225                (match_operand:DF 3 "div_operator" "")
16226                  (const_string "fdiv")
16227               ]
16228               (const_string "fop")))
16229    (set_attr "fp_int_src" "true")
16230    (set_attr "mode" "<MODE>")])
16231
16232 (define_insn "*fop_df_4_i387"
16233   [(set (match_operand:DF 0 "register_operand" "=f,f")
16234         (match_operator:DF 3 "binary_fp_operator"
16235            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16236             (match_operand:DF 2 "register_operand" "0,f")]))]
16237   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16238    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16239   "* return output_387_binary_op (insn, operands);"
16240   [(set (attr "type")
16241         (cond [(match_operand:DF 3 "mult_operator" "")
16242                  (const_string "fmul")
16243                (match_operand:DF 3 "div_operator" "")
16244                  (const_string "fdiv")
16245               ]
16246               (const_string "fop")))
16247    (set_attr "mode" "SF")])
16248
16249 (define_insn "*fop_df_5_i387"
16250   [(set (match_operand:DF 0 "register_operand" "=f,f")
16251         (match_operator:DF 3 "binary_fp_operator"
16252           [(match_operand:DF 1 "register_operand" "0,f")
16253            (float_extend:DF
16254             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16255   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16256   "* return output_387_binary_op (insn, operands);"
16257   [(set (attr "type")
16258         (cond [(match_operand:DF 3 "mult_operator" "")
16259                  (const_string "fmul")
16260                (match_operand:DF 3 "div_operator" "")
16261                  (const_string "fdiv")
16262               ]
16263               (const_string "fop")))
16264    (set_attr "mode" "SF")])
16265
16266 (define_insn "*fop_df_6_i387"
16267   [(set (match_operand:DF 0 "register_operand" "=f,f")
16268         (match_operator:DF 3 "binary_fp_operator"
16269           [(float_extend:DF
16270             (match_operand:SF 1 "register_operand" "0,f"))
16271            (float_extend:DF
16272             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16273   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16274   "* return output_387_binary_op (insn, operands);"
16275   [(set (attr "type")
16276         (cond [(match_operand:DF 3 "mult_operator" "")
16277                  (const_string "fmul")
16278                (match_operand:DF 3 "div_operator" "")
16279                  (const_string "fdiv")
16280               ]
16281               (const_string "fop")))
16282    (set_attr "mode" "SF")])
16283
16284 (define_insn "*fop_xf_comm_i387"
16285   [(set (match_operand:XF 0 "register_operand" "=f")
16286         (match_operator:XF 3 "binary_fp_operator"
16287                         [(match_operand:XF 1 "register_operand" "%0")
16288                          (match_operand:XF 2 "register_operand" "f")]))]
16289   "TARGET_80387
16290    && COMMUTATIVE_ARITH_P (operands[3])"
16291   "* return output_387_binary_op (insn, operands);"
16292   [(set (attr "type")
16293         (if_then_else (match_operand:XF 3 "mult_operator" "")
16294            (const_string "fmul")
16295            (const_string "fop")))
16296    (set_attr "mode" "XF")])
16297
16298 (define_insn "*fop_xf_1_i387"
16299   [(set (match_operand:XF 0 "register_operand" "=f,f")
16300         (match_operator:XF 3 "binary_fp_operator"
16301                         [(match_operand:XF 1 "register_operand" "0,f")
16302                          (match_operand:XF 2 "register_operand" "f,0")]))]
16303   "TARGET_80387
16304    && !COMMUTATIVE_ARITH_P (operands[3])"
16305   "* return output_387_binary_op (insn, operands);"
16306   [(set (attr "type")
16307         (cond [(match_operand:XF 3 "mult_operator" "")
16308                  (const_string "fmul")
16309                (match_operand:XF 3 "div_operator" "")
16310                  (const_string "fdiv")
16311               ]
16312               (const_string "fop")))
16313    (set_attr "mode" "XF")])
16314
16315 (define_insn "*fop_xf_2<mode>_i387"
16316   [(set (match_operand:XF 0 "register_operand" "=f,f")
16317         (match_operator:XF 3 "binary_fp_operator"
16318            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16319             (match_operand:XF 2 "register_operand" "0,0")]))]
16320   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16321   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16322   [(set (attr "type")
16323         (cond [(match_operand:XF 3 "mult_operator" "")
16324                  (const_string "fmul")
16325                (match_operand:XF 3 "div_operator" "")
16326                  (const_string "fdiv")
16327               ]
16328               (const_string "fop")))
16329    (set_attr "fp_int_src" "true")
16330    (set_attr "mode" "<MODE>")])
16331
16332 (define_insn "*fop_xf_3<mode>_i387"
16333   [(set (match_operand:XF 0 "register_operand" "=f,f")
16334         (match_operator:XF 3 "binary_fp_operator"
16335           [(match_operand:XF 1 "register_operand" "0,0")
16336            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16337   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16338   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16339   [(set (attr "type")
16340         (cond [(match_operand:XF 3 "mult_operator" "")
16341                  (const_string "fmul")
16342                (match_operand:XF 3 "div_operator" "")
16343                  (const_string "fdiv")
16344               ]
16345               (const_string "fop")))
16346    (set_attr "fp_int_src" "true")
16347    (set_attr "mode" "<MODE>")])
16348
16349 (define_insn "*fop_xf_4_i387"
16350   [(set (match_operand:XF 0 "register_operand" "=f,f")
16351         (match_operator:XF 3 "binary_fp_operator"
16352            [(float_extend:XF
16353               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16354             (match_operand:XF 2 "register_operand" "0,f")]))]
16355   "TARGET_80387"
16356   "* return output_387_binary_op (insn, operands);"
16357   [(set (attr "type")
16358         (cond [(match_operand:XF 3 "mult_operator" "")
16359                  (const_string "fmul")
16360                (match_operand:XF 3 "div_operator" "")
16361                  (const_string "fdiv")
16362               ]
16363               (const_string "fop")))
16364    (set_attr "mode" "SF")])
16365
16366 (define_insn "*fop_xf_5_i387"
16367   [(set (match_operand:XF 0 "register_operand" "=f,f")
16368         (match_operator:XF 3 "binary_fp_operator"
16369           [(match_operand:XF 1 "register_operand" "0,f")
16370            (float_extend:XF
16371              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16372   "TARGET_80387"
16373   "* return output_387_binary_op (insn, operands);"
16374   [(set (attr "type")
16375         (cond [(match_operand:XF 3 "mult_operator" "")
16376                  (const_string "fmul")
16377                (match_operand:XF 3 "div_operator" "")
16378                  (const_string "fdiv")
16379               ]
16380               (const_string "fop")))
16381    (set_attr "mode" "SF")])
16382
16383 (define_insn "*fop_xf_6_i387"
16384   [(set (match_operand:XF 0 "register_operand" "=f,f")
16385         (match_operator:XF 3 "binary_fp_operator"
16386           [(float_extend:XF
16387              (match_operand:MODEF 1 "register_operand" "0,f"))
16388            (float_extend:XF
16389              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16390   "TARGET_80387"
16391   "* return output_387_binary_op (insn, operands);"
16392   [(set (attr "type")
16393         (cond [(match_operand:XF 3 "mult_operator" "")
16394                  (const_string "fmul")
16395                (match_operand:XF 3 "div_operator" "")
16396                  (const_string "fdiv")
16397               ]
16398               (const_string "fop")))
16399    (set_attr "mode" "SF")])
16400
16401 (define_split
16402   [(set (match_operand 0 "register_operand" "")
16403         (match_operator 3 "binary_fp_operator"
16404            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16405             (match_operand 2 "register_operand" "")]))]
16406   "reload_completed
16407    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16408   [(const_int 0)]
16409 {
16410   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16411   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16412   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16413                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16414                                           GET_MODE (operands[3]),
16415                                           operands[4],
16416                                           operands[2])));
16417   ix86_free_from_memory (GET_MODE (operands[1]));
16418   DONE;
16419 })
16420
16421 (define_split
16422   [(set (match_operand 0 "register_operand" "")
16423         (match_operator 3 "binary_fp_operator"
16424            [(match_operand 1 "register_operand" "")
16425             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16426   "reload_completed
16427    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16428   [(const_int 0)]
16429 {
16430   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16431   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16432   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16433                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16434                                           GET_MODE (operands[3]),
16435                                           operands[1],
16436                                           operands[4])));
16437   ix86_free_from_memory (GET_MODE (operands[2]));
16438   DONE;
16439 })
16440 \f
16441 ;; FPU special functions.
16442
16443 ;; This pattern implements a no-op XFmode truncation for
16444 ;; all fancy i386 XFmode math functions.
16445
16446 (define_insn "truncxf<mode>2_i387_noop_unspec"
16447   [(set (match_operand:MODEF 0 "register_operand" "=f")
16448         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16449         UNSPEC_TRUNC_NOOP))]
16450   "TARGET_USE_FANCY_MATH_387"
16451   "* return output_387_reg_move (insn, operands);"
16452   [(set_attr "type" "fmov")
16453    (set_attr "mode" "<MODE>")])
16454
16455 (define_insn "sqrtxf2"
16456   [(set (match_operand:XF 0 "register_operand" "=f")
16457         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16458   "TARGET_USE_FANCY_MATH_387"
16459   "fsqrt"
16460   [(set_attr "type" "fpspc")
16461    (set_attr "mode" "XF")
16462    (set_attr "athlon_decode" "direct")
16463    (set_attr "amdfam10_decode" "direct")])
16464
16465 (define_insn "sqrt_extend<mode>xf2_i387"
16466   [(set (match_operand:XF 0 "register_operand" "=f")
16467         (sqrt:XF
16468           (float_extend:XF
16469             (match_operand:MODEF 1 "register_operand" "0"))))]
16470   "TARGET_USE_FANCY_MATH_387"
16471   "fsqrt"
16472   [(set_attr "type" "fpspc")
16473    (set_attr "mode" "XF")
16474    (set_attr "athlon_decode" "direct")
16475    (set_attr "amdfam10_decode" "direct")])
16476
16477 (define_insn "*rsqrtsf2_sse"
16478   [(set (match_operand:SF 0 "register_operand" "=x")
16479         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16480                    UNSPEC_RSQRT))]
16481   "TARGET_SSE_MATH"
16482   "rsqrtss\t{%1, %0|%0, %1}"
16483   [(set_attr "type" "sse")
16484    (set_attr "mode" "SF")])
16485
16486 (define_expand "rsqrtsf2"
16487   [(set (match_operand:SF 0 "register_operand" "")
16488         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16489                    UNSPEC_RSQRT))]
16490   "TARGET_SSE_MATH"
16491 {
16492   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16493   DONE;
16494 })
16495
16496 (define_insn "*sqrt<mode>2_sse"
16497   [(set (match_operand:MODEF 0 "register_operand" "=x")
16498         (sqrt:MODEF
16499           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16500   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16501   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16502   [(set_attr "type" "sse")
16503    (set_attr "mode" "<MODE>")
16504    (set_attr "athlon_decode" "*")
16505    (set_attr "amdfam10_decode" "*")])
16506
16507 (define_expand "sqrt<mode>2"
16508   [(set (match_operand:MODEF 0 "register_operand" "")
16509         (sqrt:MODEF
16510           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16511   "TARGET_USE_FANCY_MATH_387
16512    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16513 {
16514   if (<MODE>mode == SFmode
16515       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16516       && flag_finite_math_only && !flag_trapping_math
16517       && flag_unsafe_math_optimizations)
16518     {
16519       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16520       DONE;
16521     }
16522
16523   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16524     {
16525       rtx op0 = gen_reg_rtx (XFmode);
16526       rtx op1 = force_reg (<MODE>mode, operands[1]);
16527
16528       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16529       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16530       DONE;
16531    }
16532 })
16533
16534 (define_insn "fpremxf4_i387"
16535   [(set (match_operand:XF 0 "register_operand" "=f")
16536         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16537                     (match_operand:XF 3 "register_operand" "1")]
16538                    UNSPEC_FPREM_F))
16539    (set (match_operand:XF 1 "register_operand" "=u")
16540         (unspec:XF [(match_dup 2) (match_dup 3)]
16541                    UNSPEC_FPREM_U))
16542    (set (reg:CCFP FPSR_REG)
16543         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16544                      UNSPEC_C2_FLAG))]
16545   "TARGET_USE_FANCY_MATH_387"
16546   "fprem"
16547   [(set_attr "type" "fpspc")
16548    (set_attr "mode" "XF")])
16549
16550 (define_expand "fmodxf3"
16551   [(use (match_operand:XF 0 "register_operand" ""))
16552    (use (match_operand:XF 1 "register_operand" ""))
16553    (use (match_operand:XF 2 "register_operand" ""))]
16554   "TARGET_USE_FANCY_MATH_387"
16555 {
16556   rtx label = gen_label_rtx ();
16557
16558   rtx op2;
16559
16560   if (rtx_equal_p (operands[1], operands[2]))
16561     {
16562       op2 = gen_reg_rtx (XFmode);
16563       emit_move_insn (op2, operands[2]);
16564     }
16565   else
16566     op2 = operands[2];
16567
16568   emit_label (label);
16569   emit_insn (gen_fpremxf4_i387 (operands[1], op2, operands[1], op2));
16570   ix86_emit_fp_unordered_jump (label);
16571   LABEL_NUSES (label) = 1;
16572
16573   emit_move_insn (operands[0], operands[1]);
16574   DONE;
16575 })
16576
16577 (define_expand "fmod<mode>3"
16578   [(use (match_operand:MODEF 0 "register_operand" ""))
16579    (use (match_operand:MODEF 1 "general_operand" ""))
16580    (use (match_operand:MODEF 2 "general_operand" ""))]
16581   "TARGET_USE_FANCY_MATH_387"
16582 {
16583   rtx label = gen_label_rtx ();
16584
16585   rtx op1 = gen_reg_rtx (XFmode);
16586   rtx op2 = gen_reg_rtx (XFmode);
16587
16588   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16589   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16590
16591   emit_label (label);
16592   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16593   ix86_emit_fp_unordered_jump (label);
16594   LABEL_NUSES (label) = 1;
16595
16596   /* Truncate the result properly for strict SSE math.  */
16597   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16598       && !TARGET_MIX_SSE_I387)
16599     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16600   else
16601     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16602
16603   DONE;
16604 })
16605
16606 (define_insn "fprem1xf4_i387"
16607   [(set (match_operand:XF 0 "register_operand" "=f")
16608         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16609                     (match_operand:XF 3 "register_operand" "1")]
16610                    UNSPEC_FPREM1_F))
16611    (set (match_operand:XF 1 "register_operand" "=u")
16612         (unspec:XF [(match_dup 2) (match_dup 3)]
16613                    UNSPEC_FPREM1_U))
16614    (set (reg:CCFP FPSR_REG)
16615         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16616                      UNSPEC_C2_FLAG))]
16617   "TARGET_USE_FANCY_MATH_387"
16618   "fprem1"
16619   [(set_attr "type" "fpspc")
16620    (set_attr "mode" "XF")])
16621
16622 (define_expand "remainderxf3"
16623   [(use (match_operand:XF 0 "register_operand" ""))
16624    (use (match_operand:XF 1 "register_operand" ""))
16625    (use (match_operand:XF 2 "register_operand" ""))]
16626   "TARGET_USE_FANCY_MATH_387"
16627 {
16628   rtx label = gen_label_rtx ();
16629
16630   rtx op2;
16631
16632   if (rtx_equal_p (operands[1], operands[2]))
16633     {
16634       op2 = gen_reg_rtx (XFmode);
16635       emit_move_insn (op2, operands[2]);
16636     }
16637   else
16638     op2 = operands[2];
16639
16640   emit_label (label);
16641   emit_insn (gen_fprem1xf4_i387 (operands[1], op2, operands[1], op2));
16642   ix86_emit_fp_unordered_jump (label);
16643   LABEL_NUSES (label) = 1;
16644
16645   emit_move_insn (operands[0], operands[1]);
16646   DONE;
16647 })
16648
16649 (define_expand "remainder<mode>3"
16650   [(use (match_operand:MODEF 0 "register_operand" ""))
16651    (use (match_operand:MODEF 1 "general_operand" ""))
16652    (use (match_operand:MODEF 2 "general_operand" ""))]
16653   "TARGET_USE_FANCY_MATH_387"
16654 {
16655   rtx label = gen_label_rtx ();
16656
16657   rtx op1 = gen_reg_rtx (XFmode);
16658   rtx op2 = gen_reg_rtx (XFmode);
16659
16660   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16661   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16662
16663   emit_label (label);
16664
16665   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16666   ix86_emit_fp_unordered_jump (label);
16667   LABEL_NUSES (label) = 1;
16668
16669   /* Truncate the result properly for strict SSE math.  */
16670   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16671       && !TARGET_MIX_SSE_I387)
16672     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16673   else
16674     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16675
16676   DONE;
16677 })
16678
16679 (define_insn "*sinxf2_i387"
16680   [(set (match_operand:XF 0 "register_operand" "=f")
16681         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16682   "TARGET_USE_FANCY_MATH_387
16683    && flag_unsafe_math_optimizations"
16684   "fsin"
16685   [(set_attr "type" "fpspc")
16686    (set_attr "mode" "XF")])
16687
16688 (define_insn "*sin_extend<mode>xf2_i387"
16689   [(set (match_operand:XF 0 "register_operand" "=f")
16690         (unspec:XF [(float_extend:XF
16691                       (match_operand:MODEF 1 "register_operand" "0"))]
16692                    UNSPEC_SIN))]
16693   "TARGET_USE_FANCY_MATH_387
16694    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16695        || TARGET_MIX_SSE_I387)
16696    && flag_unsafe_math_optimizations"
16697   "fsin"
16698   [(set_attr "type" "fpspc")
16699    (set_attr "mode" "XF")])
16700
16701 (define_insn "*cosxf2_i387"
16702   [(set (match_operand:XF 0 "register_operand" "=f")
16703         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16704   "TARGET_USE_FANCY_MATH_387
16705    && flag_unsafe_math_optimizations"
16706   "fcos"
16707   [(set_attr "type" "fpspc")
16708    (set_attr "mode" "XF")])
16709
16710 (define_insn "*cos_extend<mode>xf2_i387"
16711   [(set (match_operand:XF 0 "register_operand" "=f")
16712         (unspec:XF [(float_extend:XF
16713                       (match_operand:MODEF 1 "register_operand" "0"))]
16714                    UNSPEC_COS))]
16715   "TARGET_USE_FANCY_MATH_387
16716    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16717        || TARGET_MIX_SSE_I387)
16718    && flag_unsafe_math_optimizations"
16719   "fcos"
16720   [(set_attr "type" "fpspc")
16721    (set_attr "mode" "XF")])
16722
16723 ;; When sincos pattern is defined, sin and cos builtin functions will be
16724 ;; expanded to sincos pattern with one of its outputs left unused.
16725 ;; CSE pass will figure out if two sincos patterns can be combined,
16726 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16727 ;; depending on the unused output.
16728
16729 (define_insn "sincosxf3"
16730   [(set (match_operand:XF 0 "register_operand" "=f")
16731         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16732                    UNSPEC_SINCOS_COS))
16733    (set (match_operand:XF 1 "register_operand" "=u")
16734         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16735   "TARGET_USE_FANCY_MATH_387
16736    && flag_unsafe_math_optimizations"
16737   "fsincos"
16738   [(set_attr "type" "fpspc")
16739    (set_attr "mode" "XF")])
16740
16741 (define_split
16742   [(set (match_operand:XF 0 "register_operand" "")
16743         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16744                    UNSPEC_SINCOS_COS))
16745    (set (match_operand:XF 1 "register_operand" "")
16746         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16747   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16748    && !(reload_completed || reload_in_progress)"
16749   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16750   "")
16751
16752 (define_split
16753   [(set (match_operand:XF 0 "register_operand" "")
16754         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16755                    UNSPEC_SINCOS_COS))
16756    (set (match_operand:XF 1 "register_operand" "")
16757         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16758   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16759    && !(reload_completed || reload_in_progress)"
16760   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16761   "")
16762
16763 (define_insn "sincos_extend<mode>xf3_i387"
16764   [(set (match_operand:XF 0 "register_operand" "=f")
16765         (unspec:XF [(float_extend:XF
16766                       (match_operand:MODEF 2 "register_operand" "0"))]
16767                    UNSPEC_SINCOS_COS))
16768    (set (match_operand:XF 1 "register_operand" "=u")
16769         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16770   "TARGET_USE_FANCY_MATH_387
16771    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16772        || TARGET_MIX_SSE_I387)
16773    && flag_unsafe_math_optimizations"
16774   "fsincos"
16775   [(set_attr "type" "fpspc")
16776    (set_attr "mode" "XF")])
16777
16778 (define_split
16779   [(set (match_operand:XF 0 "register_operand" "")
16780         (unspec:XF [(float_extend:XF
16781                       (match_operand:MODEF 2 "register_operand" ""))]
16782                    UNSPEC_SINCOS_COS))
16783    (set (match_operand:XF 1 "register_operand" "")
16784         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16785   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16786    && !(reload_completed || reload_in_progress)"
16787   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16788   "")
16789
16790 (define_split
16791   [(set (match_operand:XF 0 "register_operand" "")
16792         (unspec:XF [(float_extend:XF
16793                       (match_operand:MODEF 2 "register_operand" ""))]
16794                    UNSPEC_SINCOS_COS))
16795    (set (match_operand:XF 1 "register_operand" "")
16796         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16797   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16798    && !(reload_completed || reload_in_progress)"
16799   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16800   "")
16801
16802 (define_expand "sincos<mode>3"
16803   [(use (match_operand:MODEF 0 "register_operand" ""))
16804    (use (match_operand:MODEF 1 "register_operand" ""))
16805    (use (match_operand:MODEF 2 "register_operand" ""))]
16806   "TARGET_USE_FANCY_MATH_387
16807    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16808        || TARGET_MIX_SSE_I387)
16809    && flag_unsafe_math_optimizations"
16810 {
16811   rtx op0 = gen_reg_rtx (XFmode);
16812   rtx op1 = gen_reg_rtx (XFmode);
16813
16814   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16815   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16816   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16817   DONE;
16818 })
16819
16820 (define_insn "fptanxf4_i387"
16821   [(set (match_operand:XF 0 "register_operand" "=f")
16822         (match_operand:XF 3 "const_double_operand" "F"))
16823    (set (match_operand:XF 1 "register_operand" "=u")
16824         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16825                    UNSPEC_TAN))]
16826   "TARGET_USE_FANCY_MATH_387
16827    && flag_unsafe_math_optimizations
16828    && standard_80387_constant_p (operands[3]) == 2"
16829   "fptan"
16830   [(set_attr "type" "fpspc")
16831    (set_attr "mode" "XF")])
16832
16833 (define_insn "fptan_extend<mode>xf4_i387"
16834   [(set (match_operand:MODEF 0 "register_operand" "=f")
16835         (match_operand:MODEF 3 "const_double_operand" "F"))
16836    (set (match_operand:XF 1 "register_operand" "=u")
16837         (unspec:XF [(float_extend:XF
16838                       (match_operand:MODEF 2 "register_operand" "0"))]
16839                    UNSPEC_TAN))]
16840   "TARGET_USE_FANCY_MATH_387
16841    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16842        || TARGET_MIX_SSE_I387)
16843    && flag_unsafe_math_optimizations
16844    && standard_80387_constant_p (operands[3]) == 2"
16845   "fptan"
16846   [(set_attr "type" "fpspc")
16847    (set_attr "mode" "XF")])
16848
16849 (define_expand "tanxf2"
16850   [(use (match_operand:XF 0 "register_operand" ""))
16851    (use (match_operand:XF 1 "register_operand" ""))]
16852   "TARGET_USE_FANCY_MATH_387
16853    && flag_unsafe_math_optimizations"
16854 {
16855   rtx one = gen_reg_rtx (XFmode);
16856   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16857
16858   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16859   DONE;
16860 })
16861
16862 (define_expand "tan<mode>2"
16863   [(use (match_operand:MODEF 0 "register_operand" ""))
16864    (use (match_operand:MODEF 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
16872   rtx one = gen_reg_rtx (<MODE>mode);
16873   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16874
16875   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16876                                              operands[1], op2));
16877   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16878   DONE;
16879 })
16880
16881 (define_insn "*fpatanxf3_i387"
16882   [(set (match_operand:XF 0 "register_operand" "=f")
16883         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16884                     (match_operand:XF 2 "register_operand" "u")]
16885                    UNSPEC_FPATAN))
16886    (clobber (match_scratch:XF 3 "=2"))]
16887   "TARGET_USE_FANCY_MATH_387
16888    && flag_unsafe_math_optimizations"
16889   "fpatan"
16890   [(set_attr "type" "fpspc")
16891    (set_attr "mode" "XF")])
16892
16893 (define_insn "fpatan_extend<mode>xf3_i387"
16894   [(set (match_operand:XF 0 "register_operand" "=f")
16895         (unspec:XF [(float_extend:XF
16896                       (match_operand:MODEF 1 "register_operand" "0"))
16897                     (float_extend:XF
16898                       (match_operand:MODEF 2 "register_operand" "u"))]
16899                    UNSPEC_FPATAN))
16900    (clobber (match_scratch:XF 3 "=2"))]
16901   "TARGET_USE_FANCY_MATH_387
16902    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16903        || TARGET_MIX_SSE_I387)
16904    && flag_unsafe_math_optimizations"
16905   "fpatan"
16906   [(set_attr "type" "fpspc")
16907    (set_attr "mode" "XF")])
16908
16909 (define_expand "atan2xf3"
16910   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16911                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16912                                (match_operand:XF 1 "register_operand" "")]
16913                               UNSPEC_FPATAN))
16914               (clobber (match_scratch:XF 3 ""))])]
16915   "TARGET_USE_FANCY_MATH_387
16916    && flag_unsafe_math_optimizations"
16917   "")
16918
16919 (define_expand "atan2<mode>3"
16920   [(use (match_operand:MODEF 0 "register_operand" ""))
16921    (use (match_operand:MODEF 1 "register_operand" ""))
16922    (use (match_operand:MODEF 2 "register_operand" ""))]
16923   "TARGET_USE_FANCY_MATH_387
16924    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16925        || TARGET_MIX_SSE_I387)
16926    && flag_unsafe_math_optimizations"
16927 {
16928   rtx op0 = gen_reg_rtx (XFmode);
16929
16930   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16931   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16932   DONE;
16933 })
16934
16935 (define_expand "atanxf2"
16936   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16937                    (unspec:XF [(match_dup 2)
16938                                (match_operand:XF 1 "register_operand" "")]
16939                               UNSPEC_FPATAN))
16940               (clobber (match_scratch:XF 3 ""))])]
16941   "TARGET_USE_FANCY_MATH_387
16942    && flag_unsafe_math_optimizations"
16943 {
16944   operands[2] = gen_reg_rtx (XFmode);
16945   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16946 })
16947
16948 (define_expand "atan<mode>2"
16949   [(use (match_operand:MODEF 0 "register_operand" ""))
16950    (use (match_operand:MODEF 1 "register_operand" ""))]
16951   "TARGET_USE_FANCY_MATH_387
16952    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16953        || TARGET_MIX_SSE_I387)
16954    && flag_unsafe_math_optimizations"
16955 {
16956   rtx op0 = gen_reg_rtx (XFmode);
16957
16958   rtx op2 = gen_reg_rtx (<MODE>mode);
16959   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16960
16961   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16962   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16963   DONE;
16964 })
16965
16966 (define_expand "asinxf2"
16967   [(set (match_dup 2)
16968         (mult:XF (match_operand:XF 1 "register_operand" "")
16969                  (match_dup 1)))
16970    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16971    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16972    (parallel [(set (match_operand:XF 0 "register_operand" "")
16973                    (unspec:XF [(match_dup 5) (match_dup 1)]
16974                               UNSPEC_FPATAN))
16975               (clobber (match_scratch:XF 6 ""))])]
16976   "TARGET_USE_FANCY_MATH_387
16977    && flag_unsafe_math_optimizations && !optimize_size"
16978 {
16979   int i;
16980
16981   for (i = 2; i < 6; i++)
16982     operands[i] = gen_reg_rtx (XFmode);
16983
16984   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16985 })
16986
16987 (define_expand "asin<mode>2"
16988   [(use (match_operand:MODEF 0 "register_operand" ""))
16989    (use (match_operand:MODEF 1 "general_operand" ""))]
16990  "TARGET_USE_FANCY_MATH_387
16991    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16992        || TARGET_MIX_SSE_I387)
16993    && flag_unsafe_math_optimizations && !optimize_size"
16994 {
16995   rtx op0 = gen_reg_rtx (XFmode);
16996   rtx op1 = gen_reg_rtx (XFmode);
16997
16998   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16999   emit_insn (gen_asinxf2 (op0, op1));
17000   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17001   DONE;
17002 })
17003
17004 (define_expand "acosxf2"
17005   [(set (match_dup 2)
17006         (mult:XF (match_operand:XF 1 "register_operand" "")
17007                  (match_dup 1)))
17008    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17009    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17010    (parallel [(set (match_operand:XF 0 "register_operand" "")
17011                    (unspec:XF [(match_dup 1) (match_dup 5)]
17012                               UNSPEC_FPATAN))
17013               (clobber (match_scratch:XF 6 ""))])]
17014   "TARGET_USE_FANCY_MATH_387
17015    && flag_unsafe_math_optimizations && !optimize_size"
17016 {
17017   int i;
17018
17019   for (i = 2; i < 6; i++)
17020     operands[i] = gen_reg_rtx (XFmode);
17021
17022   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17023 })
17024
17025 (define_expand "acos<mode>2"
17026   [(use (match_operand:MODEF 0 "register_operand" ""))
17027    (use (match_operand:MODEF 1 "general_operand" ""))]
17028  "TARGET_USE_FANCY_MATH_387
17029    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17030        || TARGET_MIX_SSE_I387)
17031    && flag_unsafe_math_optimizations && !optimize_size"
17032 {
17033   rtx op0 = gen_reg_rtx (XFmode);
17034   rtx op1 = gen_reg_rtx (XFmode);
17035
17036   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17037   emit_insn (gen_acosxf2 (op0, op1));
17038   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17039   DONE;
17040 })
17041
17042 (define_insn "fyl2xxf3_i387"
17043   [(set (match_operand:XF 0 "register_operand" "=f")
17044         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17045                     (match_operand:XF 2 "register_operand" "u")]
17046                    UNSPEC_FYL2X))
17047    (clobber (match_scratch:XF 3 "=2"))]
17048   "TARGET_USE_FANCY_MATH_387
17049    && flag_unsafe_math_optimizations"
17050   "fyl2x"
17051   [(set_attr "type" "fpspc")
17052    (set_attr "mode" "XF")])
17053
17054 (define_insn "fyl2x_extend<mode>xf3_i387"
17055   [(set (match_operand:XF 0 "register_operand" "=f")
17056         (unspec:XF [(float_extend:XF
17057                       (match_operand:MODEF 1 "register_operand" "0"))
17058                     (match_operand:XF 2 "register_operand" "u")]
17059                    UNSPEC_FYL2X))
17060    (clobber (match_scratch:XF 3 "=2"))]
17061   "TARGET_USE_FANCY_MATH_387
17062    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17063        || TARGET_MIX_SSE_I387)
17064    && flag_unsafe_math_optimizations"
17065   "fyl2x"
17066   [(set_attr "type" "fpspc")
17067    (set_attr "mode" "XF")])
17068
17069 (define_expand "logxf2"
17070   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17071                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17072                                (match_dup 2)] UNSPEC_FYL2X))
17073               (clobber (match_scratch:XF 3 ""))])]
17074   "TARGET_USE_FANCY_MATH_387
17075    && flag_unsafe_math_optimizations"
17076 {
17077   operands[2] = gen_reg_rtx (XFmode);
17078   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17079 })
17080
17081 (define_expand "log<mode>2"
17082   [(use (match_operand:MODEF 0 "register_operand" ""))
17083    (use (match_operand:MODEF 1 "register_operand" ""))]
17084   "TARGET_USE_FANCY_MATH_387
17085    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17086        || TARGET_MIX_SSE_I387)
17087    && flag_unsafe_math_optimizations"
17088 {
17089   rtx op0 = gen_reg_rtx (XFmode);
17090
17091   rtx op2 = gen_reg_rtx (XFmode);
17092   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17093
17094   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17095   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17096   DONE;
17097 })
17098
17099 (define_expand "log10xf2"
17100   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17101                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17102                                (match_dup 2)] UNSPEC_FYL2X))
17103               (clobber (match_scratch:XF 3 ""))])]
17104   "TARGET_USE_FANCY_MATH_387
17105    && flag_unsafe_math_optimizations"
17106 {
17107   operands[2] = gen_reg_rtx (XFmode);
17108   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17109 })
17110
17111 (define_expand "log10<mode>2"
17112   [(use (match_operand:MODEF 0 "register_operand" ""))
17113    (use (match_operand:MODEF 1 "register_operand" ""))]
17114   "TARGET_USE_FANCY_MATH_387
17115    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17116        || TARGET_MIX_SSE_I387)
17117    && flag_unsafe_math_optimizations"
17118 {
17119   rtx op0 = gen_reg_rtx (XFmode);
17120
17121   rtx op2 = gen_reg_rtx (XFmode);
17122   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17123
17124   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17125   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17126   DONE;
17127 })
17128
17129 (define_expand "log2xf2"
17130   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17131                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17132                                (match_dup 2)] UNSPEC_FYL2X))
17133               (clobber (match_scratch:XF 3 ""))])]
17134   "TARGET_USE_FANCY_MATH_387
17135    && flag_unsafe_math_optimizations"
17136 {
17137   operands[2] = gen_reg_rtx (XFmode);
17138   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17139 })
17140
17141 (define_expand "log2<mode>2"
17142   [(use (match_operand:MODEF 0 "register_operand" ""))
17143    (use (match_operand:MODEF 1 "register_operand" ""))]
17144   "TARGET_USE_FANCY_MATH_387
17145    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17146        || TARGET_MIX_SSE_I387)
17147    && flag_unsafe_math_optimizations"
17148 {
17149   rtx op0 = gen_reg_rtx (XFmode);
17150
17151   rtx op2 = gen_reg_rtx (XFmode);
17152   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17153
17154   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17155   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17156   DONE;
17157 })
17158
17159 (define_insn "fyl2xp1xf3_i387"
17160   [(set (match_operand:XF 0 "register_operand" "=f")
17161         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17162                     (match_operand:XF 2 "register_operand" "u")]
17163                    UNSPEC_FYL2XP1))
17164    (clobber (match_scratch:XF 3 "=2"))]
17165   "TARGET_USE_FANCY_MATH_387
17166    && flag_unsafe_math_optimizations"
17167   "fyl2xp1"
17168   [(set_attr "type" "fpspc")
17169    (set_attr "mode" "XF")])
17170
17171 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17172   [(set (match_operand:XF 0 "register_operand" "=f")
17173         (unspec:XF [(float_extend:XF
17174                       (match_operand:MODEF 1 "register_operand" "0"))
17175                     (match_operand:XF 2 "register_operand" "u")]
17176                    UNSPEC_FYL2XP1))
17177    (clobber (match_scratch:XF 3 "=2"))]
17178   "TARGET_USE_FANCY_MATH_387
17179    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17180        || TARGET_MIX_SSE_I387)
17181    && flag_unsafe_math_optimizations"
17182   "fyl2xp1"
17183   [(set_attr "type" "fpspc")
17184    (set_attr "mode" "XF")])
17185
17186 (define_expand "log1pxf2"
17187   [(use (match_operand:XF 0 "register_operand" ""))
17188    (use (match_operand:XF 1 "register_operand" ""))]
17189   "TARGET_USE_FANCY_MATH_387
17190    && flag_unsafe_math_optimizations && !optimize_size"
17191 {
17192   ix86_emit_i387_log1p (operands[0], operands[1]);
17193   DONE;
17194 })
17195
17196 (define_expand "log1p<mode>2"
17197   [(use (match_operand:MODEF 0 "register_operand" ""))
17198    (use (match_operand:MODEF 1 "register_operand" ""))]
17199   "TARGET_USE_FANCY_MATH_387
17200    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17201        || TARGET_MIX_SSE_I387)
17202    && flag_unsafe_math_optimizations && !optimize_size"
17203 {
17204   rtx op0 = gen_reg_rtx (XFmode);
17205
17206   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17207
17208   ix86_emit_i387_log1p (op0, operands[1]);
17209   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17210   DONE;
17211 })
17212
17213 (define_insn "fxtractxf3_i387"
17214   [(set (match_operand:XF 0 "register_operand" "=f")
17215         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17216                    UNSPEC_XTRACT_FRACT))
17217    (set (match_operand:XF 1 "register_operand" "=u")
17218         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17219   "TARGET_USE_FANCY_MATH_387
17220    && flag_unsafe_math_optimizations"
17221   "fxtract"
17222   [(set_attr "type" "fpspc")
17223    (set_attr "mode" "XF")])
17224
17225 (define_insn "fxtract_extend<mode>xf3_i387"
17226   [(set (match_operand:XF 0 "register_operand" "=f")
17227         (unspec:XF [(float_extend:XF
17228                       (match_operand:MODEF 2 "register_operand" "0"))]
17229                    UNSPEC_XTRACT_FRACT))
17230    (set (match_operand:XF 1 "register_operand" "=u")
17231         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17232   "TARGET_USE_FANCY_MATH_387
17233    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17234        || TARGET_MIX_SSE_I387)
17235    && flag_unsafe_math_optimizations"
17236   "fxtract"
17237   [(set_attr "type" "fpspc")
17238    (set_attr "mode" "XF")])
17239
17240 (define_expand "logbxf2"
17241   [(parallel [(set (match_dup 2)
17242                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17243                               UNSPEC_XTRACT_FRACT))
17244               (set (match_operand:XF 0 "register_operand" "")
17245                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17246   "TARGET_USE_FANCY_MATH_387
17247    && flag_unsafe_math_optimizations"
17248 {
17249   operands[2] = gen_reg_rtx (XFmode);
17250 })
17251
17252 (define_expand "logb<mode>2"
17253   [(use (match_operand:MODEF 0 "register_operand" ""))
17254    (use (match_operand:MODEF 1 "register_operand" ""))]
17255   "TARGET_USE_FANCY_MATH_387
17256    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17257        || TARGET_MIX_SSE_I387)
17258    && flag_unsafe_math_optimizations"
17259 {
17260   rtx op0 = gen_reg_rtx (XFmode);
17261   rtx op1 = gen_reg_rtx (XFmode);
17262
17263   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17264   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17265   DONE;
17266 })
17267
17268 (define_expand "ilogbxf2"
17269   [(use (match_operand:SI 0 "register_operand" ""))
17270    (use (match_operand:XF 1 "register_operand" ""))]
17271   "TARGET_USE_FANCY_MATH_387
17272    && flag_unsafe_math_optimizations && !optimize_size"
17273 {
17274   rtx op0 = gen_reg_rtx (XFmode);
17275   rtx op1 = gen_reg_rtx (XFmode);
17276
17277   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17278   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17279   DONE;
17280 })
17281
17282 (define_expand "ilogb<mode>2"
17283   [(use (match_operand:SI 0 "register_operand" ""))
17284    (use (match_operand:MODEF 1 "register_operand" ""))]
17285   "TARGET_USE_FANCY_MATH_387
17286    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17287        || TARGET_MIX_SSE_I387)
17288    && flag_unsafe_math_optimizations && !optimize_size"
17289 {
17290   rtx op0 = gen_reg_rtx (XFmode);
17291   rtx op1 = gen_reg_rtx (XFmode);
17292
17293   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17294   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17295   DONE;
17296 })
17297
17298 (define_insn "*f2xm1xf2_i387"
17299   [(set (match_operand:XF 0 "register_operand" "=f")
17300         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17301                    UNSPEC_F2XM1))]
17302   "TARGET_USE_FANCY_MATH_387
17303    && flag_unsafe_math_optimizations"
17304   "f2xm1"
17305   [(set_attr "type" "fpspc")
17306    (set_attr "mode" "XF")])
17307
17308 (define_insn "*fscalexf4_i387"
17309   [(set (match_operand:XF 0 "register_operand" "=f")
17310         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17311                     (match_operand:XF 3 "register_operand" "1")]
17312                    UNSPEC_FSCALE_FRACT))
17313    (set (match_operand:XF 1 "register_operand" "=u")
17314         (unspec:XF [(match_dup 2) (match_dup 3)]
17315                    UNSPEC_FSCALE_EXP))]
17316   "TARGET_USE_FANCY_MATH_387
17317    && flag_unsafe_math_optimizations"
17318   "fscale"
17319   [(set_attr "type" "fpspc")
17320    (set_attr "mode" "XF")])
17321
17322 (define_expand "expNcorexf3"
17323   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17324                                (match_operand:XF 2 "register_operand" "")))
17325    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17326    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17327    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17328    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17329    (parallel [(set (match_operand:XF 0 "register_operand" "")
17330                    (unspec:XF [(match_dup 8) (match_dup 4)]
17331                               UNSPEC_FSCALE_FRACT))
17332               (set (match_dup 9)
17333                    (unspec:XF [(match_dup 8) (match_dup 4)]
17334                               UNSPEC_FSCALE_EXP))])]
17335   "TARGET_USE_FANCY_MATH_387
17336    && flag_unsafe_math_optimizations && !optimize_size"
17337 {
17338   int i;
17339
17340   for (i = 3; i < 10; i++)
17341     operands[i] = gen_reg_rtx (XFmode);
17342
17343   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17344 })
17345
17346 (define_expand "expxf2"
17347   [(use (match_operand:XF 0 "register_operand" ""))
17348    (use (match_operand:XF 1 "register_operand" ""))]
17349   "TARGET_USE_FANCY_MATH_387
17350    && flag_unsafe_math_optimizations && !optimize_size"
17351 {
17352   rtx op2 = gen_reg_rtx (XFmode);
17353   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17354
17355   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17356   DONE;
17357 })
17358
17359 (define_expand "exp<mode>2"
17360   [(use (match_operand:MODEF 0 "register_operand" ""))
17361    (use (match_operand:MODEF 1 "general_operand" ""))]
17362  "TARGET_USE_FANCY_MATH_387
17363    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17364        || TARGET_MIX_SSE_I387)
17365    && flag_unsafe_math_optimizations && !optimize_size"
17366 {
17367   rtx op0 = gen_reg_rtx (XFmode);
17368   rtx op1 = gen_reg_rtx (XFmode);
17369
17370   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17371   emit_insn (gen_expxf2 (op0, op1));
17372   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17373   DONE;
17374 })
17375
17376 (define_expand "exp10xf2"
17377   [(use (match_operand:XF 0 "register_operand" ""))
17378    (use (match_operand:XF 1 "register_operand" ""))]
17379   "TARGET_USE_FANCY_MATH_387
17380    && flag_unsafe_math_optimizations && !optimize_size"
17381 {
17382   rtx op2 = gen_reg_rtx (XFmode);
17383   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17384
17385   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17386   DONE;
17387 })
17388
17389 (define_expand "exp10<mode>2"
17390   [(use (match_operand:MODEF 0 "register_operand" ""))
17391    (use (match_operand:MODEF 1 "general_operand" ""))]
17392  "TARGET_USE_FANCY_MATH_387
17393    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17394        || TARGET_MIX_SSE_I387)
17395    && flag_unsafe_math_optimizations && !optimize_size"
17396 {
17397   rtx op0 = gen_reg_rtx (XFmode);
17398   rtx op1 = gen_reg_rtx (XFmode);
17399
17400   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17401   emit_insn (gen_exp10xf2 (op0, op1));
17402   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17403   DONE;
17404 })
17405
17406 (define_expand "exp2xf2"
17407   [(use (match_operand:XF 0 "register_operand" ""))
17408    (use (match_operand:XF 1 "register_operand" ""))]
17409   "TARGET_USE_FANCY_MATH_387
17410    && flag_unsafe_math_optimizations && !optimize_size"
17411 {
17412   rtx op2 = gen_reg_rtx (XFmode);
17413   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17414
17415   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17416   DONE;
17417 })
17418
17419 (define_expand "exp2<mode>2"
17420   [(use (match_operand:MODEF 0 "register_operand" ""))
17421    (use (match_operand:MODEF 1 "general_operand" ""))]
17422  "TARGET_USE_FANCY_MATH_387
17423    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17424        || TARGET_MIX_SSE_I387)
17425    && flag_unsafe_math_optimizations && !optimize_size"
17426 {
17427   rtx op0 = gen_reg_rtx (XFmode);
17428   rtx op1 = gen_reg_rtx (XFmode);
17429
17430   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17431   emit_insn (gen_exp2xf2 (op0, op1));
17432   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17433   DONE;
17434 })
17435
17436 (define_expand "expm1xf2"
17437   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17438                                (match_dup 2)))
17439    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17440    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17441    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17442    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17443    (parallel [(set (match_dup 7)
17444                    (unspec:XF [(match_dup 6) (match_dup 4)]
17445                               UNSPEC_FSCALE_FRACT))
17446               (set (match_dup 8)
17447                    (unspec:XF [(match_dup 6) (match_dup 4)]
17448                               UNSPEC_FSCALE_EXP))])
17449    (parallel [(set (match_dup 10)
17450                    (unspec:XF [(match_dup 9) (match_dup 8)]
17451                               UNSPEC_FSCALE_FRACT))
17452               (set (match_dup 11)
17453                    (unspec:XF [(match_dup 9) (match_dup 8)]
17454                               UNSPEC_FSCALE_EXP))])
17455    (set (match_dup 12) (minus:XF (match_dup 10)
17456                                  (float_extend:XF (match_dup 13))))
17457    (set (match_operand:XF 0 "register_operand" "")
17458         (plus:XF (match_dup 12) (match_dup 7)))]
17459   "TARGET_USE_FANCY_MATH_387
17460    && flag_unsafe_math_optimizations && !optimize_size"
17461 {
17462   int i;
17463
17464   for (i = 2; i < 13; i++)
17465     operands[i] = gen_reg_rtx (XFmode);
17466
17467   operands[13]
17468     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17469
17470   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17471 })
17472
17473 (define_expand "expm1<mode>2"
17474   [(use (match_operand:MODEF 0 "register_operand" ""))
17475    (use (match_operand:MODEF 1 "general_operand" ""))]
17476  "TARGET_USE_FANCY_MATH_387
17477    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17478        || TARGET_MIX_SSE_I387)
17479    && flag_unsafe_math_optimizations && !optimize_size"
17480 {
17481   rtx op0 = gen_reg_rtx (XFmode);
17482   rtx op1 = gen_reg_rtx (XFmode);
17483
17484   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17485   emit_insn (gen_expm1xf2 (op0, op1));
17486   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17487   DONE;
17488 })
17489
17490 (define_expand "ldexpxf3"
17491   [(set (match_dup 3)
17492         (float:XF (match_operand:SI 2 "register_operand" "")))
17493    (parallel [(set (match_operand:XF 0 " register_operand" "")
17494                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17495                                (match_dup 3)]
17496                               UNSPEC_FSCALE_FRACT))
17497               (set (match_dup 4)
17498                    (unspec:XF [(match_dup 1) (match_dup 3)]
17499                               UNSPEC_FSCALE_EXP))])]
17500   "TARGET_USE_FANCY_MATH_387
17501    && flag_unsafe_math_optimizations && !optimize_size"
17502 {
17503   operands[3] = gen_reg_rtx (XFmode);
17504   operands[4] = gen_reg_rtx (XFmode);
17505 })
17506
17507 (define_expand "ldexp<mode>3"
17508   [(use (match_operand:MODEF 0 "register_operand" ""))
17509    (use (match_operand:MODEF 1 "general_operand" ""))
17510    (use (match_operand:SI 2 "register_operand" ""))]
17511  "TARGET_USE_FANCY_MATH_387
17512    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17513        || TARGET_MIX_SSE_I387)
17514    && flag_unsafe_math_optimizations && !optimize_size"
17515 {
17516   rtx op0 = gen_reg_rtx (XFmode);
17517   rtx op1 = gen_reg_rtx (XFmode);
17518
17519   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17520   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17521   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17522   DONE;
17523 })
17524
17525 (define_expand "scalbxf3"
17526   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17527                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17528                                (match_operand:XF 2 "register_operand" "")]
17529                               UNSPEC_FSCALE_FRACT))
17530               (set (match_dup 3)
17531                    (unspec:XF [(match_dup 1) (match_dup 2)]
17532                               UNSPEC_FSCALE_EXP))])]
17533   "TARGET_USE_FANCY_MATH_387
17534    && flag_unsafe_math_optimizations && !optimize_size"
17535 {
17536   operands[3] = gen_reg_rtx (XFmode);
17537 })
17538
17539 (define_expand "scalb<mode>3"
17540   [(use (match_operand:MODEF 0 "register_operand" ""))
17541    (use (match_operand:MODEF 1 "general_operand" ""))
17542    (use (match_operand:MODEF 2 "register_operand" ""))]
17543  "TARGET_USE_FANCY_MATH_387
17544    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17545        || TARGET_MIX_SSE_I387)
17546    && flag_unsafe_math_optimizations && !optimize_size"
17547 {
17548   rtx op0 = gen_reg_rtx (XFmode);
17549   rtx op1 = gen_reg_rtx (XFmode);
17550   rtx op2 = gen_reg_rtx (XFmode);
17551
17552   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17553   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17554   emit_insn (gen_scalbxf3 (op0, op1, op2));
17555   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17556   DONE;
17557 })
17558 \f
17559
17560 (define_insn "sse4_1_round<mode>2"
17561   [(set (match_operand:MODEF 0 "register_operand" "=x")
17562         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17563                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
17564                       UNSPEC_ROUND))]
17565   "TARGET_ROUND"
17566   "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17567   [(set_attr "type" "ssecvt")
17568    (set_attr "prefix_extra" "1")
17569    (set_attr "mode" "<MODE>")])
17570
17571 (define_insn "rintxf2"
17572   [(set (match_operand:XF 0 "register_operand" "=f")
17573         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17574                    UNSPEC_FRNDINT))]
17575   "TARGET_USE_FANCY_MATH_387
17576    && flag_unsafe_math_optimizations"
17577   "frndint"
17578   [(set_attr "type" "fpspc")
17579    (set_attr "mode" "XF")])
17580
17581 (define_expand "rint<mode>2"
17582   [(use (match_operand:MODEF 0 "register_operand" ""))
17583    (use (match_operand:MODEF 1 "register_operand" ""))]
17584   "(TARGET_USE_FANCY_MATH_387
17585     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17586         || TARGET_MIX_SSE_I387)
17587     && flag_unsafe_math_optimizations)
17588    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17589        && !flag_trapping_math
17590        && (TARGET_ROUND || !optimize_size))"
17591 {
17592   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17593       && !flag_trapping_math
17594       && (TARGET_ROUND || !optimize_size))
17595     {
17596       if (TARGET_ROUND)
17597         emit_insn (gen_sse4_1_round<mode>2
17598                    (operands[0], operands[1], GEN_INT (0x04)));
17599       else
17600         ix86_expand_rint (operand0, operand1);
17601     }
17602   else
17603     {
17604       rtx op0 = gen_reg_rtx (XFmode);
17605       rtx op1 = gen_reg_rtx (XFmode);
17606
17607       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17608       emit_insn (gen_rintxf2 (op0, op1));
17609
17610       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17611     }
17612   DONE;
17613 })
17614
17615 (define_expand "round<mode>2"
17616   [(match_operand:MODEF 0 "register_operand" "")
17617    (match_operand:MODEF 1 "nonimmediate_operand" "")]
17618   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17619    && !flag_trapping_math && !flag_rounding_math
17620    && !optimize_size"
17621 {
17622   if (TARGET_64BIT || (<MODE>mode != DFmode))
17623     ix86_expand_round (operand0, operand1);
17624   else
17625     ix86_expand_rounddf_32 (operand0, operand1);
17626   DONE;
17627 })
17628
17629 (define_insn_and_split "*fistdi2_1"
17630   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17631         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17632                    UNSPEC_FIST))]
17633   "TARGET_USE_FANCY_MATH_387
17634    && !(reload_completed || reload_in_progress)"
17635   "#"
17636   "&& 1"
17637   [(const_int 0)]
17638 {
17639   if (memory_operand (operands[0], VOIDmode))
17640     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17641   else
17642     {
17643       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17644       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17645                                          operands[2]));
17646     }
17647   DONE;
17648 }
17649   [(set_attr "type" "fpspc")
17650    (set_attr "mode" "DI")])
17651
17652 (define_insn "fistdi2"
17653   [(set (match_operand:DI 0 "memory_operand" "=m")
17654         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17655                    UNSPEC_FIST))
17656    (clobber (match_scratch:XF 2 "=&1f"))]
17657   "TARGET_USE_FANCY_MATH_387"
17658   "* return output_fix_trunc (insn, operands, 0);"
17659   [(set_attr "type" "fpspc")
17660    (set_attr "mode" "DI")])
17661
17662 (define_insn "fistdi2_with_temp"
17663   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17664         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17665                    UNSPEC_FIST))
17666    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17667    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17668   "TARGET_USE_FANCY_MATH_387"
17669   "#"
17670   [(set_attr "type" "fpspc")
17671    (set_attr "mode" "DI")])
17672
17673 (define_split
17674   [(set (match_operand:DI 0 "register_operand" "")
17675         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17676                    UNSPEC_FIST))
17677    (clobber (match_operand:DI 2 "memory_operand" ""))
17678    (clobber (match_scratch 3 ""))]
17679   "reload_completed"
17680   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17681               (clobber (match_dup 3))])
17682    (set (match_dup 0) (match_dup 2))]
17683   "")
17684
17685 (define_split
17686   [(set (match_operand:DI 0 "memory_operand" "")
17687         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17688                    UNSPEC_FIST))
17689    (clobber (match_operand:DI 2 "memory_operand" ""))
17690    (clobber (match_scratch 3 ""))]
17691   "reload_completed"
17692   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17693               (clobber (match_dup 3))])]
17694   "")
17695
17696 (define_insn_and_split "*fist<mode>2_1"
17697   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17698         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17699                            UNSPEC_FIST))]
17700   "TARGET_USE_FANCY_MATH_387
17701    && !(reload_completed || reload_in_progress)"
17702   "#"
17703   "&& 1"
17704   [(const_int 0)]
17705 {
17706   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17707   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17708                                         operands[2]));
17709   DONE;
17710 }
17711   [(set_attr "type" "fpspc")
17712    (set_attr "mode" "<MODE>")])
17713
17714 (define_insn "fist<mode>2"
17715   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17716         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17717                            UNSPEC_FIST))]
17718   "TARGET_USE_FANCY_MATH_387"
17719   "* return output_fix_trunc (insn, operands, 0);"
17720   [(set_attr "type" "fpspc")
17721    (set_attr "mode" "<MODE>")])
17722
17723 (define_insn "fist<mode>2_with_temp"
17724   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17725         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17726                            UNSPEC_FIST))
17727    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17728   "TARGET_USE_FANCY_MATH_387"
17729   "#"
17730   [(set_attr "type" "fpspc")
17731    (set_attr "mode" "<MODE>")])
17732
17733 (define_split
17734   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17735         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17736                            UNSPEC_FIST))
17737    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17738   "reload_completed"
17739   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17740    (set (match_dup 0) (match_dup 2))]
17741   "")
17742
17743 (define_split
17744   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17745         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17746                            UNSPEC_FIST))
17747    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17748   "reload_completed"
17749   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17750   "")
17751
17752 (define_expand "lrintxf<mode>2"
17753   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17754      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17755                       UNSPEC_FIST))]
17756   "TARGET_USE_FANCY_MATH_387"
17757   "")
17758
17759 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17760   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17761      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17762                         UNSPEC_FIX_NOTRUNC))]
17763   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17764    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17765   "")
17766
17767 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17768   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17769    (match_operand:MODEF 1 "register_operand" "")]
17770   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17771    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17772    && !flag_trapping_math && !flag_rounding_math
17773    && !optimize_size"
17774 {
17775   ix86_expand_lround (operand0, operand1);
17776   DONE;
17777 })
17778
17779 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17780 (define_insn_and_split "frndintxf2_floor"
17781   [(set (match_operand:XF 0 "register_operand" "")
17782         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17783          UNSPEC_FRNDINT_FLOOR))
17784    (clobber (reg:CC FLAGS_REG))]
17785   "TARGET_USE_FANCY_MATH_387
17786    && flag_unsafe_math_optimizations
17787    && !(reload_completed || reload_in_progress)"
17788   "#"
17789   "&& 1"
17790   [(const_int 0)]
17791 {
17792   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17793
17794   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17795   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17796
17797   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17798                                         operands[2], operands[3]));
17799   DONE;
17800 }
17801   [(set_attr "type" "frndint")
17802    (set_attr "i387_cw" "floor")
17803    (set_attr "mode" "XF")])
17804
17805 (define_insn "frndintxf2_floor_i387"
17806   [(set (match_operand:XF 0 "register_operand" "=f")
17807         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17808          UNSPEC_FRNDINT_FLOOR))
17809    (use (match_operand:HI 2 "memory_operand" "m"))
17810    (use (match_operand:HI 3 "memory_operand" "m"))]
17811   "TARGET_USE_FANCY_MATH_387
17812    && flag_unsafe_math_optimizations"
17813   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17814   [(set_attr "type" "frndint")
17815    (set_attr "i387_cw" "floor")
17816    (set_attr "mode" "XF")])
17817
17818 (define_expand "floorxf2"
17819   [(use (match_operand:XF 0 "register_operand" ""))
17820    (use (match_operand:XF 1 "register_operand" ""))]
17821   "TARGET_USE_FANCY_MATH_387
17822    && flag_unsafe_math_optimizations && !optimize_size"
17823 {
17824   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17825   DONE;
17826 })
17827
17828 (define_expand "floor<mode>2"
17829   [(use (match_operand:MODEF 0 "register_operand" ""))
17830    (use (match_operand:MODEF 1 "register_operand" ""))]
17831   "(TARGET_USE_FANCY_MATH_387
17832     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17833         || TARGET_MIX_SSE_I387)
17834     && flag_unsafe_math_optimizations && !optimize_size)
17835    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17836        && !flag_trapping_math
17837        && (TARGET_ROUND || !optimize_size))"
17838 {
17839   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17840       && !flag_trapping_math
17841       && (TARGET_ROUND || !optimize_size))
17842     {
17843       if (TARGET_ROUND)
17844         emit_insn (gen_sse4_1_round<mode>2
17845                    (operands[0], operands[1], GEN_INT (0x01)));
17846       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17847         ix86_expand_floorceil (operand0, operand1, true);
17848       else
17849         ix86_expand_floorceildf_32 (operand0, operand1, true);
17850     }
17851   else
17852     {
17853       rtx op0 = gen_reg_rtx (XFmode);
17854       rtx op1 = gen_reg_rtx (XFmode);
17855
17856       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17857       emit_insn (gen_frndintxf2_floor (op0, op1));
17858
17859       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17860     }
17861   DONE;
17862 })
17863
17864 (define_insn_and_split "*fist<mode>2_floor_1"
17865   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17866         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17867          UNSPEC_FIST_FLOOR))
17868    (clobber (reg:CC FLAGS_REG))]
17869   "TARGET_USE_FANCY_MATH_387
17870    && flag_unsafe_math_optimizations
17871    && !(reload_completed || reload_in_progress)"
17872   "#"
17873   "&& 1"
17874   [(const_int 0)]
17875 {
17876   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17877
17878   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17879   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17880   if (memory_operand (operands[0], VOIDmode))
17881     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17882                                       operands[2], operands[3]));
17883   else
17884     {
17885       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17886       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17887                                                   operands[2], operands[3],
17888                                                   operands[4]));
17889     }
17890   DONE;
17891 }
17892   [(set_attr "type" "fistp")
17893    (set_attr "i387_cw" "floor")
17894    (set_attr "mode" "<MODE>")])
17895
17896 (define_insn "fistdi2_floor"
17897   [(set (match_operand:DI 0 "memory_operand" "=m")
17898         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17899          UNSPEC_FIST_FLOOR))
17900    (use (match_operand:HI 2 "memory_operand" "m"))
17901    (use (match_operand:HI 3 "memory_operand" "m"))
17902    (clobber (match_scratch:XF 4 "=&1f"))]
17903   "TARGET_USE_FANCY_MATH_387
17904    && flag_unsafe_math_optimizations"
17905   "* return output_fix_trunc (insn, operands, 0);"
17906   [(set_attr "type" "fistp")
17907    (set_attr "i387_cw" "floor")
17908    (set_attr "mode" "DI")])
17909
17910 (define_insn "fistdi2_floor_with_temp"
17911   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17912         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17913          UNSPEC_FIST_FLOOR))
17914    (use (match_operand:HI 2 "memory_operand" "m,m"))
17915    (use (match_operand:HI 3 "memory_operand" "m,m"))
17916    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17917    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17918   "TARGET_USE_FANCY_MATH_387
17919    && flag_unsafe_math_optimizations"
17920   "#"
17921   [(set_attr "type" "fistp")
17922    (set_attr "i387_cw" "floor")
17923    (set_attr "mode" "DI")])
17924
17925 (define_split
17926   [(set (match_operand:DI 0 "register_operand" "")
17927         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17928          UNSPEC_FIST_FLOOR))
17929    (use (match_operand:HI 2 "memory_operand" ""))
17930    (use (match_operand:HI 3 "memory_operand" ""))
17931    (clobber (match_operand:DI 4 "memory_operand" ""))
17932    (clobber (match_scratch 5 ""))]
17933   "reload_completed"
17934   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17935               (use (match_dup 2))
17936               (use (match_dup 3))
17937               (clobber (match_dup 5))])
17938    (set (match_dup 0) (match_dup 4))]
17939   "")
17940
17941 (define_split
17942   [(set (match_operand:DI 0 "memory_operand" "")
17943         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17944          UNSPEC_FIST_FLOOR))
17945    (use (match_operand:HI 2 "memory_operand" ""))
17946    (use (match_operand:HI 3 "memory_operand" ""))
17947    (clobber (match_operand:DI 4 "memory_operand" ""))
17948    (clobber (match_scratch 5 ""))]
17949   "reload_completed"
17950   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17951               (use (match_dup 2))
17952               (use (match_dup 3))
17953               (clobber (match_dup 5))])]
17954   "")
17955
17956 (define_insn "fist<mode>2_floor"
17957   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17958         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17959          UNSPEC_FIST_FLOOR))
17960    (use (match_operand:HI 2 "memory_operand" "m"))
17961    (use (match_operand:HI 3 "memory_operand" "m"))]
17962   "TARGET_USE_FANCY_MATH_387
17963    && flag_unsafe_math_optimizations"
17964   "* return output_fix_trunc (insn, operands, 0);"
17965   [(set_attr "type" "fistp")
17966    (set_attr "i387_cw" "floor")
17967    (set_attr "mode" "<MODE>")])
17968
17969 (define_insn "fist<mode>2_floor_with_temp"
17970   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17971         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17972          UNSPEC_FIST_FLOOR))
17973    (use (match_operand:HI 2 "memory_operand" "m,m"))
17974    (use (match_operand:HI 3 "memory_operand" "m,m"))
17975    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17976   "TARGET_USE_FANCY_MATH_387
17977    && flag_unsafe_math_optimizations"
17978   "#"
17979   [(set_attr "type" "fistp")
17980    (set_attr "i387_cw" "floor")
17981    (set_attr "mode" "<MODE>")])
17982
17983 (define_split
17984   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17985         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17986          UNSPEC_FIST_FLOOR))
17987    (use (match_operand:HI 2 "memory_operand" ""))
17988    (use (match_operand:HI 3 "memory_operand" ""))
17989    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17990   "reload_completed"
17991   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17992                                   UNSPEC_FIST_FLOOR))
17993               (use (match_dup 2))
17994               (use (match_dup 3))])
17995    (set (match_dup 0) (match_dup 4))]
17996   "")
17997
17998 (define_split
17999   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18000         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18001          UNSPEC_FIST_FLOOR))
18002    (use (match_operand:HI 2 "memory_operand" ""))
18003    (use (match_operand:HI 3 "memory_operand" ""))
18004    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18005   "reload_completed"
18006   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18007                                   UNSPEC_FIST_FLOOR))
18008               (use (match_dup 2))
18009               (use (match_dup 3))])]
18010   "")
18011
18012 (define_expand "lfloorxf<mode>2"
18013   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18014                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18015                     UNSPEC_FIST_FLOOR))
18016               (clobber (reg:CC FLAGS_REG))])]
18017   "TARGET_USE_FANCY_MATH_387
18018    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18019    && flag_unsafe_math_optimizations"
18020   "")
18021
18022 (define_expand "lfloor<mode>di2"
18023   [(match_operand:DI 0 "nonimmediate_operand" "")
18024    (match_operand:MODEF 1 "register_operand" "")]
18025   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18026    && !flag_trapping_math
18027    && !optimize_size"
18028 {
18029   ix86_expand_lfloorceil (operand0, operand1, true);
18030   DONE;
18031 })
18032
18033 (define_expand "lfloor<mode>si2"
18034   [(match_operand:SI 0 "nonimmediate_operand" "")
18035    (match_operand:MODEF 1 "register_operand" "")]
18036   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18037    && !flag_trapping_math
18038    && (!optimize_size || !TARGET_64BIT)"
18039 {
18040   ix86_expand_lfloorceil (operand0, operand1, true);
18041   DONE;
18042 })
18043
18044 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18045 (define_insn_and_split "frndintxf2_ceil"
18046   [(set (match_operand:XF 0 "register_operand" "")
18047         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18048          UNSPEC_FRNDINT_CEIL))
18049    (clobber (reg:CC FLAGS_REG))]
18050   "TARGET_USE_FANCY_MATH_387
18051    && flag_unsafe_math_optimizations
18052    && !(reload_completed || reload_in_progress)"
18053   "#"
18054   "&& 1"
18055   [(const_int 0)]
18056 {
18057   ix86_optimize_mode_switching[I387_CEIL] = 1;
18058
18059   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18060   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18061
18062   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18063                                        operands[2], operands[3]));
18064   DONE;
18065 }
18066   [(set_attr "type" "frndint")
18067    (set_attr "i387_cw" "ceil")
18068    (set_attr "mode" "XF")])
18069
18070 (define_insn "frndintxf2_ceil_i387"
18071   [(set (match_operand:XF 0 "register_operand" "=f")
18072         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18073          UNSPEC_FRNDINT_CEIL))
18074    (use (match_operand:HI 2 "memory_operand" "m"))
18075    (use (match_operand:HI 3 "memory_operand" "m"))]
18076   "TARGET_USE_FANCY_MATH_387
18077    && flag_unsafe_math_optimizations"
18078   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18079   [(set_attr "type" "frndint")
18080    (set_attr "i387_cw" "ceil")
18081    (set_attr "mode" "XF")])
18082
18083 (define_expand "ceilxf2"
18084   [(use (match_operand:XF 0 "register_operand" ""))
18085    (use (match_operand:XF 1 "register_operand" ""))]
18086   "TARGET_USE_FANCY_MATH_387
18087    && flag_unsafe_math_optimizations && !optimize_size"
18088 {
18089   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18090   DONE;
18091 })
18092
18093 (define_expand "ceil<mode>2"
18094   [(use (match_operand:MODEF 0 "register_operand" ""))
18095    (use (match_operand:MODEF 1 "register_operand" ""))]
18096   "(TARGET_USE_FANCY_MATH_387
18097     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18098         || TARGET_MIX_SSE_I387)
18099     && flag_unsafe_math_optimizations && !optimize_size)
18100    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18101        && !flag_trapping_math
18102        && (TARGET_ROUND || !optimize_size))"
18103 {
18104   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18105       && !flag_trapping_math
18106       && (TARGET_ROUND || !optimize_size))
18107     {
18108       if (TARGET_ROUND)
18109         emit_insn (gen_sse4_1_round<mode>2
18110                    (operands[0], operands[1], GEN_INT (0x02)));
18111       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18112         ix86_expand_floorceil (operand0, operand1, false);
18113       else
18114         ix86_expand_floorceildf_32 (operand0, operand1, false);
18115     }
18116   else
18117     {
18118       rtx op0 = gen_reg_rtx (XFmode);
18119       rtx op1 = gen_reg_rtx (XFmode);
18120
18121       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18122       emit_insn (gen_frndintxf2_ceil (op0, op1));
18123
18124       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18125     }
18126   DONE;
18127 })
18128
18129 (define_insn_and_split "*fist<mode>2_ceil_1"
18130   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18131         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18132          UNSPEC_FIST_CEIL))
18133    (clobber (reg:CC FLAGS_REG))]
18134   "TARGET_USE_FANCY_MATH_387
18135    && flag_unsafe_math_optimizations
18136    && !(reload_completed || reload_in_progress)"
18137   "#"
18138   "&& 1"
18139   [(const_int 0)]
18140 {
18141   ix86_optimize_mode_switching[I387_CEIL] = 1;
18142
18143   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18144   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18145   if (memory_operand (operands[0], VOIDmode))
18146     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18147                                      operands[2], operands[3]));
18148   else
18149     {
18150       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18151       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18152                                                  operands[2], operands[3],
18153                                                  operands[4]));
18154     }
18155   DONE;
18156 }
18157   [(set_attr "type" "fistp")
18158    (set_attr "i387_cw" "ceil")
18159    (set_attr "mode" "<MODE>")])
18160
18161 (define_insn "fistdi2_ceil"
18162   [(set (match_operand:DI 0 "memory_operand" "=m")
18163         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18164          UNSPEC_FIST_CEIL))
18165    (use (match_operand:HI 2 "memory_operand" "m"))
18166    (use (match_operand:HI 3 "memory_operand" "m"))
18167    (clobber (match_scratch:XF 4 "=&1f"))]
18168   "TARGET_USE_FANCY_MATH_387
18169    && flag_unsafe_math_optimizations"
18170   "* return output_fix_trunc (insn, operands, 0);"
18171   [(set_attr "type" "fistp")
18172    (set_attr "i387_cw" "ceil")
18173    (set_attr "mode" "DI")])
18174
18175 (define_insn "fistdi2_ceil_with_temp"
18176   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18177         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18178          UNSPEC_FIST_CEIL))
18179    (use (match_operand:HI 2 "memory_operand" "m,m"))
18180    (use (match_operand:HI 3 "memory_operand" "m,m"))
18181    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
18182    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18183   "TARGET_USE_FANCY_MATH_387
18184    && flag_unsafe_math_optimizations"
18185   "#"
18186   [(set_attr "type" "fistp")
18187    (set_attr "i387_cw" "ceil")
18188    (set_attr "mode" "DI")])
18189
18190 (define_split
18191   [(set (match_operand:DI 0 "register_operand" "")
18192         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18193          UNSPEC_FIST_CEIL))
18194    (use (match_operand:HI 2 "memory_operand" ""))
18195    (use (match_operand:HI 3 "memory_operand" ""))
18196    (clobber (match_operand:DI 4 "memory_operand" ""))
18197    (clobber (match_scratch 5 ""))]
18198   "reload_completed"
18199   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18200               (use (match_dup 2))
18201               (use (match_dup 3))
18202               (clobber (match_dup 5))])
18203    (set (match_dup 0) (match_dup 4))]
18204   "")
18205
18206 (define_split
18207   [(set (match_operand:DI 0 "memory_operand" "")
18208         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18209          UNSPEC_FIST_CEIL))
18210    (use (match_operand:HI 2 "memory_operand" ""))
18211    (use (match_operand:HI 3 "memory_operand" ""))
18212    (clobber (match_operand:DI 4 "memory_operand" ""))
18213    (clobber (match_scratch 5 ""))]
18214   "reload_completed"
18215   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18216               (use (match_dup 2))
18217               (use (match_dup 3))
18218               (clobber (match_dup 5))])]
18219   "")
18220
18221 (define_insn "fist<mode>2_ceil"
18222   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18223         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18224          UNSPEC_FIST_CEIL))
18225    (use (match_operand:HI 2 "memory_operand" "m"))
18226    (use (match_operand:HI 3 "memory_operand" "m"))]
18227   "TARGET_USE_FANCY_MATH_387
18228    && flag_unsafe_math_optimizations"
18229   "* return output_fix_trunc (insn, operands, 0);"
18230   [(set_attr "type" "fistp")
18231    (set_attr "i387_cw" "ceil")
18232    (set_attr "mode" "<MODE>")])
18233
18234 (define_insn "fist<mode>2_ceil_with_temp"
18235   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18236         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18237          UNSPEC_FIST_CEIL))
18238    (use (match_operand:HI 2 "memory_operand" "m,m"))
18239    (use (match_operand:HI 3 "memory_operand" "m,m"))
18240    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18241   "TARGET_USE_FANCY_MATH_387
18242    && flag_unsafe_math_optimizations"
18243   "#"
18244   [(set_attr "type" "fistp")
18245    (set_attr "i387_cw" "ceil")
18246    (set_attr "mode" "<MODE>")])
18247
18248 (define_split
18249   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18250         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18251          UNSPEC_FIST_CEIL))
18252    (use (match_operand:HI 2 "memory_operand" ""))
18253    (use (match_operand:HI 3 "memory_operand" ""))
18254    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18255   "reload_completed"
18256   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18257                                   UNSPEC_FIST_CEIL))
18258               (use (match_dup 2))
18259               (use (match_dup 3))])
18260    (set (match_dup 0) (match_dup 4))]
18261   "")
18262
18263 (define_split
18264   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18265         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18266          UNSPEC_FIST_CEIL))
18267    (use (match_operand:HI 2 "memory_operand" ""))
18268    (use (match_operand:HI 3 "memory_operand" ""))
18269    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18270   "reload_completed"
18271   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18272                                   UNSPEC_FIST_CEIL))
18273               (use (match_dup 2))
18274               (use (match_dup 3))])]
18275   "")
18276
18277 (define_expand "lceilxf<mode>2"
18278   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18279                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18280                     UNSPEC_FIST_CEIL))
18281               (clobber (reg:CC FLAGS_REG))])]
18282   "TARGET_USE_FANCY_MATH_387
18283    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18284    && flag_unsafe_math_optimizations"
18285   "")
18286
18287 (define_expand "lceil<mode>di2"
18288   [(match_operand:DI 0 "nonimmediate_operand" "")
18289    (match_operand:MODEF 1 "register_operand" "")]
18290   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18291    && !flag_trapping_math"
18292 {
18293   ix86_expand_lfloorceil (operand0, operand1, false);
18294   DONE;
18295 })
18296
18297 (define_expand "lceil<mode>si2"
18298   [(match_operand:SI 0 "nonimmediate_operand" "")
18299    (match_operand:MODEF 1 "register_operand" "")]
18300   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18301    && !flag_trapping_math"
18302 {
18303   ix86_expand_lfloorceil (operand0, operand1, false);
18304   DONE;
18305 })
18306
18307 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18308 (define_insn_and_split "frndintxf2_trunc"
18309   [(set (match_operand:XF 0 "register_operand" "")
18310         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18311          UNSPEC_FRNDINT_TRUNC))
18312    (clobber (reg:CC FLAGS_REG))]
18313   "TARGET_USE_FANCY_MATH_387
18314    && flag_unsafe_math_optimizations
18315    && !(reload_completed || reload_in_progress)"
18316   "#"
18317   "&& 1"
18318   [(const_int 0)]
18319 {
18320   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18321
18322   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18323   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18324
18325   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18326                                         operands[2], operands[3]));
18327   DONE;
18328 }
18329   [(set_attr "type" "frndint")
18330    (set_attr "i387_cw" "trunc")
18331    (set_attr "mode" "XF")])
18332
18333 (define_insn "frndintxf2_trunc_i387"
18334   [(set (match_operand:XF 0 "register_operand" "=f")
18335         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18336          UNSPEC_FRNDINT_TRUNC))
18337    (use (match_operand:HI 2 "memory_operand" "m"))
18338    (use (match_operand:HI 3 "memory_operand" "m"))]
18339   "TARGET_USE_FANCY_MATH_387
18340    && flag_unsafe_math_optimizations"
18341   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18342   [(set_attr "type" "frndint")
18343    (set_attr "i387_cw" "trunc")
18344    (set_attr "mode" "XF")])
18345
18346 (define_expand "btruncxf2"
18347   [(use (match_operand:XF 0 "register_operand" ""))
18348    (use (match_operand:XF 1 "register_operand" ""))]
18349   "TARGET_USE_FANCY_MATH_387
18350    && flag_unsafe_math_optimizations && !optimize_size"
18351 {
18352   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18353   DONE;
18354 })
18355
18356 (define_expand "btrunc<mode>2"
18357   [(use (match_operand:MODEF 0 "register_operand" ""))
18358    (use (match_operand:MODEF 1 "register_operand" ""))]
18359   "(TARGET_USE_FANCY_MATH_387
18360     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18361         || TARGET_MIX_SSE_I387)
18362     && flag_unsafe_math_optimizations && !optimize_size)
18363    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18364        && !flag_trapping_math
18365        && (TARGET_ROUND || !optimize_size))"
18366 {
18367   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18368       && !flag_trapping_math
18369       && (TARGET_ROUND || !optimize_size))
18370     {
18371       if (TARGET_ROUND)
18372         emit_insn (gen_sse4_1_round<mode>2
18373                    (operands[0], operands[1], GEN_INT (0x03)));
18374       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18375         ix86_expand_trunc (operand0, operand1);
18376       else
18377         ix86_expand_truncdf_32 (operand0, operand1);
18378     }
18379   else
18380     {
18381       rtx op0 = gen_reg_rtx (XFmode);
18382       rtx op1 = gen_reg_rtx (XFmode);
18383
18384       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18385       emit_insn (gen_frndintxf2_trunc (op0, op1));
18386
18387       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18388     }
18389   DONE;
18390 })
18391
18392 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18393 (define_insn_and_split "frndintxf2_mask_pm"
18394   [(set (match_operand:XF 0 "register_operand" "")
18395         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18396          UNSPEC_FRNDINT_MASK_PM))
18397    (clobber (reg:CC FLAGS_REG))]
18398   "TARGET_USE_FANCY_MATH_387
18399    && flag_unsafe_math_optimizations
18400    && !(reload_completed || reload_in_progress)"
18401   "#"
18402   "&& 1"
18403   [(const_int 0)]
18404 {
18405   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18406
18407   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18408   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18409
18410   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18411                                           operands[2], operands[3]));
18412   DONE;
18413 }
18414   [(set_attr "type" "frndint")
18415    (set_attr "i387_cw" "mask_pm")
18416    (set_attr "mode" "XF")])
18417
18418 (define_insn "frndintxf2_mask_pm_i387"
18419   [(set (match_operand:XF 0 "register_operand" "=f")
18420         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18421          UNSPEC_FRNDINT_MASK_PM))
18422    (use (match_operand:HI 2 "memory_operand" "m"))
18423    (use (match_operand:HI 3 "memory_operand" "m"))]
18424   "TARGET_USE_FANCY_MATH_387
18425    && flag_unsafe_math_optimizations"
18426   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18427   [(set_attr "type" "frndint")
18428    (set_attr "i387_cw" "mask_pm")
18429    (set_attr "mode" "XF")])
18430
18431 (define_expand "nearbyintxf2"
18432   [(use (match_operand:XF 0 "register_operand" ""))
18433    (use (match_operand:XF 1 "register_operand" ""))]
18434   "TARGET_USE_FANCY_MATH_387
18435    && flag_unsafe_math_optimizations"
18436 {
18437   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18438
18439   DONE;
18440 })
18441
18442 (define_expand "nearbyint<mode>2"
18443   [(use (match_operand:MODEF 0 "register_operand" ""))
18444    (use (match_operand:MODEF 1 "register_operand" ""))]
18445   "TARGET_USE_FANCY_MATH_387
18446    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18447        || TARGET_MIX_SSE_I387)
18448    && flag_unsafe_math_optimizations"
18449 {
18450   rtx op0 = gen_reg_rtx (XFmode);
18451   rtx op1 = gen_reg_rtx (XFmode);
18452
18453   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18454   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18455
18456   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18457   DONE;
18458 })
18459
18460 (define_insn "fxam<mode>2_i387"
18461   [(set (match_operand:HI 0 "register_operand" "=a")
18462         (unspec:HI
18463           [(match_operand:X87MODEF 1 "register_operand" "f")]
18464           UNSPEC_FXAM))]
18465   "TARGET_USE_FANCY_MATH_387"
18466   "fxam\n\tfnstsw\t%0"
18467   [(set_attr "type" "multi")
18468    (set_attr "unit" "i387")
18469    (set_attr "mode" "<MODE>")])
18470
18471 (define_expand "isinf<mode>2"
18472   [(use (match_operand:SI 0 "register_operand" ""))
18473    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18474   "TARGET_USE_FANCY_MATH_387
18475    && TARGET_C99_FUNCTIONS
18476    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18477 {
18478   rtx mask = GEN_INT (0x45);
18479   rtx val = GEN_INT (0x05);
18480
18481   rtx cond;
18482
18483   rtx scratch = gen_reg_rtx (HImode);
18484   rtx res = gen_reg_rtx (QImode);
18485
18486   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18487   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18488   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18489   cond = gen_rtx_fmt_ee (EQ, QImode,
18490                          gen_rtx_REG (CCmode, FLAGS_REG),
18491                          const0_rtx);
18492   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18493   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18494   DONE;
18495 })
18496
18497 (define_expand "signbit<mode>2"
18498   [(use (match_operand:SI 0 "register_operand" ""))
18499    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18500   "TARGET_USE_FANCY_MATH_387
18501    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18502 {
18503   rtx mask = GEN_INT (0x0200);
18504
18505   rtx scratch = gen_reg_rtx (HImode);
18506
18507   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18508   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18509   DONE;
18510 })
18511 \f
18512 ;; Block operation instructions
18513
18514 (define_expand "movmemsi"
18515   [(use (match_operand:BLK 0 "memory_operand" ""))
18516    (use (match_operand:BLK 1 "memory_operand" ""))
18517    (use (match_operand:SI 2 "nonmemory_operand" ""))
18518    (use (match_operand:SI 3 "const_int_operand" ""))
18519    (use (match_operand:SI 4 "const_int_operand" ""))
18520    (use (match_operand:SI 5 "const_int_operand" ""))]
18521   ""
18522 {
18523  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18524                          operands[4], operands[5]))
18525    DONE;
18526  else
18527    FAIL;
18528 })
18529
18530 (define_expand "movmemdi"
18531   [(use (match_operand:BLK 0 "memory_operand" ""))
18532    (use (match_operand:BLK 1 "memory_operand" ""))
18533    (use (match_operand:DI 2 "nonmemory_operand" ""))
18534    (use (match_operand:DI 3 "const_int_operand" ""))
18535    (use (match_operand:SI 4 "const_int_operand" ""))
18536    (use (match_operand:SI 5 "const_int_operand" ""))]
18537   "TARGET_64BIT"
18538 {
18539  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18540                          operands[4], operands[5]))
18541    DONE;
18542  else
18543    FAIL;
18544 })
18545
18546 ;; Most CPUs don't like single string operations
18547 ;; Handle this case here to simplify previous expander.
18548
18549 (define_expand "strmov"
18550   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18551    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18552    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18553               (clobber (reg:CC FLAGS_REG))])
18554    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18555               (clobber (reg:CC FLAGS_REG))])]
18556   ""
18557 {
18558   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18559
18560   /* If .md ever supports :P for Pmode, these can be directly
18561      in the pattern above.  */
18562   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18563   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18564
18565   /* Can't use this if the user has appropriated esi or edi.  */
18566   if ((TARGET_SINGLE_STRINGOP || optimize_size)
18567       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18568     {
18569       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18570                                       operands[2], operands[3],
18571                                       operands[5], operands[6]));
18572       DONE;
18573     }
18574
18575   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18576 })
18577
18578 (define_expand "strmov_singleop"
18579   [(parallel [(set (match_operand 1 "memory_operand" "")
18580                    (match_operand 3 "memory_operand" ""))
18581               (set (match_operand 0 "register_operand" "")
18582                    (match_operand 4 "" ""))
18583               (set (match_operand 2 "register_operand" "")
18584                    (match_operand 5 "" ""))])]
18585   "TARGET_SINGLE_STRINGOP || optimize_size"
18586   "")
18587
18588 (define_insn "*strmovdi_rex_1"
18589   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18590         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18591    (set (match_operand:DI 0 "register_operand" "=D")
18592         (plus:DI (match_dup 2)
18593                  (const_int 8)))
18594    (set (match_operand:DI 1 "register_operand" "=S")
18595         (plus:DI (match_dup 3)
18596                  (const_int 8)))]
18597   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18598   "movsq"
18599   [(set_attr "type" "str")
18600    (set_attr "mode" "DI")
18601    (set_attr "memory" "both")])
18602
18603 (define_insn "*strmovsi_1"
18604   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18605         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18606    (set (match_operand:SI 0 "register_operand" "=D")
18607         (plus:SI (match_dup 2)
18608                  (const_int 4)))
18609    (set (match_operand:SI 1 "register_operand" "=S")
18610         (plus:SI (match_dup 3)
18611                  (const_int 4)))]
18612   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18613   "{movsl|movsd}"
18614   [(set_attr "type" "str")
18615    (set_attr "mode" "SI")
18616    (set_attr "memory" "both")])
18617
18618 (define_insn "*strmovsi_rex_1"
18619   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18620         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18621    (set (match_operand:DI 0 "register_operand" "=D")
18622         (plus:DI (match_dup 2)
18623                  (const_int 4)))
18624    (set (match_operand:DI 1 "register_operand" "=S")
18625         (plus:DI (match_dup 3)
18626                  (const_int 4)))]
18627   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18628   "{movsl|movsd}"
18629   [(set_attr "type" "str")
18630    (set_attr "mode" "SI")
18631    (set_attr "memory" "both")])
18632
18633 (define_insn "*strmovhi_1"
18634   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18635         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18636    (set (match_operand:SI 0 "register_operand" "=D")
18637         (plus:SI (match_dup 2)
18638                  (const_int 2)))
18639    (set (match_operand:SI 1 "register_operand" "=S")
18640         (plus:SI (match_dup 3)
18641                  (const_int 2)))]
18642   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18643   "movsw"
18644   [(set_attr "type" "str")
18645    (set_attr "memory" "both")
18646    (set_attr "mode" "HI")])
18647
18648 (define_insn "*strmovhi_rex_1"
18649   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18650         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18651    (set (match_operand:DI 0 "register_operand" "=D")
18652         (plus:DI (match_dup 2)
18653                  (const_int 2)))
18654    (set (match_operand:DI 1 "register_operand" "=S")
18655         (plus:DI (match_dup 3)
18656                  (const_int 2)))]
18657   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18658   "movsw"
18659   [(set_attr "type" "str")
18660    (set_attr "memory" "both")
18661    (set_attr "mode" "HI")])
18662
18663 (define_insn "*strmovqi_1"
18664   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18665         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18666    (set (match_operand:SI 0 "register_operand" "=D")
18667         (plus:SI (match_dup 2)
18668                  (const_int 1)))
18669    (set (match_operand:SI 1 "register_operand" "=S")
18670         (plus:SI (match_dup 3)
18671                  (const_int 1)))]
18672   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18673   "movsb"
18674   [(set_attr "type" "str")
18675    (set_attr "memory" "both")
18676    (set_attr "mode" "QI")])
18677
18678 (define_insn "*strmovqi_rex_1"
18679   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18680         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18681    (set (match_operand:DI 0 "register_operand" "=D")
18682         (plus:DI (match_dup 2)
18683                  (const_int 1)))
18684    (set (match_operand:DI 1 "register_operand" "=S")
18685         (plus:DI (match_dup 3)
18686                  (const_int 1)))]
18687   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18688   "movsb"
18689   [(set_attr "type" "str")
18690    (set_attr "memory" "both")
18691    (set_attr "mode" "QI")])
18692
18693 (define_expand "rep_mov"
18694   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18695               (set (match_operand 0 "register_operand" "")
18696                    (match_operand 5 "" ""))
18697               (set (match_operand 2 "register_operand" "")
18698                    (match_operand 6 "" ""))
18699               (set (match_operand 1 "memory_operand" "")
18700                    (match_operand 3 "memory_operand" ""))
18701               (use (match_dup 4))])]
18702   ""
18703   "")
18704
18705 (define_insn "*rep_movdi_rex64"
18706   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18707    (set (match_operand:DI 0 "register_operand" "=D")
18708         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18709                             (const_int 3))
18710                  (match_operand:DI 3 "register_operand" "0")))
18711    (set (match_operand:DI 1 "register_operand" "=S")
18712         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18713                  (match_operand:DI 4 "register_operand" "1")))
18714    (set (mem:BLK (match_dup 3))
18715         (mem:BLK (match_dup 4)))
18716    (use (match_dup 5))]
18717   "TARGET_64BIT"
18718   "rep movsq"
18719   [(set_attr "type" "str")
18720    (set_attr "prefix_rep" "1")
18721    (set_attr "memory" "both")
18722    (set_attr "mode" "DI")])
18723
18724 (define_insn "*rep_movsi"
18725   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18726    (set (match_operand:SI 0 "register_operand" "=D")
18727         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18728                             (const_int 2))
18729                  (match_operand:SI 3 "register_operand" "0")))
18730    (set (match_operand:SI 1 "register_operand" "=S")
18731         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18732                  (match_operand:SI 4 "register_operand" "1")))
18733    (set (mem:BLK (match_dup 3))
18734         (mem:BLK (match_dup 4)))
18735    (use (match_dup 5))]
18736   "!TARGET_64BIT"
18737   "rep movs{l|d}"
18738   [(set_attr "type" "str")
18739    (set_attr "prefix_rep" "1")
18740    (set_attr "memory" "both")
18741    (set_attr "mode" "SI")])
18742
18743 (define_insn "*rep_movsi_rex64"
18744   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18745    (set (match_operand:DI 0 "register_operand" "=D")
18746         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18747                             (const_int 2))
18748                  (match_operand:DI 3 "register_operand" "0")))
18749    (set (match_operand:DI 1 "register_operand" "=S")
18750         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18751                  (match_operand:DI 4 "register_operand" "1")))
18752    (set (mem:BLK (match_dup 3))
18753         (mem:BLK (match_dup 4)))
18754    (use (match_dup 5))]
18755   "TARGET_64BIT"
18756   "rep movs{l|d}"
18757   [(set_attr "type" "str")
18758    (set_attr "prefix_rep" "1")
18759    (set_attr "memory" "both")
18760    (set_attr "mode" "SI")])
18761
18762 (define_insn "*rep_movqi"
18763   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18764    (set (match_operand:SI 0 "register_operand" "=D")
18765         (plus:SI (match_operand:SI 3 "register_operand" "0")
18766                  (match_operand:SI 5 "register_operand" "2")))
18767    (set (match_operand:SI 1 "register_operand" "=S")
18768         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18769    (set (mem:BLK (match_dup 3))
18770         (mem:BLK (match_dup 4)))
18771    (use (match_dup 5))]
18772   "!TARGET_64BIT"
18773   "rep movsb"
18774   [(set_attr "type" "str")
18775    (set_attr "prefix_rep" "1")
18776    (set_attr "memory" "both")
18777    (set_attr "mode" "SI")])
18778
18779 (define_insn "*rep_movqi_rex64"
18780   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18781    (set (match_operand:DI 0 "register_operand" "=D")
18782         (plus:DI (match_operand:DI 3 "register_operand" "0")
18783                  (match_operand:DI 5 "register_operand" "2")))
18784    (set (match_operand:DI 1 "register_operand" "=S")
18785         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18786    (set (mem:BLK (match_dup 3))
18787         (mem:BLK (match_dup 4)))
18788    (use (match_dup 5))]
18789   "TARGET_64BIT"
18790   "rep movsb"
18791   [(set_attr "type" "str")
18792    (set_attr "prefix_rep" "1")
18793    (set_attr "memory" "both")
18794    (set_attr "mode" "SI")])
18795
18796 (define_expand "setmemsi"
18797    [(use (match_operand:BLK 0 "memory_operand" ""))
18798     (use (match_operand:SI 1 "nonmemory_operand" ""))
18799     (use (match_operand 2 "const_int_operand" ""))
18800     (use (match_operand 3 "const_int_operand" ""))
18801     (use (match_operand:SI 4 "const_int_operand" ""))
18802     (use (match_operand:SI 5 "const_int_operand" ""))]
18803   ""
18804 {
18805  if (ix86_expand_setmem (operands[0], operands[1],
18806                          operands[2], operands[3],
18807                          operands[4], operands[5]))
18808    DONE;
18809  else
18810    FAIL;
18811 })
18812
18813 (define_expand "setmemdi"
18814    [(use (match_operand:BLK 0 "memory_operand" ""))
18815     (use (match_operand:DI 1 "nonmemory_operand" ""))
18816     (use (match_operand 2 "const_int_operand" ""))
18817     (use (match_operand 3 "const_int_operand" ""))
18818     (use (match_operand 4 "const_int_operand" ""))
18819     (use (match_operand 5 "const_int_operand" ""))]
18820   "TARGET_64BIT"
18821 {
18822  if (ix86_expand_setmem (operands[0], operands[1],
18823                          operands[2], operands[3],
18824                          operands[4], operands[5]))
18825    DONE;
18826  else
18827    FAIL;
18828 })
18829
18830 ;; Most CPUs don't like single string operations
18831 ;; Handle this case here to simplify previous expander.
18832
18833 (define_expand "strset"
18834   [(set (match_operand 1 "memory_operand" "")
18835         (match_operand 2 "register_operand" ""))
18836    (parallel [(set (match_operand 0 "register_operand" "")
18837                    (match_dup 3))
18838               (clobber (reg:CC FLAGS_REG))])]
18839   ""
18840 {
18841   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18842     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18843
18844   /* If .md ever supports :P for Pmode, this can be directly
18845      in the pattern above.  */
18846   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18847                               GEN_INT (GET_MODE_SIZE (GET_MODE
18848                                                       (operands[2]))));
18849   if (TARGET_SINGLE_STRINGOP || optimize_size)
18850     {
18851       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18852                                       operands[3]));
18853       DONE;
18854     }
18855 })
18856
18857 (define_expand "strset_singleop"
18858   [(parallel [(set (match_operand 1 "memory_operand" "")
18859                    (match_operand 2 "register_operand" ""))
18860               (set (match_operand 0 "register_operand" "")
18861                    (match_operand 3 "" ""))])]
18862   "TARGET_SINGLE_STRINGOP || optimize_size"
18863   "")
18864
18865 (define_insn "*strsetdi_rex_1"
18866   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18867         (match_operand:DI 2 "register_operand" "a"))
18868    (set (match_operand:DI 0 "register_operand" "=D")
18869         (plus:DI (match_dup 1)
18870                  (const_int 8)))]
18871   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18872   "stosq"
18873   [(set_attr "type" "str")
18874    (set_attr "memory" "store")
18875    (set_attr "mode" "DI")])
18876
18877 (define_insn "*strsetsi_1"
18878   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18879         (match_operand:SI 2 "register_operand" "a"))
18880    (set (match_operand:SI 0 "register_operand" "=D")
18881         (plus:SI (match_dup 1)
18882                  (const_int 4)))]
18883   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18884   "{stosl|stosd}"
18885   [(set_attr "type" "str")
18886    (set_attr "memory" "store")
18887    (set_attr "mode" "SI")])
18888
18889 (define_insn "*strsetsi_rex_1"
18890   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18891         (match_operand:SI 2 "register_operand" "a"))
18892    (set (match_operand:DI 0 "register_operand" "=D")
18893         (plus:DI (match_dup 1)
18894                  (const_int 4)))]
18895   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18896   "{stosl|stosd}"
18897   [(set_attr "type" "str")
18898    (set_attr "memory" "store")
18899    (set_attr "mode" "SI")])
18900
18901 (define_insn "*strsethi_1"
18902   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18903         (match_operand:HI 2 "register_operand" "a"))
18904    (set (match_operand:SI 0 "register_operand" "=D")
18905         (plus:SI (match_dup 1)
18906                  (const_int 2)))]
18907   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18908   "stosw"
18909   [(set_attr "type" "str")
18910    (set_attr "memory" "store")
18911    (set_attr "mode" "HI")])
18912
18913 (define_insn "*strsethi_rex_1"
18914   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18915         (match_operand:HI 2 "register_operand" "a"))
18916    (set (match_operand:DI 0 "register_operand" "=D")
18917         (plus:DI (match_dup 1)
18918                  (const_int 2)))]
18919   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18920   "stosw"
18921   [(set_attr "type" "str")
18922    (set_attr "memory" "store")
18923    (set_attr "mode" "HI")])
18924
18925 (define_insn "*strsetqi_1"
18926   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18927         (match_operand:QI 2 "register_operand" "a"))
18928    (set (match_operand:SI 0 "register_operand" "=D")
18929         (plus:SI (match_dup 1)
18930                  (const_int 1)))]
18931   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18932   "stosb"
18933   [(set_attr "type" "str")
18934    (set_attr "memory" "store")
18935    (set_attr "mode" "QI")])
18936
18937 (define_insn "*strsetqi_rex_1"
18938   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18939         (match_operand:QI 2 "register_operand" "a"))
18940    (set (match_operand:DI 0 "register_operand" "=D")
18941         (plus:DI (match_dup 1)
18942                  (const_int 1)))]
18943   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18944   "stosb"
18945   [(set_attr "type" "str")
18946    (set_attr "memory" "store")
18947    (set_attr "mode" "QI")])
18948
18949 (define_expand "rep_stos"
18950   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18951               (set (match_operand 0 "register_operand" "")
18952                    (match_operand 4 "" ""))
18953               (set (match_operand 2 "memory_operand" "") (const_int 0))
18954               (use (match_operand 3 "register_operand" ""))
18955               (use (match_dup 1))])]
18956   ""
18957   "")
18958
18959 (define_insn "*rep_stosdi_rex64"
18960   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18961    (set (match_operand:DI 0 "register_operand" "=D")
18962         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18963                             (const_int 3))
18964                  (match_operand:DI 3 "register_operand" "0")))
18965    (set (mem:BLK (match_dup 3))
18966         (const_int 0))
18967    (use (match_operand:DI 2 "register_operand" "a"))
18968    (use (match_dup 4))]
18969   "TARGET_64BIT"
18970   "rep stosq"
18971   [(set_attr "type" "str")
18972    (set_attr "prefix_rep" "1")
18973    (set_attr "memory" "store")
18974    (set_attr "mode" "DI")])
18975
18976 (define_insn "*rep_stossi"
18977   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18978    (set (match_operand:SI 0 "register_operand" "=D")
18979         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18980                             (const_int 2))
18981                  (match_operand:SI 3 "register_operand" "0")))
18982    (set (mem:BLK (match_dup 3))
18983         (const_int 0))
18984    (use (match_operand:SI 2 "register_operand" "a"))
18985    (use (match_dup 4))]
18986   "!TARGET_64BIT"
18987   "rep stos{l|d}"
18988   [(set_attr "type" "str")
18989    (set_attr "prefix_rep" "1")
18990    (set_attr "memory" "store")
18991    (set_attr "mode" "SI")])
18992
18993 (define_insn "*rep_stossi_rex64"
18994   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18995    (set (match_operand:DI 0 "register_operand" "=D")
18996         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18997                             (const_int 2))
18998                  (match_operand:DI 3 "register_operand" "0")))
18999    (set (mem:BLK (match_dup 3))
19000         (const_int 0))
19001    (use (match_operand:SI 2 "register_operand" "a"))
19002    (use (match_dup 4))]
19003   "TARGET_64BIT"
19004   "rep stos{l|d}"
19005   [(set_attr "type" "str")
19006    (set_attr "prefix_rep" "1")
19007    (set_attr "memory" "store")
19008    (set_attr "mode" "SI")])
19009
19010 (define_insn "*rep_stosqi"
19011   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19012    (set (match_operand:SI 0 "register_operand" "=D")
19013         (plus:SI (match_operand:SI 3 "register_operand" "0")
19014                  (match_operand:SI 4 "register_operand" "1")))
19015    (set (mem:BLK (match_dup 3))
19016         (const_int 0))
19017    (use (match_operand:QI 2 "register_operand" "a"))
19018    (use (match_dup 4))]
19019   "!TARGET_64BIT"
19020   "rep stosb"
19021   [(set_attr "type" "str")
19022    (set_attr "prefix_rep" "1")
19023    (set_attr "memory" "store")
19024    (set_attr "mode" "QI")])
19025
19026 (define_insn "*rep_stosqi_rex64"
19027   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19028    (set (match_operand:DI 0 "register_operand" "=D")
19029         (plus:DI (match_operand:DI 3 "register_operand" "0")
19030                  (match_operand:DI 4 "register_operand" "1")))
19031    (set (mem:BLK (match_dup 3))
19032         (const_int 0))
19033    (use (match_operand:QI 2 "register_operand" "a"))
19034    (use (match_dup 4))]
19035   "TARGET_64BIT"
19036   "rep stosb"
19037   [(set_attr "type" "str")
19038    (set_attr "prefix_rep" "1")
19039    (set_attr "memory" "store")
19040    (set_attr "mode" "QI")])
19041
19042 (define_expand "cmpstrnsi"
19043   [(set (match_operand:SI 0 "register_operand" "")
19044         (compare:SI (match_operand:BLK 1 "general_operand" "")
19045                     (match_operand:BLK 2 "general_operand" "")))
19046    (use (match_operand 3 "general_operand" ""))
19047    (use (match_operand 4 "immediate_operand" ""))]
19048   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
19049 {
19050   rtx addr1, addr2, out, outlow, count, countreg, align;
19051
19052   /* Can't use this if the user has appropriated esi or edi.  */
19053   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19054     FAIL;
19055
19056   out = operands[0];
19057   if (!REG_P (out))
19058     out = gen_reg_rtx (SImode);
19059
19060   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19061   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19062   if (addr1 != XEXP (operands[1], 0))
19063     operands[1] = replace_equiv_address_nv (operands[1], addr1);
19064   if (addr2 != XEXP (operands[2], 0))
19065     operands[2] = replace_equiv_address_nv (operands[2], addr2);
19066
19067   count = operands[3];
19068   countreg = ix86_zero_extend_to_Pmode (count);
19069
19070   /* %%% Iff we are testing strict equality, we can use known alignment
19071      to good advantage.  This may be possible with combine, particularly
19072      once cc0 is dead.  */
19073   align = operands[4];
19074
19075   if (CONST_INT_P (count))
19076     {
19077       if (INTVAL (count) == 0)
19078         {
19079           emit_move_insn (operands[0], const0_rtx);
19080           DONE;
19081         }
19082       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19083                                      operands[1], operands[2]));
19084     }
19085   else
19086     {
19087       if (TARGET_64BIT)
19088         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19089       else
19090         emit_insn (gen_cmpsi_1 (countreg, countreg));
19091       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19092                                   operands[1], operands[2]));
19093     }
19094
19095   outlow = gen_lowpart (QImode, out);
19096   emit_insn (gen_cmpintqi (outlow));
19097   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19098
19099   if (operands[0] != out)
19100     emit_move_insn (operands[0], out);
19101
19102   DONE;
19103 })
19104
19105 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19106
19107 (define_expand "cmpintqi"
19108   [(set (match_dup 1)
19109         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19110    (set (match_dup 2)
19111         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19112    (parallel [(set (match_operand:QI 0 "register_operand" "")
19113                    (minus:QI (match_dup 1)
19114                              (match_dup 2)))
19115               (clobber (reg:CC FLAGS_REG))])]
19116   ""
19117   "operands[1] = gen_reg_rtx (QImode);
19118    operands[2] = gen_reg_rtx (QImode);")
19119
19120 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
19121 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
19122
19123 (define_expand "cmpstrnqi_nz_1"
19124   [(parallel [(set (reg:CC FLAGS_REG)
19125                    (compare:CC (match_operand 4 "memory_operand" "")
19126                                (match_operand 5 "memory_operand" "")))
19127               (use (match_operand 2 "register_operand" ""))
19128               (use (match_operand:SI 3 "immediate_operand" ""))
19129               (clobber (match_operand 0 "register_operand" ""))
19130               (clobber (match_operand 1 "register_operand" ""))
19131               (clobber (match_dup 2))])]
19132   ""
19133   "")
19134
19135 (define_insn "*cmpstrnqi_nz_1"
19136   [(set (reg:CC FLAGS_REG)
19137         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19138                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19139    (use (match_operand:SI 6 "register_operand" "2"))
19140    (use (match_operand:SI 3 "immediate_operand" "i"))
19141    (clobber (match_operand:SI 0 "register_operand" "=S"))
19142    (clobber (match_operand:SI 1 "register_operand" "=D"))
19143    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19144   "!TARGET_64BIT"
19145   "repz cmpsb"
19146   [(set_attr "type" "str")
19147    (set_attr "mode" "QI")
19148    (set_attr "prefix_rep" "1")])
19149
19150 (define_insn "*cmpstrnqi_nz_rex_1"
19151   [(set (reg:CC FLAGS_REG)
19152         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19153                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19154    (use (match_operand:DI 6 "register_operand" "2"))
19155    (use (match_operand:SI 3 "immediate_operand" "i"))
19156    (clobber (match_operand:DI 0 "register_operand" "=S"))
19157    (clobber (match_operand:DI 1 "register_operand" "=D"))
19158    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19159   "TARGET_64BIT"
19160   "repz cmpsb"
19161   [(set_attr "type" "str")
19162    (set_attr "mode" "QI")
19163    (set_attr "prefix_rep" "1")])
19164
19165 ;; The same, but the count is not known to not be zero.
19166
19167 (define_expand "cmpstrnqi_1"
19168   [(parallel [(set (reg:CC FLAGS_REG)
19169                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19170                                      (const_int 0))
19171                   (compare:CC (match_operand 4 "memory_operand" "")
19172                               (match_operand 5 "memory_operand" ""))
19173                   (const_int 0)))
19174               (use (match_operand:SI 3 "immediate_operand" ""))
19175               (use (reg:CC FLAGS_REG))
19176               (clobber (match_operand 0 "register_operand" ""))
19177               (clobber (match_operand 1 "register_operand" ""))
19178               (clobber (match_dup 2))])]
19179   ""
19180   "")
19181
19182 (define_insn "*cmpstrnqi_1"
19183   [(set (reg:CC FLAGS_REG)
19184         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19185                              (const_int 0))
19186           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19187                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19188           (const_int 0)))
19189    (use (match_operand:SI 3 "immediate_operand" "i"))
19190    (use (reg:CC FLAGS_REG))
19191    (clobber (match_operand:SI 0 "register_operand" "=S"))
19192    (clobber (match_operand:SI 1 "register_operand" "=D"))
19193    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19194   "!TARGET_64BIT"
19195   "repz cmpsb"
19196   [(set_attr "type" "str")
19197    (set_attr "mode" "QI")
19198    (set_attr "prefix_rep" "1")])
19199
19200 (define_insn "*cmpstrnqi_rex_1"
19201   [(set (reg:CC FLAGS_REG)
19202         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19203                              (const_int 0))
19204           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19205                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19206           (const_int 0)))
19207    (use (match_operand:SI 3 "immediate_operand" "i"))
19208    (use (reg:CC FLAGS_REG))
19209    (clobber (match_operand:DI 0 "register_operand" "=S"))
19210    (clobber (match_operand:DI 1 "register_operand" "=D"))
19211    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19212   "TARGET_64BIT"
19213   "repz cmpsb"
19214   [(set_attr "type" "str")
19215    (set_attr "mode" "QI")
19216    (set_attr "prefix_rep" "1")])
19217
19218 (define_expand "strlensi"
19219   [(set (match_operand:SI 0 "register_operand" "")
19220         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19221                     (match_operand:QI 2 "immediate_operand" "")
19222                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19223   ""
19224 {
19225  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19226    DONE;
19227  else
19228    FAIL;
19229 })
19230
19231 (define_expand "strlendi"
19232   [(set (match_operand:DI 0 "register_operand" "")
19233         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19234                     (match_operand:QI 2 "immediate_operand" "")
19235                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19236   ""
19237 {
19238  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19239    DONE;
19240  else
19241    FAIL;
19242 })
19243
19244 (define_expand "strlenqi_1"
19245   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19246               (clobber (match_operand 1 "register_operand" ""))
19247               (clobber (reg:CC FLAGS_REG))])]
19248   ""
19249   "")
19250
19251 (define_insn "*strlenqi_1"
19252   [(set (match_operand:SI 0 "register_operand" "=&c")
19253         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19254                     (match_operand:QI 2 "register_operand" "a")
19255                     (match_operand:SI 3 "immediate_operand" "i")
19256                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19257    (clobber (match_operand:SI 1 "register_operand" "=D"))
19258    (clobber (reg:CC FLAGS_REG))]
19259   "!TARGET_64BIT"
19260   "repnz scasb"
19261   [(set_attr "type" "str")
19262    (set_attr "mode" "QI")
19263    (set_attr "prefix_rep" "1")])
19264
19265 (define_insn "*strlenqi_rex_1"
19266   [(set (match_operand:DI 0 "register_operand" "=&c")
19267         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19268                     (match_operand:QI 2 "register_operand" "a")
19269                     (match_operand:DI 3 "immediate_operand" "i")
19270                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19271    (clobber (match_operand:DI 1 "register_operand" "=D"))
19272    (clobber (reg:CC FLAGS_REG))]
19273   "TARGET_64BIT"
19274   "repnz scasb"
19275   [(set_attr "type" "str")
19276    (set_attr "mode" "QI")
19277    (set_attr "prefix_rep" "1")])
19278
19279 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19280 ;; handled in combine, but it is not currently up to the task.
19281 ;; When used for their truth value, the cmpstrn* expanders generate
19282 ;; code like this:
19283 ;;
19284 ;;   repz cmpsb
19285 ;;   seta       %al
19286 ;;   setb       %dl
19287 ;;   cmpb       %al, %dl
19288 ;;   jcc        label
19289 ;;
19290 ;; The intermediate three instructions are unnecessary.
19291
19292 ;; This one handles cmpstrn*_nz_1...
19293 (define_peephole2
19294   [(parallel[
19295      (set (reg:CC FLAGS_REG)
19296           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19297                       (mem:BLK (match_operand 5 "register_operand" ""))))
19298      (use (match_operand 6 "register_operand" ""))
19299      (use (match_operand:SI 3 "immediate_operand" ""))
19300      (clobber (match_operand 0 "register_operand" ""))
19301      (clobber (match_operand 1 "register_operand" ""))
19302      (clobber (match_operand 2 "register_operand" ""))])
19303    (set (match_operand:QI 7 "register_operand" "")
19304         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19305    (set (match_operand:QI 8 "register_operand" "")
19306         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19307    (set (reg FLAGS_REG)
19308         (compare (match_dup 7) (match_dup 8)))
19309   ]
19310   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19311   [(parallel[
19312      (set (reg:CC FLAGS_REG)
19313           (compare:CC (mem:BLK (match_dup 4))
19314                       (mem:BLK (match_dup 5))))
19315      (use (match_dup 6))
19316      (use (match_dup 3))
19317      (clobber (match_dup 0))
19318      (clobber (match_dup 1))
19319      (clobber (match_dup 2))])]
19320   "")
19321
19322 ;; ...and this one handles cmpstrn*_1.
19323 (define_peephole2
19324   [(parallel[
19325      (set (reg:CC FLAGS_REG)
19326           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19327                                (const_int 0))
19328             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19329                         (mem:BLK (match_operand 5 "register_operand" "")))
19330             (const_int 0)))
19331      (use (match_operand:SI 3 "immediate_operand" ""))
19332      (use (reg:CC FLAGS_REG))
19333      (clobber (match_operand 0 "register_operand" ""))
19334      (clobber (match_operand 1 "register_operand" ""))
19335      (clobber (match_operand 2 "register_operand" ""))])
19336    (set (match_operand:QI 7 "register_operand" "")
19337         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19338    (set (match_operand:QI 8 "register_operand" "")
19339         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19340    (set (reg FLAGS_REG)
19341         (compare (match_dup 7) (match_dup 8)))
19342   ]
19343   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19344   [(parallel[
19345      (set (reg:CC FLAGS_REG)
19346           (if_then_else:CC (ne (match_dup 6)
19347                                (const_int 0))
19348             (compare:CC (mem:BLK (match_dup 4))
19349                         (mem:BLK (match_dup 5)))
19350             (const_int 0)))
19351      (use (match_dup 3))
19352      (use (reg:CC FLAGS_REG))
19353      (clobber (match_dup 0))
19354      (clobber (match_dup 1))
19355      (clobber (match_dup 2))])]
19356   "")
19357
19358
19359 \f
19360 ;; Conditional move instructions.
19361
19362 (define_expand "movdicc"
19363   [(set (match_operand:DI 0 "register_operand" "")
19364         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19365                          (match_operand:DI 2 "general_operand" "")
19366                          (match_operand:DI 3 "general_operand" "")))]
19367   "TARGET_64BIT"
19368   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19369
19370 (define_insn "x86_movdicc_0_m1_rex64"
19371   [(set (match_operand:DI 0 "register_operand" "=r")
19372         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19373           (const_int -1)
19374           (const_int 0)))
19375    (clobber (reg:CC FLAGS_REG))]
19376   "TARGET_64BIT"
19377   "sbb{q}\t%0, %0"
19378   ; Since we don't have the proper number of operands for an alu insn,
19379   ; fill in all the blanks.
19380   [(set_attr "type" "alu")
19381    (set_attr "pent_pair" "pu")
19382    (set_attr "memory" "none")
19383    (set_attr "imm_disp" "false")
19384    (set_attr "mode" "DI")
19385    (set_attr "length_immediate" "0")])
19386
19387 (define_insn "*x86_movdicc_0_m1_se"
19388   [(set (match_operand:DI 0 "register_operand" "=r")
19389         (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19390                          (const_int 1)
19391                          (const_int 0)))
19392    (clobber (reg:CC FLAGS_REG))]
19393   ""
19394   "sbb{q}\t%0, %0"
19395   [(set_attr "type" "alu")
19396    (set_attr "pent_pair" "pu")
19397    (set_attr "memory" "none")
19398    (set_attr "imm_disp" "false")
19399    (set_attr "mode" "DI")
19400    (set_attr "length_immediate" "0")])
19401
19402 (define_insn "*movdicc_c_rex64"
19403   [(set (match_operand:DI 0 "register_operand" "=r,r")
19404         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19405                                 [(reg FLAGS_REG) (const_int 0)])
19406                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19407                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19408   "TARGET_64BIT && TARGET_CMOVE
19409    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19410   "@
19411    cmov%O2%C1\t{%2, %0|%0, %2}
19412    cmov%O2%c1\t{%3, %0|%0, %3}"
19413   [(set_attr "type" "icmov")
19414    (set_attr "mode" "DI")])
19415
19416 (define_expand "movsicc"
19417   [(set (match_operand:SI 0 "register_operand" "")
19418         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19419                          (match_operand:SI 2 "general_operand" "")
19420                          (match_operand:SI 3 "general_operand" "")))]
19421   ""
19422   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19423
19424 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19425 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19426 ;; So just document what we're doing explicitly.
19427
19428 (define_insn "x86_movsicc_0_m1"
19429   [(set (match_operand:SI 0 "register_operand" "=r")
19430         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19431           (const_int -1)
19432           (const_int 0)))
19433    (clobber (reg:CC FLAGS_REG))]
19434   ""
19435   "sbb{l}\t%0, %0"
19436   ; Since we don't have the proper number of operands for an alu insn,
19437   ; fill in all the blanks.
19438   [(set_attr "type" "alu")
19439    (set_attr "pent_pair" "pu")
19440    (set_attr "memory" "none")
19441    (set_attr "imm_disp" "false")
19442    (set_attr "mode" "SI")
19443    (set_attr "length_immediate" "0")])
19444
19445 (define_insn "*x86_movsicc_0_m1_se"
19446   [(set (match_operand:SI 0 "register_operand" "=r")
19447         (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19448                          (const_int 1)
19449                          (const_int 0)))
19450    (clobber (reg:CC FLAGS_REG))]
19451   ""
19452   "sbb{l}\t%0, %0"
19453   [(set_attr "type" "alu")
19454    (set_attr "pent_pair" "pu")
19455    (set_attr "memory" "none")
19456    (set_attr "imm_disp" "false")
19457    (set_attr "mode" "SI")
19458    (set_attr "length_immediate" "0")])
19459
19460 (define_insn "*movsicc_noc"
19461   [(set (match_operand:SI 0 "register_operand" "=r,r")
19462         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19463                                 [(reg FLAGS_REG) (const_int 0)])
19464                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19465                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19466   "TARGET_CMOVE
19467    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19468   "@
19469    cmov%O2%C1\t{%2, %0|%0, %2}
19470    cmov%O2%c1\t{%3, %0|%0, %3}"
19471   [(set_attr "type" "icmov")
19472    (set_attr "mode" "SI")])
19473
19474 (define_expand "movhicc"
19475   [(set (match_operand:HI 0 "register_operand" "")
19476         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19477                          (match_operand:HI 2 "general_operand" "")
19478                          (match_operand:HI 3 "general_operand" "")))]
19479   "TARGET_HIMODE_MATH"
19480   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19481
19482 (define_insn "*movhicc_noc"
19483   [(set (match_operand:HI 0 "register_operand" "=r,r")
19484         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19485                                 [(reg FLAGS_REG) (const_int 0)])
19486                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19487                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19488   "TARGET_CMOVE
19489    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19490   "@
19491    cmov%O2%C1\t{%2, %0|%0, %2}
19492    cmov%O2%c1\t{%3, %0|%0, %3}"
19493   [(set_attr "type" "icmov")
19494    (set_attr "mode" "HI")])
19495
19496 (define_expand "movqicc"
19497   [(set (match_operand:QI 0 "register_operand" "")
19498         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19499                          (match_operand:QI 2 "general_operand" "")
19500                          (match_operand:QI 3 "general_operand" "")))]
19501   "TARGET_QIMODE_MATH"
19502   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19503
19504 (define_insn_and_split "*movqicc_noc"
19505   [(set (match_operand:QI 0 "register_operand" "=r,r")
19506         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19507                                 [(match_operand 4 "flags_reg_operand" "")
19508                                  (const_int 0)])
19509                       (match_operand:QI 2 "register_operand" "r,0")
19510                       (match_operand:QI 3 "register_operand" "0,r")))]
19511   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19512   "#"
19513   "&& reload_completed"
19514   [(set (match_dup 0)
19515         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19516                       (match_dup 2)
19517                       (match_dup 3)))]
19518   "operands[0] = gen_lowpart (SImode, operands[0]);
19519    operands[2] = gen_lowpart (SImode, operands[2]);
19520    operands[3] = gen_lowpart (SImode, operands[3]);"
19521   [(set_attr "type" "icmov")
19522    (set_attr "mode" "SI")])
19523
19524 (define_expand "mov<mode>cc"
19525   [(set (match_operand:X87MODEF 0 "register_operand" "")
19526         (if_then_else:X87MODEF
19527           (match_operand 1 "comparison_operator" "")
19528           (match_operand:X87MODEF 2 "register_operand" "")
19529           (match_operand:X87MODEF 3 "register_operand" "")))]
19530   "(TARGET_80387 && TARGET_CMOVE)
19531    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19532   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19533
19534 (define_insn "*movsfcc_1_387"
19535   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19536         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19537                                 [(reg FLAGS_REG) (const_int 0)])
19538                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19539                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19540   "TARGET_80387 && TARGET_CMOVE
19541    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19542   "@
19543    fcmov%F1\t{%2, %0|%0, %2}
19544    fcmov%f1\t{%3, %0|%0, %3}
19545    cmov%O2%C1\t{%2, %0|%0, %2}
19546    cmov%O2%c1\t{%3, %0|%0, %3}"
19547   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19548    (set_attr "mode" "SF,SF,SI,SI")])
19549
19550 (define_insn "*movdfcc_1"
19551   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19552         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19553                                 [(reg FLAGS_REG) (const_int 0)])
19554                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19555                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19556   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19557    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19558   "@
19559    fcmov%F1\t{%2, %0|%0, %2}
19560    fcmov%f1\t{%3, %0|%0, %3}
19561    #
19562    #"
19563   [(set_attr "type" "fcmov,fcmov,multi,multi")
19564    (set_attr "mode" "DF")])
19565
19566 (define_insn "*movdfcc_1_rex64"
19567   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19568         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19569                                 [(reg FLAGS_REG) (const_int 0)])
19570                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19571                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19572   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19573    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19574   "@
19575    fcmov%F1\t{%2, %0|%0, %2}
19576    fcmov%f1\t{%3, %0|%0, %3}
19577    cmov%O2%C1\t{%2, %0|%0, %2}
19578    cmov%O2%c1\t{%3, %0|%0, %3}"
19579   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19580    (set_attr "mode" "DF")])
19581
19582 (define_split
19583   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19584         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19585                                 [(match_operand 4 "flags_reg_operand" "")
19586                                  (const_int 0)])
19587                       (match_operand:DF 2 "nonimmediate_operand" "")
19588                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19589   "!TARGET_64BIT && reload_completed"
19590   [(set (match_dup 2)
19591         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19592                       (match_dup 5)
19593                       (match_dup 7)))
19594    (set (match_dup 3)
19595         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19596                       (match_dup 6)
19597                       (match_dup 8)))]
19598   "split_di (operands+2, 1, operands+5, operands+6);
19599    split_di (operands+3, 1, operands+7, operands+8);
19600    split_di (operands, 1, operands+2, operands+3);")
19601
19602 (define_insn "*movxfcc_1"
19603   [(set (match_operand:XF 0 "register_operand" "=f,f")
19604         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19605                                 [(reg FLAGS_REG) (const_int 0)])
19606                       (match_operand:XF 2 "register_operand" "f,0")
19607                       (match_operand:XF 3 "register_operand" "0,f")))]
19608   "TARGET_80387 && TARGET_CMOVE"
19609   "@
19610    fcmov%F1\t{%2, %0|%0, %2}
19611    fcmov%f1\t{%3, %0|%0, %3}"
19612   [(set_attr "type" "fcmov")
19613    (set_attr "mode" "XF")])
19614
19615 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19616 ;; the scalar versions to have only XMM registers as operands.
19617
19618 ;; SSE5 conditional move
19619 (define_insn "*sse5_pcmov_<mode>"
19620   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19621         (if_then_else:MODEF
19622           (match_operand:MODEF 1 "register_operand" "x,0")
19623           (match_operand:MODEF 2 "register_operand" "0,x")
19624           (match_operand:MODEF 3 "register_operand" "x,x")))]
19625   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19626   "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19627   [(set_attr "type" "sse4arg")])
19628
19629 ;; These versions of the min/max patterns are intentionally ignorant of
19630 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19631 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19632 ;; are undefined in this condition, we're certain this is correct.
19633
19634 (define_insn "smin<mode>3"
19635   [(set (match_operand:MODEF 0 "register_operand" "=x")
19636         (smin:MODEF
19637           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19638           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19639   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19640   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19641   [(set_attr "type" "sseadd")
19642    (set_attr "mode" "<MODE>")])
19643
19644 (define_insn "smax<mode>3"
19645   [(set (match_operand:MODEF 0 "register_operand" "=x")
19646         (smax:MODEF
19647           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19648           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19649   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19650   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19651   [(set_attr "type" "sseadd")
19652    (set_attr "mode" "<MODE>")])
19653
19654 ;; These versions of the min/max patterns implement exactly the operations
19655 ;;   min = (op1 < op2 ? op1 : op2)
19656 ;;   max = (!(op1 < op2) ? op1 : op2)
19657 ;; Their operands are not commutative, and thus they may be used in the
19658 ;; presence of -0.0 and NaN.
19659
19660 (define_insn "*ieee_smin<mode>3"
19661   [(set (match_operand:MODEF 0 "register_operand" "=x")
19662         (unspec:MODEF
19663           [(match_operand:MODEF 1 "register_operand" "0")
19664            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19665          UNSPEC_IEEE_MIN))]
19666   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19667   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19668   [(set_attr "type" "sseadd")
19669    (set_attr "mode" "<MODE>")])
19670
19671 (define_insn "*ieee_smax<mode>3"
19672   [(set (match_operand:MODEF 0 "register_operand" "=x")
19673         (unspec:MODEF
19674           [(match_operand:MODEF 1 "register_operand" "0")
19675            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19676          UNSPEC_IEEE_MAX))]
19677   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19678   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19679   [(set_attr "type" "sseadd")
19680    (set_attr "mode" "<MODE>")])
19681
19682 ;; Make two stack loads independent:
19683 ;;   fld aa              fld aa
19684 ;;   fld %st(0)     ->   fld bb
19685 ;;   fmul bb             fmul %st(1), %st
19686 ;;
19687 ;; Actually we only match the last two instructions for simplicity.
19688 (define_peephole2
19689   [(set (match_operand 0 "fp_register_operand" "")
19690         (match_operand 1 "fp_register_operand" ""))
19691    (set (match_dup 0)
19692         (match_operator 2 "binary_fp_operator"
19693            [(match_dup 0)
19694             (match_operand 3 "memory_operand" "")]))]
19695   "REGNO (operands[0]) != REGNO (operands[1])"
19696   [(set (match_dup 0) (match_dup 3))
19697    (set (match_dup 0) (match_dup 4))]
19698
19699   ;; The % modifier is not operational anymore in peephole2's, so we have to
19700   ;; swap the operands manually in the case of addition and multiplication.
19701   "if (COMMUTATIVE_ARITH_P (operands[2]))
19702      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19703                                  operands[0], operands[1]);
19704    else
19705      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19706                                  operands[1], operands[0]);")
19707
19708 ;; Conditional addition patterns
19709 (define_expand "addqicc"
19710   [(match_operand:QI 0 "register_operand" "")
19711    (match_operand 1 "comparison_operator" "")
19712    (match_operand:QI 2 "register_operand" "")
19713    (match_operand:QI 3 "const_int_operand" "")]
19714   ""
19715   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19716
19717 (define_expand "addhicc"
19718   [(match_operand:HI 0 "register_operand" "")
19719    (match_operand 1 "comparison_operator" "")
19720    (match_operand:HI 2 "register_operand" "")
19721    (match_operand:HI 3 "const_int_operand" "")]
19722   ""
19723   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19724
19725 (define_expand "addsicc"
19726   [(match_operand:SI 0 "register_operand" "")
19727    (match_operand 1 "comparison_operator" "")
19728    (match_operand:SI 2 "register_operand" "")
19729    (match_operand:SI 3 "const_int_operand" "")]
19730   ""
19731   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19732
19733 (define_expand "adddicc"
19734   [(match_operand:DI 0 "register_operand" "")
19735    (match_operand 1 "comparison_operator" "")
19736    (match_operand:DI 2 "register_operand" "")
19737    (match_operand:DI 3 "const_int_operand" "")]
19738   "TARGET_64BIT"
19739   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19740
19741 \f
19742 ;; Misc patterns (?)
19743
19744 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19745 ;; Otherwise there will be nothing to keep
19746 ;;
19747 ;; [(set (reg ebp) (reg esp))]
19748 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19749 ;;  (clobber (eflags)]
19750 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19751 ;;
19752 ;; in proper program order.
19753 (define_insn "pro_epilogue_adjust_stack_1"
19754   [(set (match_operand:SI 0 "register_operand" "=r,r")
19755         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19756                  (match_operand:SI 2 "immediate_operand" "i,i")))
19757    (clobber (reg:CC FLAGS_REG))
19758    (clobber (mem:BLK (scratch)))]
19759   "!TARGET_64BIT"
19760 {
19761   switch (get_attr_type (insn))
19762     {
19763     case TYPE_IMOV:
19764       return "mov{l}\t{%1, %0|%0, %1}";
19765
19766     case TYPE_ALU:
19767       if (CONST_INT_P (operands[2])
19768           && (INTVAL (operands[2]) == 128
19769               || (INTVAL (operands[2]) < 0
19770                   && INTVAL (operands[2]) != -128)))
19771         {
19772           operands[2] = GEN_INT (-INTVAL (operands[2]));
19773           return "sub{l}\t{%2, %0|%0, %2}";
19774         }
19775       return "add{l}\t{%2, %0|%0, %2}";
19776
19777     case TYPE_LEA:
19778       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19779       return "lea{l}\t{%a2, %0|%0, %a2}";
19780
19781     default:
19782       gcc_unreachable ();
19783     }
19784 }
19785   [(set (attr "type")
19786         (cond [(eq_attr "alternative" "0")
19787                  (const_string "alu")
19788                (match_operand:SI 2 "const0_operand" "")
19789                  (const_string "imov")
19790               ]
19791               (const_string "lea")))
19792    (set_attr "mode" "SI")])
19793
19794 (define_insn "pro_epilogue_adjust_stack_rex64"
19795   [(set (match_operand:DI 0 "register_operand" "=r,r")
19796         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19797                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19798    (clobber (reg:CC FLAGS_REG))
19799    (clobber (mem:BLK (scratch)))]
19800   "TARGET_64BIT"
19801 {
19802   switch (get_attr_type (insn))
19803     {
19804     case TYPE_IMOV:
19805       return "mov{q}\t{%1, %0|%0, %1}";
19806
19807     case TYPE_ALU:
19808       if (CONST_INT_P (operands[2])
19809           /* Avoid overflows.  */
19810           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19811           && (INTVAL (operands[2]) == 128
19812               || (INTVAL (operands[2]) < 0
19813                   && INTVAL (operands[2]) != -128)))
19814         {
19815           operands[2] = GEN_INT (-INTVAL (operands[2]));
19816           return "sub{q}\t{%2, %0|%0, %2}";
19817         }
19818       return "add{q}\t{%2, %0|%0, %2}";
19819
19820     case TYPE_LEA:
19821       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19822       return "lea{q}\t{%a2, %0|%0, %a2}";
19823
19824     default:
19825       gcc_unreachable ();
19826     }
19827 }
19828   [(set (attr "type")
19829         (cond [(eq_attr "alternative" "0")
19830                  (const_string "alu")
19831                (match_operand:DI 2 "const0_operand" "")
19832                  (const_string "imov")
19833               ]
19834               (const_string "lea")))
19835    (set_attr "mode" "DI")])
19836
19837 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19838   [(set (match_operand:DI 0 "register_operand" "=r,r")
19839         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19840                  (match_operand:DI 3 "immediate_operand" "i,i")))
19841    (use (match_operand:DI 2 "register_operand" "r,r"))
19842    (clobber (reg:CC FLAGS_REG))
19843    (clobber (mem:BLK (scratch)))]
19844   "TARGET_64BIT"
19845 {
19846   switch (get_attr_type (insn))
19847     {
19848     case TYPE_ALU:
19849       return "add{q}\t{%2, %0|%0, %2}";
19850
19851     case TYPE_LEA:
19852       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19853       return "lea{q}\t{%a2, %0|%0, %a2}";
19854
19855     default:
19856       gcc_unreachable ();
19857     }
19858 }
19859   [(set_attr "type" "alu,lea")
19860    (set_attr "mode" "DI")])
19861
19862 (define_insn "allocate_stack_worker_32"
19863   [(set (match_operand:SI 0 "register_operand" "+a")
19864         (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19865    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19866    (clobber (reg:CC FLAGS_REG))]
19867   "!TARGET_64BIT && TARGET_STACK_PROBE"
19868   "call\t___chkstk"
19869   [(set_attr "type" "multi")
19870    (set_attr "length" "5")])
19871
19872 (define_insn "allocate_stack_worker_64"
19873   [(set (match_operand:DI 0 "register_operand" "=a")
19874         (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19875    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19876    (clobber (reg:DI R10_REG))
19877    (clobber (reg:DI R11_REG))
19878    (clobber (reg:CC FLAGS_REG))]
19879   "TARGET_64BIT && TARGET_STACK_PROBE"
19880   "call\t___chkstk"
19881   [(set_attr "type" "multi")
19882    (set_attr "length" "5")])
19883
19884 (define_expand "allocate_stack"
19885   [(match_operand 0 "register_operand" "")
19886    (match_operand 1 "general_operand" "")]
19887   "TARGET_STACK_PROBE"
19888 {
19889   rtx x;
19890
19891 #ifndef CHECK_STACK_LIMIT
19892 #define CHECK_STACK_LIMIT 0
19893 #endif
19894
19895   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19896       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19897     {
19898       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19899                                stack_pointer_rtx, 0, OPTAB_DIRECT);
19900       if (x != stack_pointer_rtx)
19901         emit_move_insn (stack_pointer_rtx, x);
19902     }
19903   else
19904     {
19905       x = copy_to_mode_reg (Pmode, operands[1]);
19906       if (TARGET_64BIT)
19907         x = gen_allocate_stack_worker_64 (x);
19908       else
19909         x = gen_allocate_stack_worker_32 (x);
19910       emit_insn (x);
19911     }
19912
19913   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19914   DONE;
19915 })
19916
19917 (define_expand "builtin_setjmp_receiver"
19918   [(label_ref (match_operand 0 "" ""))]
19919   "!TARGET_64BIT && flag_pic"
19920 {
19921   if (TARGET_MACHO)
19922     {
19923       rtx xops[3];
19924       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19925       rtx label_rtx = gen_label_rtx ();
19926       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19927       xops[0] = xops[1] = picreg;
19928       xops[2] = gen_rtx_CONST (SImode,
19929                   gen_rtx_MINUS (SImode,
19930                     gen_rtx_LABEL_REF (SImode, label_rtx),
19931                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19932       ix86_expand_binary_operator (MINUS, SImode, xops);
19933     }
19934   else
19935     emit_insn (gen_set_got (pic_offset_table_rtx));
19936   DONE;
19937 })
19938 \f
19939 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19940
19941 (define_split
19942   [(set (match_operand 0 "register_operand" "")
19943         (match_operator 3 "promotable_binary_operator"
19944            [(match_operand 1 "register_operand" "")
19945             (match_operand 2 "aligned_operand" "")]))
19946    (clobber (reg:CC FLAGS_REG))]
19947   "! TARGET_PARTIAL_REG_STALL && reload_completed
19948    && ((GET_MODE (operands[0]) == HImode
19949         && ((!optimize_size && !TARGET_FAST_PREFIX)
19950             /* ??? next two lines just !satisfies_constraint_K (...) */
19951             || !CONST_INT_P (operands[2])
19952             || satisfies_constraint_K (operands[2])))
19953        || (GET_MODE (operands[0]) == QImode
19954            && (TARGET_PROMOTE_QImode || optimize_size)))"
19955   [(parallel [(set (match_dup 0)
19956                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19957               (clobber (reg:CC FLAGS_REG))])]
19958   "operands[0] = gen_lowpart (SImode, operands[0]);
19959    operands[1] = gen_lowpart (SImode, operands[1]);
19960    if (GET_CODE (operands[3]) != ASHIFT)
19961      operands[2] = gen_lowpart (SImode, operands[2]);
19962    PUT_MODE (operands[3], SImode);")
19963
19964 ; Promote the QImode tests, as i386 has encoding of the AND
19965 ; instruction with 32-bit sign-extended immediate and thus the
19966 ; instruction size is unchanged, except in the %eax case for
19967 ; which it is increased by one byte, hence the ! optimize_size.
19968 (define_split
19969   [(set (match_operand 0 "flags_reg_operand" "")
19970         (match_operator 2 "compare_operator"
19971           [(and (match_operand 3 "aligned_operand" "")
19972                 (match_operand 4 "const_int_operand" ""))
19973            (const_int 0)]))
19974    (set (match_operand 1 "register_operand" "")
19975         (and (match_dup 3) (match_dup 4)))]
19976   "! TARGET_PARTIAL_REG_STALL && reload_completed
19977    && ! optimize_size
19978    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19979        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19980    /* Ensure that the operand will remain sign-extended immediate.  */
19981    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19982   [(parallel [(set (match_dup 0)
19983                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19984                                     (const_int 0)]))
19985               (set (match_dup 1)
19986                    (and:SI (match_dup 3) (match_dup 4)))])]
19987 {
19988   operands[4]
19989     = gen_int_mode (INTVAL (operands[4])
19990                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19991   operands[1] = gen_lowpart (SImode, operands[1]);
19992   operands[3] = gen_lowpart (SImode, operands[3]);
19993 })
19994
19995 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19996 ; the TEST instruction with 32-bit sign-extended immediate and thus
19997 ; the instruction size would at least double, which is not what we
19998 ; want even with ! optimize_size.
19999 (define_split
20000   [(set (match_operand 0 "flags_reg_operand" "")
20001         (match_operator 1 "compare_operator"
20002           [(and (match_operand:HI 2 "aligned_operand" "")
20003                 (match_operand:HI 3 "const_int_operand" ""))
20004            (const_int 0)]))]
20005   "! TARGET_PARTIAL_REG_STALL && reload_completed
20006    && ! TARGET_FAST_PREFIX
20007    && ! optimize_size
20008    /* Ensure that the operand will remain sign-extended immediate.  */
20009    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20010   [(set (match_dup 0)
20011         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20012                          (const_int 0)]))]
20013 {
20014   operands[3]
20015     = gen_int_mode (INTVAL (operands[3])
20016                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20017   operands[2] = gen_lowpart (SImode, operands[2]);
20018 })
20019
20020 (define_split
20021   [(set (match_operand 0 "register_operand" "")
20022         (neg (match_operand 1 "register_operand" "")))
20023    (clobber (reg:CC FLAGS_REG))]
20024   "! TARGET_PARTIAL_REG_STALL && reload_completed
20025    && (GET_MODE (operands[0]) == HImode
20026        || (GET_MODE (operands[0]) == QImode
20027            && (TARGET_PROMOTE_QImode || optimize_size)))"
20028   [(parallel [(set (match_dup 0)
20029                    (neg:SI (match_dup 1)))
20030               (clobber (reg:CC FLAGS_REG))])]
20031   "operands[0] = gen_lowpart (SImode, operands[0]);
20032    operands[1] = gen_lowpart (SImode, operands[1]);")
20033
20034 (define_split
20035   [(set (match_operand 0 "register_operand" "")
20036         (not (match_operand 1 "register_operand" "")))]
20037   "! TARGET_PARTIAL_REG_STALL && reload_completed
20038    && (GET_MODE (operands[0]) == HImode
20039        || (GET_MODE (operands[0]) == QImode
20040            && (TARGET_PROMOTE_QImode || optimize_size)))"
20041   [(set (match_dup 0)
20042         (not:SI (match_dup 1)))]
20043   "operands[0] = gen_lowpart (SImode, operands[0]);
20044    operands[1] = gen_lowpart (SImode, operands[1]);")
20045
20046 (define_split
20047   [(set (match_operand 0 "register_operand" "")
20048         (if_then_else (match_operator 1 "comparison_operator"
20049                                 [(reg FLAGS_REG) (const_int 0)])
20050                       (match_operand 2 "register_operand" "")
20051                       (match_operand 3 "register_operand" "")))]
20052   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20053    && (GET_MODE (operands[0]) == HImode
20054        || (GET_MODE (operands[0]) == QImode
20055            && (TARGET_PROMOTE_QImode || optimize_size)))"
20056   [(set (match_dup 0)
20057         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20058   "operands[0] = gen_lowpart (SImode, operands[0]);
20059    operands[2] = gen_lowpart (SImode, operands[2]);
20060    operands[3] = gen_lowpart (SImode, operands[3]);")
20061
20062 \f
20063 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
20064 ;; transform a complex memory operation into two memory to register operations.
20065
20066 ;; Don't push memory operands
20067 (define_peephole2
20068   [(set (match_operand:SI 0 "push_operand" "")
20069         (match_operand:SI 1 "memory_operand" ""))
20070    (match_scratch:SI 2 "r")]
20071   "!optimize_size && !TARGET_PUSH_MEMORY
20072    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20073   [(set (match_dup 2) (match_dup 1))
20074    (set (match_dup 0) (match_dup 2))]
20075   "")
20076
20077 (define_peephole2
20078   [(set (match_operand:DI 0 "push_operand" "")
20079         (match_operand:DI 1 "memory_operand" ""))
20080    (match_scratch:DI 2 "r")]
20081   "!optimize_size && !TARGET_PUSH_MEMORY
20082    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20083   [(set (match_dup 2) (match_dup 1))
20084    (set (match_dup 0) (match_dup 2))]
20085   "")
20086
20087 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20088 ;; SImode pushes.
20089 (define_peephole2
20090   [(set (match_operand:SF 0 "push_operand" "")
20091         (match_operand:SF 1 "memory_operand" ""))
20092    (match_scratch:SF 2 "r")]
20093   "!optimize_size && !TARGET_PUSH_MEMORY
20094    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20095   [(set (match_dup 2) (match_dup 1))
20096    (set (match_dup 0) (match_dup 2))]
20097   "")
20098
20099 (define_peephole2
20100   [(set (match_operand:HI 0 "push_operand" "")
20101         (match_operand:HI 1 "memory_operand" ""))
20102    (match_scratch:HI 2 "r")]
20103   "!optimize_size && !TARGET_PUSH_MEMORY
20104    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20105   [(set (match_dup 2) (match_dup 1))
20106    (set (match_dup 0) (match_dup 2))]
20107   "")
20108
20109 (define_peephole2
20110   [(set (match_operand:QI 0 "push_operand" "")
20111         (match_operand:QI 1 "memory_operand" ""))
20112    (match_scratch:QI 2 "q")]
20113   "!optimize_size && !TARGET_PUSH_MEMORY
20114    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20115   [(set (match_dup 2) (match_dup 1))
20116    (set (match_dup 0) (match_dup 2))]
20117   "")
20118
20119 ;; Don't move an immediate directly to memory when the instruction
20120 ;; gets too big.
20121 (define_peephole2
20122   [(match_scratch:SI 1 "r")
20123    (set (match_operand:SI 0 "memory_operand" "")
20124         (const_int 0))]
20125   "! optimize_size
20126    && ! TARGET_USE_MOV0
20127    && TARGET_SPLIT_LONG_MOVES
20128    && get_attr_length (insn) >= ix86_cost->large_insn
20129    && peep2_regno_dead_p (0, FLAGS_REG)"
20130   [(parallel [(set (match_dup 1) (const_int 0))
20131               (clobber (reg:CC FLAGS_REG))])
20132    (set (match_dup 0) (match_dup 1))]
20133   "")
20134
20135 (define_peephole2
20136   [(match_scratch:HI 1 "r")
20137    (set (match_operand:HI 0 "memory_operand" "")
20138         (const_int 0))]
20139   "! optimize_size
20140    && ! TARGET_USE_MOV0
20141    && TARGET_SPLIT_LONG_MOVES
20142    && get_attr_length (insn) >= ix86_cost->large_insn
20143    && peep2_regno_dead_p (0, FLAGS_REG)"
20144   [(parallel [(set (match_dup 2) (const_int 0))
20145               (clobber (reg:CC FLAGS_REG))])
20146    (set (match_dup 0) (match_dup 1))]
20147   "operands[2] = gen_lowpart (SImode, operands[1]);")
20148
20149 (define_peephole2
20150   [(match_scratch:QI 1 "q")
20151    (set (match_operand:QI 0 "memory_operand" "")
20152         (const_int 0))]
20153   "! optimize_size
20154    && ! TARGET_USE_MOV0
20155    && TARGET_SPLIT_LONG_MOVES
20156    && get_attr_length (insn) >= ix86_cost->large_insn
20157    && peep2_regno_dead_p (0, FLAGS_REG)"
20158   [(parallel [(set (match_dup 2) (const_int 0))
20159               (clobber (reg:CC FLAGS_REG))])
20160    (set (match_dup 0) (match_dup 1))]
20161   "operands[2] = gen_lowpart (SImode, operands[1]);")
20162
20163 (define_peephole2
20164   [(match_scratch:SI 2 "r")
20165    (set (match_operand:SI 0 "memory_operand" "")
20166         (match_operand:SI 1 "immediate_operand" ""))]
20167   "! optimize_size
20168    && TARGET_SPLIT_LONG_MOVES
20169    && get_attr_length (insn) >= ix86_cost->large_insn"
20170   [(set (match_dup 2) (match_dup 1))
20171    (set (match_dup 0) (match_dup 2))]
20172   "")
20173
20174 (define_peephole2
20175   [(match_scratch:HI 2 "r")
20176    (set (match_operand:HI 0 "memory_operand" "")
20177         (match_operand:HI 1 "immediate_operand" ""))]
20178   "! optimize_size
20179    && TARGET_SPLIT_LONG_MOVES
20180    && get_attr_length (insn) >= ix86_cost->large_insn"
20181   [(set (match_dup 2) (match_dup 1))
20182    (set (match_dup 0) (match_dup 2))]
20183   "")
20184
20185 (define_peephole2
20186   [(match_scratch:QI 2 "q")
20187    (set (match_operand:QI 0 "memory_operand" "")
20188         (match_operand:QI 1 "immediate_operand" ""))]
20189   "! optimize_size
20190    && TARGET_SPLIT_LONG_MOVES
20191    && get_attr_length (insn) >= ix86_cost->large_insn"
20192   [(set (match_dup 2) (match_dup 1))
20193    (set (match_dup 0) (match_dup 2))]
20194   "")
20195
20196 ;; Don't compare memory with zero, load and use a test instead.
20197 (define_peephole2
20198   [(set (match_operand 0 "flags_reg_operand" "")
20199         (match_operator 1 "compare_operator"
20200           [(match_operand:SI 2 "memory_operand" "")
20201            (const_int 0)]))
20202    (match_scratch:SI 3 "r")]
20203   " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20204   [(set (match_dup 3) (match_dup 2))
20205    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20206   "")
20207
20208 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20209 ;; Don't split NOTs with a displacement operand, because resulting XOR
20210 ;; will not be pairable anyway.
20211 ;;
20212 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20213 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20214 ;; so this split helps here as well.
20215 ;;
20216 ;; Note: Can't do this as a regular split because we can't get proper
20217 ;; lifetime information then.
20218
20219 (define_peephole2
20220   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20221         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20222   "!optimize_size
20223    && ((TARGET_NOT_UNPAIRABLE
20224         && (!MEM_P (operands[0])
20225             || !memory_displacement_operand (operands[0], SImode)))
20226        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20227    && peep2_regno_dead_p (0, FLAGS_REG)"
20228   [(parallel [(set (match_dup 0)
20229                    (xor:SI (match_dup 1) (const_int -1)))
20230               (clobber (reg:CC FLAGS_REG))])]
20231   "")
20232
20233 (define_peephole2
20234   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20235         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20236   "!optimize_size
20237    && ((TARGET_NOT_UNPAIRABLE
20238         && (!MEM_P (operands[0])
20239             || !memory_displacement_operand (operands[0], HImode)))
20240        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20241    && peep2_regno_dead_p (0, FLAGS_REG)"
20242   [(parallel [(set (match_dup 0)
20243                    (xor:HI (match_dup 1) (const_int -1)))
20244               (clobber (reg:CC FLAGS_REG))])]
20245   "")
20246
20247 (define_peephole2
20248   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20249         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20250   "!optimize_size
20251    && ((TARGET_NOT_UNPAIRABLE
20252         && (!MEM_P (operands[0])
20253             || !memory_displacement_operand (operands[0], QImode)))
20254        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20255    && peep2_regno_dead_p (0, FLAGS_REG)"
20256   [(parallel [(set (match_dup 0)
20257                    (xor:QI (match_dup 1) (const_int -1)))
20258               (clobber (reg:CC FLAGS_REG))])]
20259   "")
20260
20261 ;; Non pairable "test imm, reg" instructions can be translated to
20262 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20263 ;; byte opcode instead of two, have a short form for byte operands),
20264 ;; so do it for other CPUs as well.  Given that the value was dead,
20265 ;; this should not create any new dependencies.  Pass on the sub-word
20266 ;; versions if we're concerned about partial register stalls.
20267
20268 (define_peephole2
20269   [(set (match_operand 0 "flags_reg_operand" "")
20270         (match_operator 1 "compare_operator"
20271           [(and:SI (match_operand:SI 2 "register_operand" "")
20272                    (match_operand:SI 3 "immediate_operand" ""))
20273            (const_int 0)]))]
20274   "ix86_match_ccmode (insn, CCNOmode)
20275    && (true_regnum (operands[2]) != AX_REG
20276        || satisfies_constraint_K (operands[3]))
20277    && peep2_reg_dead_p (1, operands[2])"
20278   [(parallel
20279      [(set (match_dup 0)
20280            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20281                             (const_int 0)]))
20282       (set (match_dup 2)
20283            (and:SI (match_dup 2) (match_dup 3)))])]
20284   "")
20285
20286 ;; We don't need to handle HImode case, because it will be promoted to SImode
20287 ;; on ! TARGET_PARTIAL_REG_STALL
20288
20289 (define_peephole2
20290   [(set (match_operand 0 "flags_reg_operand" "")
20291         (match_operator 1 "compare_operator"
20292           [(and:QI (match_operand:QI 2 "register_operand" "")
20293                    (match_operand:QI 3 "immediate_operand" ""))
20294            (const_int 0)]))]
20295   "! TARGET_PARTIAL_REG_STALL
20296    && ix86_match_ccmode (insn, CCNOmode)
20297    && true_regnum (operands[2]) != AX_REG
20298    && peep2_reg_dead_p (1, operands[2])"
20299   [(parallel
20300      [(set (match_dup 0)
20301            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20302                             (const_int 0)]))
20303       (set (match_dup 2)
20304            (and:QI (match_dup 2) (match_dup 3)))])]
20305   "")
20306
20307 (define_peephole2
20308   [(set (match_operand 0 "flags_reg_operand" "")
20309         (match_operator 1 "compare_operator"
20310           [(and:SI
20311              (zero_extract:SI
20312                (match_operand 2 "ext_register_operand" "")
20313                (const_int 8)
20314                (const_int 8))
20315              (match_operand 3 "const_int_operand" ""))
20316            (const_int 0)]))]
20317   "! TARGET_PARTIAL_REG_STALL
20318    && ix86_match_ccmode (insn, CCNOmode)
20319    && true_regnum (operands[2]) != AX_REG
20320    && peep2_reg_dead_p (1, operands[2])"
20321   [(parallel [(set (match_dup 0)
20322                    (match_op_dup 1
20323                      [(and:SI
20324                         (zero_extract:SI
20325                           (match_dup 2)
20326                           (const_int 8)
20327                           (const_int 8))
20328                         (match_dup 3))
20329                       (const_int 0)]))
20330               (set (zero_extract:SI (match_dup 2)
20331                                     (const_int 8)
20332                                     (const_int 8))
20333                    (and:SI
20334                      (zero_extract:SI
20335                        (match_dup 2)
20336                        (const_int 8)
20337                        (const_int 8))
20338                      (match_dup 3)))])]
20339   "")
20340
20341 ;; Don't do logical operations with memory inputs.
20342 (define_peephole2
20343   [(match_scratch:SI 2 "r")
20344    (parallel [(set (match_operand:SI 0 "register_operand" "")
20345                    (match_operator:SI 3 "arith_or_logical_operator"
20346                      [(match_dup 0)
20347                       (match_operand:SI 1 "memory_operand" "")]))
20348               (clobber (reg:CC FLAGS_REG))])]
20349   "! optimize_size && ! TARGET_READ_MODIFY"
20350   [(set (match_dup 2) (match_dup 1))
20351    (parallel [(set (match_dup 0)
20352                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20353               (clobber (reg:CC FLAGS_REG))])]
20354   "")
20355
20356 (define_peephole2
20357   [(match_scratch:SI 2 "r")
20358    (parallel [(set (match_operand:SI 0 "register_operand" "")
20359                    (match_operator:SI 3 "arith_or_logical_operator"
20360                      [(match_operand:SI 1 "memory_operand" "")
20361                       (match_dup 0)]))
20362               (clobber (reg:CC FLAGS_REG))])]
20363   "! optimize_size && ! TARGET_READ_MODIFY"
20364   [(set (match_dup 2) (match_dup 1))
20365    (parallel [(set (match_dup 0)
20366                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20367               (clobber (reg:CC FLAGS_REG))])]
20368   "")
20369
20370 ; Don't do logical operations with memory outputs
20371 ;
20372 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20373 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20374 ; the same decoder scheduling characteristics as the original.
20375
20376 (define_peephole2
20377   [(match_scratch:SI 2 "r")
20378    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20379                    (match_operator:SI 3 "arith_or_logical_operator"
20380                      [(match_dup 0)
20381                       (match_operand:SI 1 "nonmemory_operand" "")]))
20382               (clobber (reg:CC FLAGS_REG))])]
20383   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20384   [(set (match_dup 2) (match_dup 0))
20385    (parallel [(set (match_dup 2)
20386                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20387               (clobber (reg:CC FLAGS_REG))])
20388    (set (match_dup 0) (match_dup 2))]
20389   "")
20390
20391 (define_peephole2
20392   [(match_scratch:SI 2 "r")
20393    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20394                    (match_operator:SI 3 "arith_or_logical_operator"
20395                      [(match_operand:SI 1 "nonmemory_operand" "")
20396                       (match_dup 0)]))
20397               (clobber (reg:CC FLAGS_REG))])]
20398   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20399   [(set (match_dup 2) (match_dup 0))
20400    (parallel [(set (match_dup 2)
20401                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20402               (clobber (reg:CC FLAGS_REG))])
20403    (set (match_dup 0) (match_dup 2))]
20404   "")
20405
20406 ;; Attempt to always use XOR for zeroing registers.
20407 (define_peephole2
20408   [(set (match_operand 0 "register_operand" "")
20409         (match_operand 1 "const0_operand" ""))]
20410   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20411    && (! TARGET_USE_MOV0 || optimize_size)
20412    && GENERAL_REG_P (operands[0])
20413    && peep2_regno_dead_p (0, FLAGS_REG)"
20414   [(parallel [(set (match_dup 0) (const_int 0))
20415               (clobber (reg:CC FLAGS_REG))])]
20416 {
20417   operands[0] = gen_lowpart (word_mode, operands[0]);
20418 })
20419
20420 (define_peephole2
20421   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20422         (const_int 0))]
20423   "(GET_MODE (operands[0]) == QImode
20424     || GET_MODE (operands[0]) == HImode)
20425    && (! TARGET_USE_MOV0 || optimize_size)
20426    && peep2_regno_dead_p (0, FLAGS_REG)"
20427   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20428               (clobber (reg:CC FLAGS_REG))])])
20429
20430 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20431 (define_peephole2
20432   [(set (match_operand 0 "register_operand" "")
20433         (const_int -1))]
20434   "(GET_MODE (operands[0]) == HImode
20435     || GET_MODE (operands[0]) == SImode
20436     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20437    && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20438    && peep2_regno_dead_p (0, FLAGS_REG)"
20439   [(parallel [(set (match_dup 0) (const_int -1))
20440               (clobber (reg:CC FLAGS_REG))])]
20441   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20442                               operands[0]);")
20443
20444 ;; Attempt to convert simple leas to adds. These can be created by
20445 ;; move expanders.
20446 (define_peephole2
20447   [(set (match_operand:SI 0 "register_operand" "")
20448         (plus:SI (match_dup 0)
20449                  (match_operand:SI 1 "nonmemory_operand" "")))]
20450   "peep2_regno_dead_p (0, FLAGS_REG)"
20451   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20452               (clobber (reg:CC FLAGS_REG))])]
20453   "")
20454
20455 (define_peephole2
20456   [(set (match_operand:SI 0 "register_operand" "")
20457         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20458                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20459   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20460   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20461               (clobber (reg:CC FLAGS_REG))])]
20462   "operands[2] = gen_lowpart (SImode, operands[2]);")
20463
20464 (define_peephole2
20465   [(set (match_operand:DI 0 "register_operand" "")
20466         (plus:DI (match_dup 0)
20467                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20468   "peep2_regno_dead_p (0, FLAGS_REG)"
20469   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20470               (clobber (reg:CC FLAGS_REG))])]
20471   "")
20472
20473 (define_peephole2
20474   [(set (match_operand:SI 0 "register_operand" "")
20475         (mult:SI (match_dup 0)
20476                  (match_operand:SI 1 "const_int_operand" "")))]
20477   "exact_log2 (INTVAL (operands[1])) >= 0
20478    && peep2_regno_dead_p (0, FLAGS_REG)"
20479   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20480               (clobber (reg:CC FLAGS_REG))])]
20481   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20482
20483 (define_peephole2
20484   [(set (match_operand:DI 0 "register_operand" "")
20485         (mult:DI (match_dup 0)
20486                  (match_operand:DI 1 "const_int_operand" "")))]
20487   "exact_log2 (INTVAL (operands[1])) >= 0
20488    && peep2_regno_dead_p (0, FLAGS_REG)"
20489   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20490               (clobber (reg:CC FLAGS_REG))])]
20491   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20492
20493 (define_peephole2
20494   [(set (match_operand:SI 0 "register_operand" "")
20495         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20496                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20497   "exact_log2 (INTVAL (operands[2])) >= 0
20498    && REGNO (operands[0]) == REGNO (operands[1])
20499    && peep2_regno_dead_p (0, FLAGS_REG)"
20500   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20501               (clobber (reg:CC FLAGS_REG))])]
20502   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20503
20504 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20505 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20506 ;; many CPUs it is also faster, since special hardware to avoid esp
20507 ;; dependencies is present.
20508
20509 ;; While some of these conversions may be done using splitters, we use peepholes
20510 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20511
20512 ;; Convert prologue esp subtractions to push.
20513 ;; We need register to push.  In order to keep verify_flow_info happy we have
20514 ;; two choices
20515 ;; - use scratch and clobber it in order to avoid dependencies
20516 ;; - use already live register
20517 ;; We can't use the second way right now, since there is no reliable way how to
20518 ;; verify that given register is live.  First choice will also most likely in
20519 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20520 ;; call clobbered registers are dead.  We may want to use base pointer as an
20521 ;; alternative when no register is available later.
20522
20523 (define_peephole2
20524   [(match_scratch:SI 0 "r")
20525    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20526               (clobber (reg:CC FLAGS_REG))
20527               (clobber (mem:BLK (scratch)))])]
20528   "optimize_size || !TARGET_SUB_ESP_4"
20529   [(clobber (match_dup 0))
20530    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20531               (clobber (mem:BLK (scratch)))])])
20532
20533 (define_peephole2
20534   [(match_scratch:SI 0 "r")
20535    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20536               (clobber (reg:CC FLAGS_REG))
20537               (clobber (mem:BLK (scratch)))])]
20538   "optimize_size || !TARGET_SUB_ESP_8"
20539   [(clobber (match_dup 0))
20540    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20541    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20542               (clobber (mem:BLK (scratch)))])])
20543
20544 ;; Convert esp subtractions to push.
20545 (define_peephole2
20546   [(match_scratch:SI 0 "r")
20547    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20548               (clobber (reg:CC FLAGS_REG))])]
20549   "optimize_size || !TARGET_SUB_ESP_4"
20550   [(clobber (match_dup 0))
20551    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20552
20553 (define_peephole2
20554   [(match_scratch:SI 0 "r")
20555    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20556               (clobber (reg:CC FLAGS_REG))])]
20557   "optimize_size || !TARGET_SUB_ESP_8"
20558   [(clobber (match_dup 0))
20559    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20560    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20561
20562 ;; Convert epilogue deallocator to pop.
20563 (define_peephole2
20564   [(match_scratch:SI 0 "r")
20565    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20566               (clobber (reg:CC FLAGS_REG))
20567               (clobber (mem:BLK (scratch)))])]
20568   "optimize_size || !TARGET_ADD_ESP_4"
20569   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20570               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20571               (clobber (mem:BLK (scratch)))])]
20572   "")
20573
20574 ;; Two pops case is tricky, since pop causes dependency on destination register.
20575 ;; We use two registers if available.
20576 (define_peephole2
20577   [(match_scratch:SI 0 "r")
20578    (match_scratch:SI 1 "r")
20579    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20580               (clobber (reg:CC FLAGS_REG))
20581               (clobber (mem:BLK (scratch)))])]
20582   "optimize_size || !TARGET_ADD_ESP_8"
20583   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20584               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20585               (clobber (mem:BLK (scratch)))])
20586    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20587               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20588   "")
20589
20590 (define_peephole2
20591   [(match_scratch:SI 0 "r")
20592    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20593               (clobber (reg:CC FLAGS_REG))
20594               (clobber (mem:BLK (scratch)))])]
20595   "optimize_size"
20596   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20597               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20598               (clobber (mem:BLK (scratch)))])
20599    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20600               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20601   "")
20602
20603 ;; Convert esp additions to pop.
20604 (define_peephole2
20605   [(match_scratch:SI 0 "r")
20606    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20607               (clobber (reg:CC FLAGS_REG))])]
20608   ""
20609   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20610               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20611   "")
20612
20613 ;; Two pops case is tricky, since pop causes dependency on destination register.
20614 ;; We use two registers if available.
20615 (define_peephole2
20616   [(match_scratch:SI 0 "r")
20617    (match_scratch:SI 1 "r")
20618    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20619               (clobber (reg:CC FLAGS_REG))])]
20620   ""
20621   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20622               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20623    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20624               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20625   "")
20626
20627 (define_peephole2
20628   [(match_scratch:SI 0 "r")
20629    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20630               (clobber (reg:CC FLAGS_REG))])]
20631   "optimize_size"
20632   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20633               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20634    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20635               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20636   "")
20637 \f
20638 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20639 ;; required and register dies.  Similarly for 128 to plus -128.
20640 (define_peephole2
20641   [(set (match_operand 0 "flags_reg_operand" "")
20642         (match_operator 1 "compare_operator"
20643           [(match_operand 2 "register_operand" "")
20644            (match_operand 3 "const_int_operand" "")]))]
20645   "(INTVAL (operands[3]) == -1
20646     || INTVAL (operands[3]) == 1
20647     || INTVAL (operands[3]) == 128)
20648    && ix86_match_ccmode (insn, CCGCmode)
20649    && peep2_reg_dead_p (1, operands[2])"
20650   [(parallel [(set (match_dup 0)
20651                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20652               (clobber (match_dup 2))])]
20653   "")
20654 \f
20655 (define_peephole2
20656   [(match_scratch:DI 0 "r")
20657    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20658               (clobber (reg:CC FLAGS_REG))
20659               (clobber (mem:BLK (scratch)))])]
20660   "optimize_size || !TARGET_SUB_ESP_4"
20661   [(clobber (match_dup 0))
20662    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20663               (clobber (mem:BLK (scratch)))])])
20664
20665 (define_peephole2
20666   [(match_scratch:DI 0 "r")
20667    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20668               (clobber (reg:CC FLAGS_REG))
20669               (clobber (mem:BLK (scratch)))])]
20670   "optimize_size || !TARGET_SUB_ESP_8"
20671   [(clobber (match_dup 0))
20672    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20673    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20674               (clobber (mem:BLK (scratch)))])])
20675
20676 ;; Convert esp subtractions to push.
20677 (define_peephole2
20678   [(match_scratch:DI 0 "r")
20679    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20680               (clobber (reg:CC FLAGS_REG))])]
20681   "optimize_size || !TARGET_SUB_ESP_4"
20682   [(clobber (match_dup 0))
20683    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20684
20685 (define_peephole2
20686   [(match_scratch:DI 0 "r")
20687    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20688               (clobber (reg:CC FLAGS_REG))])]
20689   "optimize_size || !TARGET_SUB_ESP_8"
20690   [(clobber (match_dup 0))
20691    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20692    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20693
20694 ;; Convert epilogue deallocator to pop.
20695 (define_peephole2
20696   [(match_scratch:DI 0 "r")
20697    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20698               (clobber (reg:CC FLAGS_REG))
20699               (clobber (mem:BLK (scratch)))])]
20700   "optimize_size || !TARGET_ADD_ESP_4"
20701   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20702               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20703               (clobber (mem:BLK (scratch)))])]
20704   "")
20705
20706 ;; Two pops case is tricky, since pop causes dependency on destination register.
20707 ;; We use two registers if available.
20708 (define_peephole2
20709   [(match_scratch:DI 0 "r")
20710    (match_scratch:DI 1 "r")
20711    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20712               (clobber (reg:CC FLAGS_REG))
20713               (clobber (mem:BLK (scratch)))])]
20714   "optimize_size || !TARGET_ADD_ESP_8"
20715   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20716               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20717               (clobber (mem:BLK (scratch)))])
20718    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20719               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20720   "")
20721
20722 (define_peephole2
20723   [(match_scratch:DI 0 "r")
20724    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20725               (clobber (reg:CC FLAGS_REG))
20726               (clobber (mem:BLK (scratch)))])]
20727   "optimize_size"
20728   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20729               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20730               (clobber (mem:BLK (scratch)))])
20731    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20732               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20733   "")
20734
20735 ;; Convert esp additions to pop.
20736 (define_peephole2
20737   [(match_scratch:DI 0 "r")
20738    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20739               (clobber (reg:CC FLAGS_REG))])]
20740   ""
20741   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20742               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20743   "")
20744
20745 ;; Two pops case is tricky, since pop causes dependency on destination register.
20746 ;; We use two registers if available.
20747 (define_peephole2
20748   [(match_scratch:DI 0 "r")
20749    (match_scratch:DI 1 "r")
20750    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20751               (clobber (reg:CC FLAGS_REG))])]
20752   ""
20753   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20754               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20755    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20756               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20757   "")
20758
20759 (define_peephole2
20760   [(match_scratch:DI 0 "r")
20761    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20762               (clobber (reg:CC FLAGS_REG))])]
20763   "optimize_size"
20764   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20765               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20766    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20767               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20768   "")
20769 \f
20770 ;; Convert imul by three, five and nine into lea
20771 (define_peephole2
20772   [(parallel
20773     [(set (match_operand:SI 0 "register_operand" "")
20774           (mult:SI (match_operand:SI 1 "register_operand" "")
20775                    (match_operand:SI 2 "const_int_operand" "")))
20776      (clobber (reg:CC FLAGS_REG))])]
20777   "INTVAL (operands[2]) == 3
20778    || INTVAL (operands[2]) == 5
20779    || INTVAL (operands[2]) == 9"
20780   [(set (match_dup 0)
20781         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20782                  (match_dup 1)))]
20783   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20784
20785 (define_peephole2
20786   [(parallel
20787     [(set (match_operand:SI 0 "register_operand" "")
20788           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20789                    (match_operand:SI 2 "const_int_operand" "")))
20790      (clobber (reg:CC FLAGS_REG))])]
20791   "!optimize_size
20792    && (INTVAL (operands[2]) == 3
20793        || INTVAL (operands[2]) == 5
20794        || INTVAL (operands[2]) == 9)"
20795   [(set (match_dup 0) (match_dup 1))
20796    (set (match_dup 0)
20797         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20798                  (match_dup 0)))]
20799   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20800
20801 (define_peephole2
20802   [(parallel
20803     [(set (match_operand:DI 0 "register_operand" "")
20804           (mult:DI (match_operand:DI 1 "register_operand" "")
20805                    (match_operand:DI 2 "const_int_operand" "")))
20806      (clobber (reg:CC FLAGS_REG))])]
20807   "TARGET_64BIT
20808    && (INTVAL (operands[2]) == 3
20809        || INTVAL (operands[2]) == 5
20810        || INTVAL (operands[2]) == 9)"
20811   [(set (match_dup 0)
20812         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20813                  (match_dup 1)))]
20814   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20815
20816 (define_peephole2
20817   [(parallel
20818     [(set (match_operand:DI 0 "register_operand" "")
20819           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20820                    (match_operand:DI 2 "const_int_operand" "")))
20821      (clobber (reg:CC FLAGS_REG))])]
20822   "TARGET_64BIT
20823    && !optimize_size
20824    && (INTVAL (operands[2]) == 3
20825        || INTVAL (operands[2]) == 5
20826        || INTVAL (operands[2]) == 9)"
20827   [(set (match_dup 0) (match_dup 1))
20828    (set (match_dup 0)
20829         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20830                  (match_dup 0)))]
20831   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20832
20833 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20834 ;; imul $32bit_imm, reg, reg is direct decoded.
20835 (define_peephole2
20836   [(match_scratch:DI 3 "r")
20837    (parallel [(set (match_operand:DI 0 "register_operand" "")
20838                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20839                             (match_operand:DI 2 "immediate_operand" "")))
20840               (clobber (reg:CC FLAGS_REG))])]
20841   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20842    && !satisfies_constraint_K (operands[2])"
20843   [(set (match_dup 3) (match_dup 1))
20844    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20845               (clobber (reg:CC FLAGS_REG))])]
20846 "")
20847
20848 (define_peephole2
20849   [(match_scratch:SI 3 "r")
20850    (parallel [(set (match_operand:SI 0 "register_operand" "")
20851                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20852                             (match_operand:SI 2 "immediate_operand" "")))
20853               (clobber (reg:CC FLAGS_REG))])]
20854   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20855    && !satisfies_constraint_K (operands[2])"
20856   [(set (match_dup 3) (match_dup 1))
20857    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20858               (clobber (reg:CC FLAGS_REG))])]
20859 "")
20860
20861 (define_peephole2
20862   [(match_scratch:SI 3 "r")
20863    (parallel [(set (match_operand:DI 0 "register_operand" "")
20864                    (zero_extend:DI
20865                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20866                               (match_operand:SI 2 "immediate_operand" ""))))
20867               (clobber (reg:CC FLAGS_REG))])]
20868   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20869    && !satisfies_constraint_K (operands[2])"
20870   [(set (match_dup 3) (match_dup 1))
20871    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20872               (clobber (reg:CC FLAGS_REG))])]
20873 "")
20874
20875 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20876 ;; Convert it into imul reg, reg
20877 ;; It would be better to force assembler to encode instruction using long
20878 ;; immediate, but there is apparently no way to do so.
20879 (define_peephole2
20880   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20881                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20882                             (match_operand:DI 2 "const_int_operand" "")))
20883               (clobber (reg:CC FLAGS_REG))])
20884    (match_scratch:DI 3 "r")]
20885   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20886    && satisfies_constraint_K (operands[2])"
20887   [(set (match_dup 3) (match_dup 2))
20888    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20889               (clobber (reg:CC FLAGS_REG))])]
20890 {
20891   if (!rtx_equal_p (operands[0], operands[1]))
20892     emit_move_insn (operands[0], operands[1]);
20893 })
20894
20895 (define_peephole2
20896   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20897                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20898                             (match_operand:SI 2 "const_int_operand" "")))
20899               (clobber (reg:CC FLAGS_REG))])
20900    (match_scratch:SI 3 "r")]
20901   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20902    && satisfies_constraint_K (operands[2])"
20903   [(set (match_dup 3) (match_dup 2))
20904    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20905               (clobber (reg:CC FLAGS_REG))])]
20906 {
20907   if (!rtx_equal_p (operands[0], operands[1]))
20908     emit_move_insn (operands[0], operands[1]);
20909 })
20910
20911 (define_peephole2
20912   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20913                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20914                             (match_operand:HI 2 "immediate_operand" "")))
20915               (clobber (reg:CC FLAGS_REG))])
20916    (match_scratch:HI 3 "r")]
20917   "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20918   [(set (match_dup 3) (match_dup 2))
20919    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20920               (clobber (reg:CC FLAGS_REG))])]
20921 {
20922   if (!rtx_equal_p (operands[0], operands[1]))
20923     emit_move_insn (operands[0], operands[1]);
20924 })
20925
20926 ;; After splitting up read-modify operations, array accesses with memory
20927 ;; operands might end up in form:
20928 ;;  sall    $2, %eax
20929 ;;  movl    4(%esp), %edx
20930 ;;  addl    %edx, %eax
20931 ;; instead of pre-splitting:
20932 ;;  sall    $2, %eax
20933 ;;  addl    4(%esp), %eax
20934 ;; Turn it into:
20935 ;;  movl    4(%esp), %edx
20936 ;;  leal    (%edx,%eax,4), %eax
20937
20938 (define_peephole2
20939   [(parallel [(set (match_operand 0 "register_operand" "")
20940                    (ashift (match_operand 1 "register_operand" "")
20941                            (match_operand 2 "const_int_operand" "")))
20942                (clobber (reg:CC FLAGS_REG))])
20943    (set (match_operand 3 "register_operand")
20944         (match_operand 4 "x86_64_general_operand" ""))
20945    (parallel [(set (match_operand 5 "register_operand" "")
20946                    (plus (match_operand 6 "register_operand" "")
20947                          (match_operand 7 "register_operand" "")))
20948                    (clobber (reg:CC FLAGS_REG))])]
20949   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20950    /* Validate MODE for lea.  */
20951    && ((!TARGET_PARTIAL_REG_STALL
20952         && (GET_MODE (operands[0]) == QImode
20953             || GET_MODE (operands[0]) == HImode))
20954        || GET_MODE (operands[0]) == SImode
20955        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20956    /* We reorder load and the shift.  */
20957    && !rtx_equal_p (operands[1], operands[3])
20958    && !reg_overlap_mentioned_p (operands[0], operands[4])
20959    /* Last PLUS must consist of operand 0 and 3.  */
20960    && !rtx_equal_p (operands[0], operands[3])
20961    && (rtx_equal_p (operands[3], operands[6])
20962        || rtx_equal_p (operands[3], operands[7]))
20963    && (rtx_equal_p (operands[0], operands[6])
20964        || rtx_equal_p (operands[0], operands[7]))
20965    /* The intermediate operand 0 must die or be same as output.  */
20966    && (rtx_equal_p (operands[0], operands[5])
20967        || peep2_reg_dead_p (3, operands[0]))"
20968   [(set (match_dup 3) (match_dup 4))
20969    (set (match_dup 0) (match_dup 1))]
20970 {
20971   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20972   int scale = 1 << INTVAL (operands[2]);
20973   rtx index = gen_lowpart (Pmode, operands[1]);
20974   rtx base = gen_lowpart (Pmode, operands[3]);
20975   rtx dest = gen_lowpart (mode, operands[5]);
20976
20977   operands[1] = gen_rtx_PLUS (Pmode, base,
20978                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20979   if (mode != Pmode)
20980     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20981   operands[0] = dest;
20982 })
20983 \f
20984 ;; Call-value patterns last so that the wildcard operand does not
20985 ;; disrupt insn-recog's switch tables.
20986
20987 (define_insn "*call_value_pop_0"
20988   [(set (match_operand 0 "" "")
20989         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20990               (match_operand:SI 2 "" "")))
20991    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20992                             (match_operand:SI 3 "immediate_operand" "")))]
20993   "!TARGET_64BIT"
20994 {
20995   if (SIBLING_CALL_P (insn))
20996     return "jmp\t%P1";
20997   else
20998     return "call\t%P1";
20999 }
21000   [(set_attr "type" "callv")])
21001
21002 (define_insn "*call_value_pop_1"
21003   [(set (match_operand 0 "" "")
21004         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21005               (match_operand:SI 2 "" "")))
21006    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21007                             (match_operand:SI 3 "immediate_operand" "i")))]
21008   "!TARGET_64BIT"
21009 {
21010   if (constant_call_address_operand (operands[1], Pmode))
21011     {
21012       if (SIBLING_CALL_P (insn))
21013         return "jmp\t%P1";
21014       else
21015         return "call\t%P1";
21016     }
21017   if (SIBLING_CALL_P (insn))
21018     return "jmp\t%A1";
21019   else
21020     return "call\t%A1";
21021 }
21022   [(set_attr "type" "callv")])
21023
21024 (define_insn "*call_value_0"
21025   [(set (match_operand 0 "" "")
21026         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21027               (match_operand:SI 2 "" "")))]
21028   "!TARGET_64BIT"
21029 {
21030   if (SIBLING_CALL_P (insn))
21031     return "jmp\t%P1";
21032   else
21033     return "call\t%P1";
21034 }
21035   [(set_attr "type" "callv")])
21036
21037 (define_insn "*call_value_0_rex64"
21038   [(set (match_operand 0 "" "")
21039         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21040               (match_operand:DI 2 "const_int_operand" "")))]
21041   "TARGET_64BIT"
21042 {
21043   if (SIBLING_CALL_P (insn))
21044     return "jmp\t%P1";
21045   else
21046     return "call\t%P1";
21047 }
21048   [(set_attr "type" "callv")])
21049
21050 (define_insn "*call_value_1"
21051   [(set (match_operand 0 "" "")
21052         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21053               (match_operand:SI 2 "" "")))]
21054   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21055 {
21056   if (constant_call_address_operand (operands[1], Pmode))
21057     return "call\t%P1";
21058   return "call\t%A1";
21059 }
21060   [(set_attr "type" "callv")])
21061
21062 (define_insn "*sibcall_value_1"
21063   [(set (match_operand 0 "" "")
21064         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21065               (match_operand:SI 2 "" "")))]
21066   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21067 {
21068   if (constant_call_address_operand (operands[1], Pmode))
21069     return "jmp\t%P1";
21070   return "jmp\t%A1";
21071 }
21072   [(set_attr "type" "callv")])
21073
21074 (define_insn "*call_value_1_rex64"
21075   [(set (match_operand 0 "" "")
21076         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21077               (match_operand:DI 2 "" "")))]
21078   "!SIBLING_CALL_P (insn) && TARGET_64BIT
21079    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21080 {
21081   if (constant_call_address_operand (operands[1], Pmode))
21082     return "call\t%P1";
21083   return "call\t%A1";
21084 }
21085   [(set_attr "type" "callv")])
21086
21087 (define_insn "*call_value_1_rex64_large"
21088   [(set (match_operand 0 "" "")
21089         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21090               (match_operand:DI 2 "" "")))]
21091   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21092   "call\t%A1"
21093   [(set_attr "type" "callv")])
21094
21095 (define_insn "*sibcall_value_1_rex64"
21096   [(set (match_operand 0 "" "")
21097         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21098               (match_operand:DI 2 "" "")))]
21099   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21100   "jmp\t%P1"
21101   [(set_attr "type" "callv")])
21102
21103 (define_insn "*sibcall_value_1_rex64_v"
21104   [(set (match_operand 0 "" "")
21105         (call (mem:QI (reg:DI R11_REG))
21106               (match_operand:DI 1 "" "")))]
21107   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21108   "jmp\t{*%%}r11"
21109   [(set_attr "type" "callv")])
21110 \f
21111 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21112 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21113 ;; caught for use by garbage collectors and the like.  Using an insn that
21114 ;; maps to SIGILL makes it more likely the program will rightfully die.
21115 ;; Keeping with tradition, "6" is in honor of #UD.
21116 (define_insn "trap"
21117   [(trap_if (const_int 1) (const_int 6))]
21118   ""
21119   { return ASM_SHORT "0x0b0f"; }
21120   [(set_attr "length" "2")])
21121
21122 (define_expand "sse_prologue_save"
21123   [(parallel [(set (match_operand:BLK 0 "" "")
21124                    (unspec:BLK [(reg:DI 21)
21125                                 (reg:DI 22)
21126                                 (reg:DI 23)
21127                                 (reg:DI 24)
21128                                 (reg:DI 25)
21129                                 (reg:DI 26)
21130                                 (reg:DI 27)
21131                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21132               (use (match_operand:DI 1 "register_operand" ""))
21133               (use (match_operand:DI 2 "immediate_operand" ""))
21134               (use (label_ref:DI (match_operand 3 "" "")))])]
21135   "TARGET_64BIT"
21136   "")
21137
21138 (define_insn "*sse_prologue_save_insn"
21139   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21140                           (match_operand:DI 4 "const_int_operand" "n")))
21141         (unspec:BLK [(reg:DI 21)
21142                      (reg:DI 22)
21143                      (reg:DI 23)
21144                      (reg:DI 24)
21145                      (reg:DI 25)
21146                      (reg:DI 26)
21147                      (reg:DI 27)
21148                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21149    (use (match_operand:DI 1 "register_operand" "r"))
21150    (use (match_operand:DI 2 "const_int_operand" "i"))
21151    (use (label_ref:DI (match_operand 3 "" "X")))]
21152   "TARGET_64BIT
21153    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21154    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21155   "*
21156 {
21157   int i;
21158   operands[0] = gen_rtx_MEM (Pmode,
21159                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21160   output_asm_insn (\"jmp\\t%A1\", operands);
21161   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21162     {
21163       operands[4] = adjust_address (operands[0], DImode, i*16);
21164       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21165       PUT_MODE (operands[4], TImode);
21166       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21167         output_asm_insn (\"rex\", operands);
21168       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21169     }
21170   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21171                              CODE_LABEL_NUMBER (operands[3]));
21172   return \"\";
21173 }
21174   "
21175   [(set_attr "type" "other")
21176    (set_attr "length_immediate" "0")
21177    (set_attr "length_address" "0")
21178    (set_attr "length" "135")
21179    (set_attr "memory" "store")
21180    (set_attr "modrm" "0")
21181    (set_attr "mode" "DI")])
21182
21183 (define_expand "prefetch"
21184   [(prefetch (match_operand 0 "address_operand" "")
21185              (match_operand:SI 1 "const_int_operand" "")
21186              (match_operand:SI 2 "const_int_operand" ""))]
21187   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21188 {
21189   int rw = INTVAL (operands[1]);
21190   int locality = INTVAL (operands[2]);
21191
21192   gcc_assert (rw == 0 || rw == 1);
21193   gcc_assert (locality >= 0 && locality <= 3);
21194   gcc_assert (GET_MODE (operands[0]) == Pmode
21195               || GET_MODE (operands[0]) == VOIDmode);
21196
21197   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21198      supported by SSE counterpart or the SSE prefetch is not available
21199      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21200      of locality.  */
21201   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21202     operands[2] = GEN_INT (3);
21203   else
21204     operands[1] = const0_rtx;
21205 })
21206
21207 (define_insn "*prefetch_sse"
21208   [(prefetch (match_operand:SI 0 "address_operand" "p")
21209              (const_int 0)
21210              (match_operand:SI 1 "const_int_operand" ""))]
21211   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21212 {
21213   static const char * const patterns[4] = {
21214    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21215   };
21216
21217   int locality = INTVAL (operands[1]);
21218   gcc_assert (locality >= 0 && locality <= 3);
21219
21220   return patterns[locality];
21221 }
21222   [(set_attr "type" "sse")
21223    (set_attr "memory" "none")])
21224
21225 (define_insn "*prefetch_sse_rex"
21226   [(prefetch (match_operand:DI 0 "address_operand" "p")
21227              (const_int 0)
21228              (match_operand:SI 1 "const_int_operand" ""))]
21229   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21230 {
21231   static const char * const patterns[4] = {
21232    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21233   };
21234
21235   int locality = INTVAL (operands[1]);
21236   gcc_assert (locality >= 0 && locality <= 3);
21237
21238   return patterns[locality];
21239 }
21240   [(set_attr "type" "sse")
21241    (set_attr "memory" "none")])
21242
21243 (define_insn "*prefetch_3dnow"
21244   [(prefetch (match_operand:SI 0 "address_operand" "p")
21245              (match_operand:SI 1 "const_int_operand" "n")
21246              (const_int 3))]
21247   "TARGET_3DNOW && !TARGET_64BIT"
21248 {
21249   if (INTVAL (operands[1]) == 0)
21250     return "prefetch\t%a0";
21251   else
21252     return "prefetchw\t%a0";
21253 }
21254   [(set_attr "type" "mmx")
21255    (set_attr "memory" "none")])
21256
21257 (define_insn "*prefetch_3dnow_rex"
21258   [(prefetch (match_operand:DI 0 "address_operand" "p")
21259              (match_operand:SI 1 "const_int_operand" "n")
21260              (const_int 3))]
21261   "TARGET_3DNOW && TARGET_64BIT"
21262 {
21263   if (INTVAL (operands[1]) == 0)
21264     return "prefetch\t%a0";
21265   else
21266     return "prefetchw\t%a0";
21267 }
21268   [(set_attr "type" "mmx")
21269    (set_attr "memory" "none")])
21270
21271 (define_expand "stack_protect_set"
21272   [(match_operand 0 "memory_operand" "")
21273    (match_operand 1 "memory_operand" "")]
21274   ""
21275 {
21276 #ifdef TARGET_THREAD_SSP_OFFSET
21277   if (TARGET_64BIT)
21278     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21279                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21280   else
21281     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21282                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21283 #else
21284   if (TARGET_64BIT)
21285     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21286   else
21287     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21288 #endif
21289   DONE;
21290 })
21291
21292 (define_insn "stack_protect_set_si"
21293   [(set (match_operand:SI 0 "memory_operand" "=m")
21294         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21295    (set (match_scratch:SI 2 "=&r") (const_int 0))
21296    (clobber (reg:CC FLAGS_REG))]
21297   ""
21298   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21299   [(set_attr "type" "multi")])
21300
21301 (define_insn "stack_protect_set_di"
21302   [(set (match_operand:DI 0 "memory_operand" "=m")
21303         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21304    (set (match_scratch:DI 2 "=&r") (const_int 0))
21305    (clobber (reg:CC FLAGS_REG))]
21306   "TARGET_64BIT"
21307   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21308   [(set_attr "type" "multi")])
21309
21310 (define_insn "stack_tls_protect_set_si"
21311   [(set (match_operand:SI 0 "memory_operand" "=m")
21312         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21313    (set (match_scratch:SI 2 "=&r") (const_int 0))
21314    (clobber (reg:CC FLAGS_REG))]
21315   ""
21316   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21317   [(set_attr "type" "multi")])
21318
21319 (define_insn "stack_tls_protect_set_di"
21320   [(set (match_operand:DI 0 "memory_operand" "=m")
21321         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21322    (set (match_scratch:DI 2 "=&r") (const_int 0))
21323    (clobber (reg:CC FLAGS_REG))]
21324   "TARGET_64BIT"
21325   {
21326      /* The kernel uses a different segment register for performance reasons; a
21327         system call would not have to trash the userspace segment register,
21328         which would be expensive */
21329      if (ix86_cmodel != CM_KERNEL)
21330         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21331      else
21332         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21333   }
21334   [(set_attr "type" "multi")])
21335
21336 (define_expand "stack_protect_test"
21337   [(match_operand 0 "memory_operand" "")
21338    (match_operand 1 "memory_operand" "")
21339    (match_operand 2 "" "")]
21340   ""
21341 {
21342   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21343   ix86_compare_op0 = operands[0];
21344   ix86_compare_op1 = operands[1];
21345   ix86_compare_emitted = flags;
21346
21347 #ifdef TARGET_THREAD_SSP_OFFSET
21348   if (TARGET_64BIT)
21349     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21350                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21351   else
21352     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21353                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21354 #else
21355   if (TARGET_64BIT)
21356     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21357   else
21358     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21359 #endif
21360   emit_jump_insn (gen_beq (operands[2]));
21361   DONE;
21362 })
21363
21364 (define_insn "stack_protect_test_si"
21365   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21366         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21367                      (match_operand:SI 2 "memory_operand" "m")]
21368                     UNSPEC_SP_TEST))
21369    (clobber (match_scratch:SI 3 "=&r"))]
21370   ""
21371   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21372   [(set_attr "type" "multi")])
21373
21374 (define_insn "stack_protect_test_di"
21375   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21376         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21377                      (match_operand:DI 2 "memory_operand" "m")]
21378                     UNSPEC_SP_TEST))
21379    (clobber (match_scratch:DI 3 "=&r"))]
21380   "TARGET_64BIT"
21381   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21382   [(set_attr "type" "multi")])
21383
21384 (define_insn "stack_tls_protect_test_si"
21385   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21386         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21387                      (match_operand:SI 2 "const_int_operand" "i")]
21388                     UNSPEC_SP_TLS_TEST))
21389    (clobber (match_scratch:SI 3 "=r"))]
21390   ""
21391   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21392   [(set_attr "type" "multi")])
21393
21394 (define_insn "stack_tls_protect_test_di"
21395   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21396         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21397                      (match_operand:DI 2 "const_int_operand" "i")]
21398                     UNSPEC_SP_TLS_TEST))
21399    (clobber (match_scratch:DI 3 "=r"))]
21400   "TARGET_64BIT"
21401   {
21402      /* The kernel uses a different segment register for performance reasons; a
21403         system call would not have to trash the userspace segment register,
21404         which would be expensive */
21405      if (ix86_cmodel != CM_KERNEL)
21406         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21407      else
21408         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21409   }
21410   [(set_attr "type" "multi")])
21411
21412 (define_mode_iterator CRC32MODE [QI HI SI])
21413 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21414 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21415
21416 (define_insn "sse4_2_crc32<mode>"
21417   [(set (match_operand:SI 0 "register_operand" "=r")
21418         (unspec:SI
21419           [(match_operand:SI 1 "register_operand" "0")
21420            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21421           UNSPEC_CRC32))]
21422   "TARGET_SSE4_2"
21423   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21424   [(set_attr "type" "sselog1")
21425    (set_attr "prefix_rep" "1")
21426    (set_attr "prefix_extra" "1")
21427    (set_attr "mode" "SI")])
21428
21429 (define_insn "sse4_2_crc32di"
21430   [(set (match_operand:DI 0 "register_operand" "=r")
21431         (unspec:DI
21432           [(match_operand:DI 1 "register_operand" "0")
21433            (match_operand:DI 2 "nonimmediate_operand" "rm")]
21434           UNSPEC_CRC32))]
21435   "TARGET_SSE4_2 && TARGET_64BIT"
21436   "crc32q\t{%2, %0|%0, %2}"
21437   [(set_attr "type" "sselog1")
21438    (set_attr "prefix_rep" "1")
21439    (set_attr "prefix_extra" "1")
21440    (set_attr "mode" "DI")])
21441
21442 (include "mmx.md")
21443 (include "sse.md")
21444 (include "sync.md")