OSDN Git Service

eb942d60d9cc97a82de9eaecf7be2aa44955fe03
[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 "nonimmediate_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 "nonimmediate_operand" "0,m")))
15461    (clobber (match_scratch:DI 0 "=r,X"))
15462    (clobber (match_scratch:SI 1 "=r,r"))
15463    (clobber (match_scratch:HI 2 "=Q,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 (MEM_P (operands[3]))
15480     emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
15481   else if (! TARGET_64BIT)
15482     operands[1] = gen_highpart (SImode, operands[3]);
15483   else
15484     {
15485       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15486       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15487     }
15488 })
15489
15490 (define_expand "paritysi2"
15491   [(set (match_operand:SI 0 "register_operand" "")
15492         (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
15493   "! TARGET_POPCNT"
15494 {
15495   rtx scratch = gen_reg_rtx (QImode);
15496   rtx cond;
15497
15498   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15499
15500   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15501                          gen_rtx_REG (CCmode, FLAGS_REG),
15502                          const0_rtx);
15503   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15504
15505   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15506   DONE;
15507 })
15508
15509 (define_insn_and_split "paritysi2_cmp"
15510   [(set (reg:CC FLAGS_REG)
15511         (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
15512    (clobber (match_scratch:SI 0 "=r,X"))
15513    (clobber (match_scratch:HI 1 "=Q,Q"))]
15514   "! TARGET_POPCNT"
15515   "#"
15516   "&& reload_completed"
15517   [(parallel
15518      [(set (match_dup 1)
15519            (xor:HI (match_dup 1) (match_dup 3)))
15520       (clobber (reg:CC FLAGS_REG))])
15521    (parallel
15522      [(set (reg:CC FLAGS_REG)
15523            (parity:CC (match_dup 1)))
15524       (clobber (match_dup 1))])]
15525 {
15526   operands[3] = gen_lowpart (HImode, operands[2]);
15527
15528   if (MEM_P (operands[2]))
15529     emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15530   else
15531     {
15532       emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15533       emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15534     }
15535 })
15536
15537 (define_insn "*parityhi2_cmp"
15538   [(set (reg:CC FLAGS_REG)
15539         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15540    (clobber (match_scratch:HI 0 "=Q"))]
15541   "! TARGET_POPCNT"
15542   "xor{b}\t{%h0, %b0|%b0, %h0}"
15543   [(set_attr "length" "2")
15544    (set_attr "mode" "HI")])
15545
15546 (define_insn "*parityqi2_cmp"
15547   [(set (reg:CC FLAGS_REG)
15548         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15549   "! TARGET_POPCNT"
15550   "test{b}\t%0, %0"
15551   [(set_attr "length" "2")
15552    (set_attr "mode" "QI")])
15553 \f
15554 ;; Thread-local storage patterns for ELF.
15555 ;;
15556 ;; Note that these code sequences must appear exactly as shown
15557 ;; in order to allow linker relaxation.
15558
15559 (define_insn "*tls_global_dynamic_32_gnu"
15560   [(set (match_operand:SI 0 "register_operand" "=a")
15561         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15562                     (match_operand:SI 2 "tls_symbolic_operand" "")
15563                     (match_operand:SI 3 "call_insn_operand" "")]
15564                     UNSPEC_TLS_GD))
15565    (clobber (match_scratch:SI 4 "=d"))
15566    (clobber (match_scratch:SI 5 "=c"))
15567    (clobber (reg:CC FLAGS_REG))]
15568   "!TARGET_64BIT && TARGET_GNU_TLS"
15569   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15570   [(set_attr "type" "multi")
15571    (set_attr "length" "12")])
15572
15573 (define_insn "*tls_global_dynamic_32_sun"
15574   [(set (match_operand:SI 0 "register_operand" "=a")
15575         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15576                     (match_operand:SI 2 "tls_symbolic_operand" "")
15577                     (match_operand:SI 3 "call_insn_operand" "")]
15578                     UNSPEC_TLS_GD))
15579    (clobber (match_scratch:SI 4 "=d"))
15580    (clobber (match_scratch:SI 5 "=c"))
15581    (clobber (reg:CC FLAGS_REG))]
15582   "!TARGET_64BIT && TARGET_SUN_TLS"
15583   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15584         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15585   [(set_attr "type" "multi")
15586    (set_attr "length" "14")])
15587
15588 (define_expand "tls_global_dynamic_32"
15589   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15590                    (unspec:SI
15591                     [(match_dup 2)
15592                      (match_operand:SI 1 "tls_symbolic_operand" "")
15593                      (match_dup 3)]
15594                     UNSPEC_TLS_GD))
15595               (clobber (match_scratch:SI 4 ""))
15596               (clobber (match_scratch:SI 5 ""))
15597               (clobber (reg:CC FLAGS_REG))])]
15598   ""
15599 {
15600   if (flag_pic)
15601     operands[2] = pic_offset_table_rtx;
15602   else
15603     {
15604       operands[2] = gen_reg_rtx (Pmode);
15605       emit_insn (gen_set_got (operands[2]));
15606     }
15607   if (TARGET_GNU2_TLS)
15608     {
15609        emit_insn (gen_tls_dynamic_gnu2_32
15610                   (operands[0], operands[1], operands[2]));
15611        DONE;
15612     }
15613   operands[3] = ix86_tls_get_addr ();
15614 })
15615
15616 (define_insn "*tls_global_dynamic_64"
15617   [(set (match_operand:DI 0 "register_operand" "=a")
15618         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15619                  (match_operand:DI 3 "" "")))
15620    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15621               UNSPEC_TLS_GD)]
15622   "TARGET_64BIT"
15623   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15624   [(set_attr "type" "multi")
15625    (set_attr "length" "16")])
15626
15627 (define_expand "tls_global_dynamic_64"
15628   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15629                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15630               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15631                          UNSPEC_TLS_GD)])]
15632   ""
15633 {
15634   if (TARGET_GNU2_TLS)
15635     {
15636        emit_insn (gen_tls_dynamic_gnu2_64
15637                   (operands[0], operands[1]));
15638        DONE;
15639     }
15640   operands[2] = ix86_tls_get_addr ();
15641 })
15642
15643 (define_insn "*tls_local_dynamic_base_32_gnu"
15644   [(set (match_operand:SI 0 "register_operand" "=a")
15645         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15646                     (match_operand:SI 2 "call_insn_operand" "")]
15647                    UNSPEC_TLS_LD_BASE))
15648    (clobber (match_scratch:SI 3 "=d"))
15649    (clobber (match_scratch:SI 4 "=c"))
15650    (clobber (reg:CC FLAGS_REG))]
15651   "!TARGET_64BIT && TARGET_GNU_TLS"
15652   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15653   [(set_attr "type" "multi")
15654    (set_attr "length" "11")])
15655
15656 (define_insn "*tls_local_dynamic_base_32_sun"
15657   [(set (match_operand:SI 0 "register_operand" "=a")
15658         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15659                     (match_operand:SI 2 "call_insn_operand" "")]
15660                    UNSPEC_TLS_LD_BASE))
15661    (clobber (match_scratch:SI 3 "=d"))
15662    (clobber (match_scratch:SI 4 "=c"))
15663    (clobber (reg:CC FLAGS_REG))]
15664   "!TARGET_64BIT && TARGET_SUN_TLS"
15665   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15666         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15667   [(set_attr "type" "multi")
15668    (set_attr "length" "13")])
15669
15670 (define_expand "tls_local_dynamic_base_32"
15671   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15672                    (unspec:SI [(match_dup 1) (match_dup 2)]
15673                               UNSPEC_TLS_LD_BASE))
15674               (clobber (match_scratch:SI 3 ""))
15675               (clobber (match_scratch:SI 4 ""))
15676               (clobber (reg:CC FLAGS_REG))])]
15677   ""
15678 {
15679   if (flag_pic)
15680     operands[1] = pic_offset_table_rtx;
15681   else
15682     {
15683       operands[1] = gen_reg_rtx (Pmode);
15684       emit_insn (gen_set_got (operands[1]));
15685     }
15686   if (TARGET_GNU2_TLS)
15687     {
15688        emit_insn (gen_tls_dynamic_gnu2_32
15689                   (operands[0], ix86_tls_module_base (), operands[1]));
15690        DONE;
15691     }
15692   operands[2] = ix86_tls_get_addr ();
15693 })
15694
15695 (define_insn "*tls_local_dynamic_base_64"
15696   [(set (match_operand:DI 0 "register_operand" "=a")
15697         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15698                  (match_operand:DI 2 "" "")))
15699    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15700   "TARGET_64BIT"
15701   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15702   [(set_attr "type" "multi")
15703    (set_attr "length" "12")])
15704
15705 (define_expand "tls_local_dynamic_base_64"
15706   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15707                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15708               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15709   ""
15710 {
15711   if (TARGET_GNU2_TLS)
15712     {
15713        emit_insn (gen_tls_dynamic_gnu2_64
15714                   (operands[0], ix86_tls_module_base ()));
15715        DONE;
15716     }
15717   operands[1] = ix86_tls_get_addr ();
15718 })
15719
15720 ;; Local dynamic of a single variable is a lose.  Show combine how
15721 ;; to convert that back to global dynamic.
15722
15723 (define_insn_and_split "*tls_local_dynamic_32_once"
15724   [(set (match_operand:SI 0 "register_operand" "=a")
15725         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15726                              (match_operand:SI 2 "call_insn_operand" "")]
15727                             UNSPEC_TLS_LD_BASE)
15728                  (const:SI (unspec:SI
15729                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15730                             UNSPEC_DTPOFF))))
15731    (clobber (match_scratch:SI 4 "=d"))
15732    (clobber (match_scratch:SI 5 "=c"))
15733    (clobber (reg:CC FLAGS_REG))]
15734   ""
15735   "#"
15736   ""
15737   [(parallel [(set (match_dup 0)
15738                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15739                               UNSPEC_TLS_GD))
15740               (clobber (match_dup 4))
15741               (clobber (match_dup 5))
15742               (clobber (reg:CC FLAGS_REG))])]
15743   "")
15744
15745 ;; Load and add the thread base pointer from %gs:0.
15746
15747 (define_insn "*load_tp_si"
15748   [(set (match_operand:SI 0 "register_operand" "=r")
15749         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15750   "!TARGET_64BIT"
15751   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15752   [(set_attr "type" "imov")
15753    (set_attr "modrm" "0")
15754    (set_attr "length" "7")
15755    (set_attr "memory" "load")
15756    (set_attr "imm_disp" "false")])
15757
15758 (define_insn "*add_tp_si"
15759   [(set (match_operand:SI 0 "register_operand" "=r")
15760         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15761                  (match_operand:SI 1 "register_operand" "0")))
15762    (clobber (reg:CC FLAGS_REG))]
15763   "!TARGET_64BIT"
15764   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15765   [(set_attr "type" "alu")
15766    (set_attr "modrm" "0")
15767    (set_attr "length" "7")
15768    (set_attr "memory" "load")
15769    (set_attr "imm_disp" "false")])
15770
15771 (define_insn "*load_tp_di"
15772   [(set (match_operand:DI 0 "register_operand" "=r")
15773         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15774   "TARGET_64BIT"
15775   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15776   [(set_attr "type" "imov")
15777    (set_attr "modrm" "0")
15778    (set_attr "length" "7")
15779    (set_attr "memory" "load")
15780    (set_attr "imm_disp" "false")])
15781
15782 (define_insn "*add_tp_di"
15783   [(set (match_operand:DI 0 "register_operand" "=r")
15784         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15785                  (match_operand:DI 1 "register_operand" "0")))
15786    (clobber (reg:CC FLAGS_REG))]
15787   "TARGET_64BIT"
15788   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15789   [(set_attr "type" "alu")
15790    (set_attr "modrm" "0")
15791    (set_attr "length" "7")
15792    (set_attr "memory" "load")
15793    (set_attr "imm_disp" "false")])
15794
15795 ;; GNU2 TLS patterns can be split.
15796
15797 (define_expand "tls_dynamic_gnu2_32"
15798   [(set (match_dup 3)
15799         (plus:SI (match_operand:SI 2 "register_operand" "")
15800                  (const:SI
15801                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15802                              UNSPEC_TLSDESC))))
15803    (parallel
15804     [(set (match_operand:SI 0 "register_operand" "")
15805           (unspec:SI [(match_dup 1) (match_dup 3)
15806                       (match_dup 2) (reg:SI SP_REG)]
15807                       UNSPEC_TLSDESC))
15808      (clobber (reg:CC FLAGS_REG))])]
15809   "!TARGET_64BIT && TARGET_GNU2_TLS"
15810 {
15811   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15812   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15813 })
15814
15815 (define_insn "*tls_dynamic_lea_32"
15816   [(set (match_operand:SI 0 "register_operand" "=r")
15817         (plus:SI (match_operand:SI 1 "register_operand" "b")
15818                  (const:SI
15819                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15820                               UNSPEC_TLSDESC))))]
15821   "!TARGET_64BIT && TARGET_GNU2_TLS"
15822   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15823   [(set_attr "type" "lea")
15824    (set_attr "mode" "SI")
15825    (set_attr "length" "6")
15826    (set_attr "length_address" "4")])
15827
15828 (define_insn "*tls_dynamic_call_32"
15829   [(set (match_operand:SI 0 "register_operand" "=a")
15830         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15831                     (match_operand:SI 2 "register_operand" "0")
15832                     ;; we have to make sure %ebx still points to the GOT
15833                     (match_operand:SI 3 "register_operand" "b")
15834                     (reg:SI SP_REG)]
15835                    UNSPEC_TLSDESC))
15836    (clobber (reg:CC FLAGS_REG))]
15837   "!TARGET_64BIT && TARGET_GNU2_TLS"
15838   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15839   [(set_attr "type" "call")
15840    (set_attr "length" "2")
15841    (set_attr "length_address" "0")])
15842
15843 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15844   [(set (match_operand:SI 0 "register_operand" "=&a")
15845         (plus:SI
15846          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15847                      (match_operand:SI 4 "" "")
15848                      (match_operand:SI 2 "register_operand" "b")
15849                      (reg:SI SP_REG)]
15850                     UNSPEC_TLSDESC)
15851          (const:SI (unspec:SI
15852                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15853                     UNSPEC_DTPOFF))))
15854    (clobber (reg:CC FLAGS_REG))]
15855   "!TARGET_64BIT && TARGET_GNU2_TLS"
15856   "#"
15857   ""
15858   [(set (match_dup 0) (match_dup 5))]
15859 {
15860   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15861   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15862 })
15863
15864 (define_expand "tls_dynamic_gnu2_64"
15865   [(set (match_dup 2)
15866         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15867                    UNSPEC_TLSDESC))
15868    (parallel
15869     [(set (match_operand:DI 0 "register_operand" "")
15870           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15871                      UNSPEC_TLSDESC))
15872      (clobber (reg:CC FLAGS_REG))])]
15873   "TARGET_64BIT && TARGET_GNU2_TLS"
15874 {
15875   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15876   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15877 })
15878
15879 (define_insn "*tls_dynamic_lea_64"
15880   [(set (match_operand:DI 0 "register_operand" "=r")
15881         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15882                    UNSPEC_TLSDESC))]
15883   "TARGET_64BIT && TARGET_GNU2_TLS"
15884   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15885   [(set_attr "type" "lea")
15886    (set_attr "mode" "DI")
15887    (set_attr "length" "7")
15888    (set_attr "length_address" "4")])
15889
15890 (define_insn "*tls_dynamic_call_64"
15891   [(set (match_operand:DI 0 "register_operand" "=a")
15892         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15893                     (match_operand:DI 2 "register_operand" "0")
15894                     (reg:DI SP_REG)]
15895                    UNSPEC_TLSDESC))
15896    (clobber (reg:CC FLAGS_REG))]
15897   "TARGET_64BIT && TARGET_GNU2_TLS"
15898   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15899   [(set_attr "type" "call")
15900    (set_attr "length" "2")
15901    (set_attr "length_address" "0")])
15902
15903 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15904   [(set (match_operand:DI 0 "register_operand" "=&a")
15905         (plus:DI
15906          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15907                      (match_operand:DI 3 "" "")
15908                      (reg:DI SP_REG)]
15909                     UNSPEC_TLSDESC)
15910          (const:DI (unspec:DI
15911                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15912                     UNSPEC_DTPOFF))))
15913    (clobber (reg:CC FLAGS_REG))]
15914   "TARGET_64BIT && TARGET_GNU2_TLS"
15915   "#"
15916   ""
15917   [(set (match_dup 0) (match_dup 4))]
15918 {
15919   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15920   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15921 })
15922
15923 ;;
15924 \f
15925 ;; These patterns match the binary 387 instructions for addM3, subM3,
15926 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15927 ;; SFmode.  The first is the normal insn, the second the same insn but
15928 ;; with one operand a conversion, and the third the same insn but with
15929 ;; the other operand a conversion.  The conversion may be SFmode or
15930 ;; SImode if the target mode DFmode, but only SImode if the target mode
15931 ;; is SFmode.
15932
15933 ;; Gcc is slightly more smart about handling normal two address instructions
15934 ;; so use special patterns for add and mull.
15935
15936 (define_insn "*fop_sf_comm_mixed"
15937   [(set (match_operand:SF 0 "register_operand" "=f,x")
15938         (match_operator:SF 3 "binary_fp_operator"
15939                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15940                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15941   "TARGET_MIX_SSE_I387
15942    && COMMUTATIVE_ARITH_P (operands[3])
15943    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15944   "* return output_387_binary_op (insn, operands);"
15945   [(set (attr "type")
15946         (if_then_else (eq_attr "alternative" "1")
15947            (if_then_else (match_operand:SF 3 "mult_operator" "")
15948               (const_string "ssemul")
15949               (const_string "sseadd"))
15950            (if_then_else (match_operand:SF 3 "mult_operator" "")
15951               (const_string "fmul")
15952               (const_string "fop"))))
15953    (set_attr "mode" "SF")])
15954
15955 (define_insn "*fop_sf_comm_sse"
15956   [(set (match_operand:SF 0 "register_operand" "=x")
15957         (match_operator:SF 3 "binary_fp_operator"
15958                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15959                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15960   "TARGET_SSE_MATH
15961    && COMMUTATIVE_ARITH_P (operands[3])
15962    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15963   "* return output_387_binary_op (insn, operands);"
15964   [(set (attr "type")
15965         (if_then_else (match_operand:SF 3 "mult_operator" "")
15966            (const_string "ssemul")
15967            (const_string "sseadd")))
15968    (set_attr "mode" "SF")])
15969
15970 (define_insn "*fop_sf_comm_i387"
15971   [(set (match_operand:SF 0 "register_operand" "=f")
15972         (match_operator:SF 3 "binary_fp_operator"
15973                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15974                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15975   "TARGET_80387
15976    && COMMUTATIVE_ARITH_P (operands[3])
15977    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15978   "* return output_387_binary_op (insn, operands);"
15979   [(set (attr "type")
15980         (if_then_else (match_operand:SF 3 "mult_operator" "")
15981            (const_string "fmul")
15982            (const_string "fop")))
15983    (set_attr "mode" "SF")])
15984
15985 (define_insn "*fop_sf_1_mixed"
15986   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15987         (match_operator:SF 3 "binary_fp_operator"
15988                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15989                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15990   "TARGET_MIX_SSE_I387
15991    && !COMMUTATIVE_ARITH_P (operands[3])
15992    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15993   "* return output_387_binary_op (insn, operands);"
15994   [(set (attr "type")
15995         (cond [(and (eq_attr "alternative" "2")
15996                     (match_operand:SF 3 "mult_operator" ""))
15997                  (const_string "ssemul")
15998                (and (eq_attr "alternative" "2")
15999                     (match_operand:SF 3 "div_operator" ""))
16000                  (const_string "ssediv")
16001                (eq_attr "alternative" "2")
16002                  (const_string "sseadd")
16003                (match_operand:SF 3 "mult_operator" "")
16004                  (const_string "fmul")
16005                (match_operand:SF 3 "div_operator" "")
16006                  (const_string "fdiv")
16007               ]
16008               (const_string "fop")))
16009    (set_attr "mode" "SF")])
16010
16011 (define_insn "*rcpsf2_sse"
16012   [(set (match_operand:SF 0 "register_operand" "=x")
16013         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16014                    UNSPEC_RCP))]
16015   "TARGET_SSE_MATH"
16016   "rcpss\t{%1, %0|%0, %1}"
16017   [(set_attr "type" "sse")
16018    (set_attr "mode" "SF")])
16019
16020 (define_insn "*fop_sf_1_sse"
16021   [(set (match_operand:SF 0 "register_operand" "=x")
16022         (match_operator:SF 3 "binary_fp_operator"
16023                         [(match_operand:SF 1 "register_operand" "0")
16024                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
16025   "TARGET_SSE_MATH
16026    && !COMMUTATIVE_ARITH_P (operands[3])"
16027   "* return output_387_binary_op (insn, operands);"
16028   [(set (attr "type")
16029         (cond [(match_operand:SF 3 "mult_operator" "")
16030                  (const_string "ssemul")
16031                (match_operand:SF 3 "div_operator" "")
16032                  (const_string "ssediv")
16033               ]
16034               (const_string "sseadd")))
16035    (set_attr "mode" "SF")])
16036
16037 ;; This pattern is not fully shadowed by the pattern above.
16038 (define_insn "*fop_sf_1_i387"
16039   [(set (match_operand:SF 0 "register_operand" "=f,f")
16040         (match_operator:SF 3 "binary_fp_operator"
16041                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
16042                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
16043   "TARGET_80387 && !TARGET_SSE_MATH
16044    && !COMMUTATIVE_ARITH_P (operands[3])
16045    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16046   "* return output_387_binary_op (insn, operands);"
16047   [(set (attr "type")
16048         (cond [(match_operand:SF 3 "mult_operator" "")
16049                  (const_string "fmul")
16050                (match_operand:SF 3 "div_operator" "")
16051                  (const_string "fdiv")
16052               ]
16053               (const_string "fop")))
16054    (set_attr "mode" "SF")])
16055
16056 ;; ??? Add SSE splitters for these!
16057 (define_insn "*fop_sf_2<mode>_i387"
16058   [(set (match_operand:SF 0 "register_operand" "=f,f")
16059         (match_operator:SF 3 "binary_fp_operator"
16060           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16061            (match_operand:SF 2 "register_operand" "0,0")]))]
16062   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16063   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16064   [(set (attr "type")
16065         (cond [(match_operand:SF 3 "mult_operator" "")
16066                  (const_string "fmul")
16067                (match_operand:SF 3 "div_operator" "")
16068                  (const_string "fdiv")
16069               ]
16070               (const_string "fop")))
16071    (set_attr "fp_int_src" "true")
16072    (set_attr "mode" "<MODE>")])
16073
16074 (define_insn "*fop_sf_3<mode>_i387"
16075   [(set (match_operand:SF 0 "register_operand" "=f,f")
16076         (match_operator:SF 3 "binary_fp_operator"
16077           [(match_operand:SF 1 "register_operand" "0,0")
16078            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16079   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16080   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16081   [(set (attr "type")
16082         (cond [(match_operand:SF 3 "mult_operator" "")
16083                  (const_string "fmul")
16084                (match_operand:SF 3 "div_operator" "")
16085                  (const_string "fdiv")
16086               ]
16087               (const_string "fop")))
16088    (set_attr "fp_int_src" "true")
16089    (set_attr "mode" "<MODE>")])
16090
16091 (define_insn "*fop_df_comm_mixed"
16092   [(set (match_operand:DF 0 "register_operand" "=f,x")
16093         (match_operator:DF 3 "binary_fp_operator"
16094           [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
16095            (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
16096   "TARGET_SSE2 && TARGET_MIX_SSE_I387
16097    && COMMUTATIVE_ARITH_P (operands[3])
16098    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16099   "* return output_387_binary_op (insn, operands);"
16100   [(set (attr "type")
16101         (if_then_else (eq_attr "alternative" "1")
16102            (if_then_else (match_operand:DF 3 "mult_operator" "")
16103               (const_string "ssemul")
16104               (const_string "sseadd"))
16105            (if_then_else (match_operand:DF 3 "mult_operator" "")
16106               (const_string "fmul")
16107               (const_string "fop"))))
16108    (set_attr "mode" "DF")])
16109
16110 (define_insn "*fop_df_comm_sse"
16111   [(set (match_operand:DF 0 "register_operand" "=x")
16112         (match_operator:DF 3 "binary_fp_operator"
16113           [(match_operand:DF 1 "nonimmediate_operand" "%0")
16114            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16115   "TARGET_SSE2 && TARGET_SSE_MATH
16116    && COMMUTATIVE_ARITH_P (operands[3])
16117    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16118   "* return output_387_binary_op (insn, operands);"
16119   [(set (attr "type")
16120         (if_then_else (match_operand:DF 3 "mult_operator" "")
16121            (const_string "ssemul")
16122            (const_string "sseadd")))
16123    (set_attr "mode" "DF")])
16124
16125 (define_insn "*fop_df_comm_i387"
16126   [(set (match_operand:DF 0 "register_operand" "=f")
16127         (match_operator:DF 3 "binary_fp_operator"
16128                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
16129                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
16130   "TARGET_80387
16131    && COMMUTATIVE_ARITH_P (operands[3])
16132    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16133   "* return output_387_binary_op (insn, operands);"
16134   [(set (attr "type")
16135         (if_then_else (match_operand:DF 3 "mult_operator" "")
16136            (const_string "fmul")
16137            (const_string "fop")))
16138    (set_attr "mode" "DF")])
16139
16140 (define_insn "*fop_df_1_mixed"
16141   [(set (match_operand:DF 0 "register_operand" "=f,f,x")
16142         (match_operator:DF 3 "binary_fp_operator"
16143           [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
16144            (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
16145   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
16146    && !COMMUTATIVE_ARITH_P (operands[3])
16147    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16148   "* return output_387_binary_op (insn, operands);"
16149   [(set (attr "type")
16150         (cond [(and (eq_attr "alternative" "2")
16151                     (match_operand:DF 3 "mult_operator" ""))
16152                  (const_string "ssemul")
16153                (and (eq_attr "alternative" "2")
16154                     (match_operand:DF 3 "div_operator" ""))
16155                  (const_string "ssediv")
16156                (eq_attr "alternative" "2")
16157                  (const_string "sseadd")
16158                (match_operand:DF 3 "mult_operator" "")
16159                  (const_string "fmul")
16160                (match_operand:DF 3 "div_operator" "")
16161                  (const_string "fdiv")
16162               ]
16163               (const_string "fop")))
16164    (set_attr "mode" "DF")])
16165
16166 (define_insn "*fop_df_1_sse"
16167   [(set (match_operand:DF 0 "register_operand" "=x")
16168         (match_operator:DF 3 "binary_fp_operator"
16169           [(match_operand:DF 1 "register_operand" "0")
16170            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16171   "TARGET_SSE2 && TARGET_SSE_MATH
16172    && !COMMUTATIVE_ARITH_P (operands[3])"
16173   "* return output_387_binary_op (insn, operands);"
16174   [(set_attr "mode" "DF")
16175    (set (attr "type")
16176         (cond [(match_operand:DF 3 "mult_operator" "")
16177                  (const_string "ssemul")
16178                (match_operand:DF 3 "div_operator" "")
16179                  (const_string "ssediv")
16180               ]
16181               (const_string "sseadd")))])
16182
16183 ;; This pattern is not fully shadowed by the pattern above.
16184 (define_insn "*fop_df_1_i387"
16185   [(set (match_operand:DF 0 "register_operand" "=f,f")
16186         (match_operator:DF 3 "binary_fp_operator"
16187                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
16188                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
16189   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16190    && !COMMUTATIVE_ARITH_P (operands[3])
16191    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16192   "* return output_387_binary_op (insn, operands);"
16193   [(set (attr "type")
16194         (cond [(match_operand:DF 3 "mult_operator" "")
16195                  (const_string "fmul")
16196                (match_operand:DF 3 "div_operator" "")
16197                  (const_string "fdiv")
16198               ]
16199               (const_string "fop")))
16200    (set_attr "mode" "DF")])
16201
16202 ;; ??? Add SSE splitters for these!
16203 (define_insn "*fop_df_2<mode>_i387"
16204   [(set (match_operand:DF 0 "register_operand" "=f,f")
16205         (match_operator:DF 3 "binary_fp_operator"
16206            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16207             (match_operand:DF 2 "register_operand" "0,0")]))]
16208   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16209    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16210   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16211   [(set (attr "type")
16212         (cond [(match_operand:DF 3 "mult_operator" "")
16213                  (const_string "fmul")
16214                (match_operand:DF 3 "div_operator" "")
16215                  (const_string "fdiv")
16216               ]
16217               (const_string "fop")))
16218    (set_attr "fp_int_src" "true")
16219    (set_attr "mode" "<MODE>")])
16220
16221 (define_insn "*fop_df_3<mode>_i387"
16222   [(set (match_operand:DF 0 "register_operand" "=f,f")
16223         (match_operator:DF 3 "binary_fp_operator"
16224            [(match_operand:DF 1 "register_operand" "0,0")
16225             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16226   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16227    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16228   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16229   [(set (attr "type")
16230         (cond [(match_operand:DF 3 "mult_operator" "")
16231                  (const_string "fmul")
16232                (match_operand:DF 3 "div_operator" "")
16233                  (const_string "fdiv")
16234               ]
16235               (const_string "fop")))
16236    (set_attr "fp_int_src" "true")
16237    (set_attr "mode" "<MODE>")])
16238
16239 (define_insn "*fop_df_4_i387"
16240   [(set (match_operand:DF 0 "register_operand" "=f,f")
16241         (match_operator:DF 3 "binary_fp_operator"
16242            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16243             (match_operand:DF 2 "register_operand" "0,f")]))]
16244   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16245    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16246   "* return output_387_binary_op (insn, operands);"
16247   [(set (attr "type")
16248         (cond [(match_operand:DF 3 "mult_operator" "")
16249                  (const_string "fmul")
16250                (match_operand:DF 3 "div_operator" "")
16251                  (const_string "fdiv")
16252               ]
16253               (const_string "fop")))
16254    (set_attr "mode" "SF")])
16255
16256 (define_insn "*fop_df_5_i387"
16257   [(set (match_operand:DF 0 "register_operand" "=f,f")
16258         (match_operator:DF 3 "binary_fp_operator"
16259           [(match_operand:DF 1 "register_operand" "0,f")
16260            (float_extend:DF
16261             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16262   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16263   "* return output_387_binary_op (insn, operands);"
16264   [(set (attr "type")
16265         (cond [(match_operand:DF 3 "mult_operator" "")
16266                  (const_string "fmul")
16267                (match_operand:DF 3 "div_operator" "")
16268                  (const_string "fdiv")
16269               ]
16270               (const_string "fop")))
16271    (set_attr "mode" "SF")])
16272
16273 (define_insn "*fop_df_6_i387"
16274   [(set (match_operand:DF 0 "register_operand" "=f,f")
16275         (match_operator:DF 3 "binary_fp_operator"
16276           [(float_extend:DF
16277             (match_operand:SF 1 "register_operand" "0,f"))
16278            (float_extend:DF
16279             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16280   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16281   "* return output_387_binary_op (insn, operands);"
16282   [(set (attr "type")
16283         (cond [(match_operand:DF 3 "mult_operator" "")
16284                  (const_string "fmul")
16285                (match_operand:DF 3 "div_operator" "")
16286                  (const_string "fdiv")
16287               ]
16288               (const_string "fop")))
16289    (set_attr "mode" "SF")])
16290
16291 (define_insn "*fop_xf_comm_i387"
16292   [(set (match_operand:XF 0 "register_operand" "=f")
16293         (match_operator:XF 3 "binary_fp_operator"
16294                         [(match_operand:XF 1 "register_operand" "%0")
16295                          (match_operand:XF 2 "register_operand" "f")]))]
16296   "TARGET_80387
16297    && COMMUTATIVE_ARITH_P (operands[3])"
16298   "* return output_387_binary_op (insn, operands);"
16299   [(set (attr "type")
16300         (if_then_else (match_operand:XF 3 "mult_operator" "")
16301            (const_string "fmul")
16302            (const_string "fop")))
16303    (set_attr "mode" "XF")])
16304
16305 (define_insn "*fop_xf_1_i387"
16306   [(set (match_operand:XF 0 "register_operand" "=f,f")
16307         (match_operator:XF 3 "binary_fp_operator"
16308                         [(match_operand:XF 1 "register_operand" "0,f")
16309                          (match_operand:XF 2 "register_operand" "f,0")]))]
16310   "TARGET_80387
16311    && !COMMUTATIVE_ARITH_P (operands[3])"
16312   "* return output_387_binary_op (insn, operands);"
16313   [(set (attr "type")
16314         (cond [(match_operand:XF 3 "mult_operator" "")
16315                  (const_string "fmul")
16316                (match_operand:XF 3 "div_operator" "")
16317                  (const_string "fdiv")
16318               ]
16319               (const_string "fop")))
16320    (set_attr "mode" "XF")])
16321
16322 (define_insn "*fop_xf_2<mode>_i387"
16323   [(set (match_operand:XF 0 "register_operand" "=f,f")
16324         (match_operator:XF 3 "binary_fp_operator"
16325            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16326             (match_operand:XF 2 "register_operand" "0,0")]))]
16327   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16328   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16329   [(set (attr "type")
16330         (cond [(match_operand:XF 3 "mult_operator" "")
16331                  (const_string "fmul")
16332                (match_operand:XF 3 "div_operator" "")
16333                  (const_string "fdiv")
16334               ]
16335               (const_string "fop")))
16336    (set_attr "fp_int_src" "true")
16337    (set_attr "mode" "<MODE>")])
16338
16339 (define_insn "*fop_xf_3<mode>_i387"
16340   [(set (match_operand:XF 0 "register_operand" "=f,f")
16341         (match_operator:XF 3 "binary_fp_operator"
16342           [(match_operand:XF 1 "register_operand" "0,0")
16343            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16344   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16345   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16346   [(set (attr "type")
16347         (cond [(match_operand:XF 3 "mult_operator" "")
16348                  (const_string "fmul")
16349                (match_operand:XF 3 "div_operator" "")
16350                  (const_string "fdiv")
16351               ]
16352               (const_string "fop")))
16353    (set_attr "fp_int_src" "true")
16354    (set_attr "mode" "<MODE>")])
16355
16356 (define_insn "*fop_xf_4_i387"
16357   [(set (match_operand:XF 0 "register_operand" "=f,f")
16358         (match_operator:XF 3 "binary_fp_operator"
16359            [(float_extend:XF
16360               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16361             (match_operand:XF 2 "register_operand" "0,f")]))]
16362   "TARGET_80387"
16363   "* return output_387_binary_op (insn, operands);"
16364   [(set (attr "type")
16365         (cond [(match_operand:XF 3 "mult_operator" "")
16366                  (const_string "fmul")
16367                (match_operand:XF 3 "div_operator" "")
16368                  (const_string "fdiv")
16369               ]
16370               (const_string "fop")))
16371    (set_attr "mode" "SF")])
16372
16373 (define_insn "*fop_xf_5_i387"
16374   [(set (match_operand:XF 0 "register_operand" "=f,f")
16375         (match_operator:XF 3 "binary_fp_operator"
16376           [(match_operand:XF 1 "register_operand" "0,f")
16377            (float_extend:XF
16378              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16379   "TARGET_80387"
16380   "* return output_387_binary_op (insn, operands);"
16381   [(set (attr "type")
16382         (cond [(match_operand:XF 3 "mult_operator" "")
16383                  (const_string "fmul")
16384                (match_operand:XF 3 "div_operator" "")
16385                  (const_string "fdiv")
16386               ]
16387               (const_string "fop")))
16388    (set_attr "mode" "SF")])
16389
16390 (define_insn "*fop_xf_6_i387"
16391   [(set (match_operand:XF 0 "register_operand" "=f,f")
16392         (match_operator:XF 3 "binary_fp_operator"
16393           [(float_extend:XF
16394              (match_operand:MODEF 1 "register_operand" "0,f"))
16395            (float_extend:XF
16396              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16397   "TARGET_80387"
16398   "* return output_387_binary_op (insn, operands);"
16399   [(set (attr "type")
16400         (cond [(match_operand:XF 3 "mult_operator" "")
16401                  (const_string "fmul")
16402                (match_operand:XF 3 "div_operator" "")
16403                  (const_string "fdiv")
16404               ]
16405               (const_string "fop")))
16406    (set_attr "mode" "SF")])
16407
16408 (define_split
16409   [(set (match_operand 0 "register_operand" "")
16410         (match_operator 3 "binary_fp_operator"
16411            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16412             (match_operand 2 "register_operand" "")]))]
16413   "reload_completed
16414    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16415   [(const_int 0)]
16416 {
16417   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16418   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16419   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16420                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16421                                           GET_MODE (operands[3]),
16422                                           operands[4],
16423                                           operands[2])));
16424   ix86_free_from_memory (GET_MODE (operands[1]));
16425   DONE;
16426 })
16427
16428 (define_split
16429   [(set (match_operand 0 "register_operand" "")
16430         (match_operator 3 "binary_fp_operator"
16431            [(match_operand 1 "register_operand" "")
16432             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16433   "reload_completed
16434    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16435   [(const_int 0)]
16436 {
16437   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16438   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16439   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16440                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16441                                           GET_MODE (operands[3]),
16442                                           operands[1],
16443                                           operands[4])));
16444   ix86_free_from_memory (GET_MODE (operands[2]));
16445   DONE;
16446 })
16447 \f
16448 ;; FPU special functions.
16449
16450 ;; This pattern implements a no-op XFmode truncation for
16451 ;; all fancy i386 XFmode math functions.
16452
16453 (define_insn "truncxf<mode>2_i387_noop_unspec"
16454   [(set (match_operand:MODEF 0 "register_operand" "=f")
16455         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16456         UNSPEC_TRUNC_NOOP))]
16457   "TARGET_USE_FANCY_MATH_387"
16458   "* return output_387_reg_move (insn, operands);"
16459   [(set_attr "type" "fmov")
16460    (set_attr "mode" "<MODE>")])
16461
16462 (define_insn "sqrtxf2"
16463   [(set (match_operand:XF 0 "register_operand" "=f")
16464         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16465   "TARGET_USE_FANCY_MATH_387"
16466   "fsqrt"
16467   [(set_attr "type" "fpspc")
16468    (set_attr "mode" "XF")
16469    (set_attr "athlon_decode" "direct")
16470    (set_attr "amdfam10_decode" "direct")])
16471
16472 (define_insn "sqrt_extend<mode>xf2_i387"
16473   [(set (match_operand:XF 0 "register_operand" "=f")
16474         (sqrt:XF
16475           (float_extend:XF
16476             (match_operand:MODEF 1 "register_operand" "0"))))]
16477   "TARGET_USE_FANCY_MATH_387"
16478   "fsqrt"
16479   [(set_attr "type" "fpspc")
16480    (set_attr "mode" "XF")
16481    (set_attr "athlon_decode" "direct")
16482    (set_attr "amdfam10_decode" "direct")])
16483
16484 (define_insn "*rsqrtsf2_sse"
16485   [(set (match_operand:SF 0 "register_operand" "=x")
16486         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16487                    UNSPEC_RSQRT))]
16488   "TARGET_SSE_MATH"
16489   "rsqrtss\t{%1, %0|%0, %1}"
16490   [(set_attr "type" "sse")
16491    (set_attr "mode" "SF")])
16492
16493 (define_expand "rsqrtsf2"
16494   [(set (match_operand:SF 0 "register_operand" "")
16495         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16496                    UNSPEC_RSQRT))]
16497   "TARGET_SSE_MATH"
16498 {
16499   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16500   DONE;
16501 })
16502
16503 (define_insn "*sqrt<mode>2_sse"
16504   [(set (match_operand:MODEF 0 "register_operand" "=x")
16505         (sqrt:MODEF
16506           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16507   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16508   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16509   [(set_attr "type" "sse")
16510    (set_attr "mode" "<MODE>")
16511    (set_attr "athlon_decode" "*")
16512    (set_attr "amdfam10_decode" "*")])
16513
16514 (define_expand "sqrt<mode>2"
16515   [(set (match_operand:MODEF 0 "register_operand" "")
16516         (sqrt:MODEF
16517           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16518   "TARGET_USE_FANCY_MATH_387
16519    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16520 {
16521   if (<MODE>mode == SFmode
16522       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16523       && flag_finite_math_only && !flag_trapping_math
16524       && flag_unsafe_math_optimizations)
16525     {
16526       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16527       DONE;
16528     }
16529
16530   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16531     {
16532       rtx op0 = gen_reg_rtx (XFmode);
16533       rtx op1 = force_reg (<MODE>mode, operands[1]);
16534
16535       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16536       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16537       DONE;
16538    }
16539 })
16540
16541 (define_insn "fpremxf4_i387"
16542   [(set (match_operand:XF 0 "register_operand" "=f")
16543         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16544                     (match_operand:XF 3 "register_operand" "1")]
16545                    UNSPEC_FPREM_F))
16546    (set (match_operand:XF 1 "register_operand" "=u")
16547         (unspec:XF [(match_dup 2) (match_dup 3)]
16548                    UNSPEC_FPREM_U))
16549    (set (reg:CCFP FPSR_REG)
16550         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16551                      UNSPEC_C2_FLAG))]
16552   "TARGET_USE_FANCY_MATH_387"
16553   "fprem"
16554   [(set_attr "type" "fpspc")
16555    (set_attr "mode" "XF")])
16556
16557 (define_expand "fmodxf3"
16558   [(use (match_operand:XF 0 "register_operand" ""))
16559    (use (match_operand:XF 1 "register_operand" ""))
16560    (use (match_operand:XF 2 "register_operand" ""))]
16561   "TARGET_USE_FANCY_MATH_387"
16562 {
16563   rtx label = gen_label_rtx ();
16564
16565   rtx op2;
16566
16567   if (rtx_equal_p (operands[1], operands[2]))
16568     {
16569       op2 = gen_reg_rtx (XFmode);
16570       emit_move_insn (op2, operands[2]);
16571     }
16572   else
16573     op2 = operands[2];
16574
16575   emit_label (label);
16576   emit_insn (gen_fpremxf4_i387 (operands[1], op2, operands[1], op2));
16577   ix86_emit_fp_unordered_jump (label);
16578   LABEL_NUSES (label) = 1;
16579
16580   emit_move_insn (operands[0], operands[1]);
16581   DONE;
16582 })
16583
16584 (define_expand "fmod<mode>3"
16585   [(use (match_operand:MODEF 0 "register_operand" ""))
16586    (use (match_operand:MODEF 1 "general_operand" ""))
16587    (use (match_operand:MODEF 2 "general_operand" ""))]
16588   "TARGET_USE_FANCY_MATH_387"
16589 {
16590   rtx label = gen_label_rtx ();
16591
16592   rtx op1 = gen_reg_rtx (XFmode);
16593   rtx op2 = gen_reg_rtx (XFmode);
16594
16595   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16596   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16597
16598   emit_label (label);
16599   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16600   ix86_emit_fp_unordered_jump (label);
16601   LABEL_NUSES (label) = 1;
16602
16603   /* Truncate the result properly for strict SSE math.  */
16604   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16605       && !TARGET_MIX_SSE_I387)
16606     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16607   else
16608     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16609
16610   DONE;
16611 })
16612
16613 (define_insn "fprem1xf4_i387"
16614   [(set (match_operand:XF 0 "register_operand" "=f")
16615         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16616                     (match_operand:XF 3 "register_operand" "1")]
16617                    UNSPEC_FPREM1_F))
16618    (set (match_operand:XF 1 "register_operand" "=u")
16619         (unspec:XF [(match_dup 2) (match_dup 3)]
16620                    UNSPEC_FPREM1_U))
16621    (set (reg:CCFP FPSR_REG)
16622         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16623                      UNSPEC_C2_FLAG))]
16624   "TARGET_USE_FANCY_MATH_387"
16625   "fprem1"
16626   [(set_attr "type" "fpspc")
16627    (set_attr "mode" "XF")])
16628
16629 (define_expand "remainderxf3"
16630   [(use (match_operand:XF 0 "register_operand" ""))
16631    (use (match_operand:XF 1 "register_operand" ""))
16632    (use (match_operand:XF 2 "register_operand" ""))]
16633   "TARGET_USE_FANCY_MATH_387"
16634 {
16635   rtx label = gen_label_rtx ();
16636
16637   rtx op2;
16638
16639   if (rtx_equal_p (operands[1], operands[2]))
16640     {
16641       op2 = gen_reg_rtx (XFmode);
16642       emit_move_insn (op2, operands[2]);
16643     }
16644   else
16645     op2 = operands[2];
16646
16647   emit_label (label);
16648   emit_insn (gen_fprem1xf4_i387 (operands[1], op2, operands[1], op2));
16649   ix86_emit_fp_unordered_jump (label);
16650   LABEL_NUSES (label) = 1;
16651
16652   emit_move_insn (operands[0], operands[1]);
16653   DONE;
16654 })
16655
16656 (define_expand "remainder<mode>3"
16657   [(use (match_operand:MODEF 0 "register_operand" ""))
16658    (use (match_operand:MODEF 1 "general_operand" ""))
16659    (use (match_operand:MODEF 2 "general_operand" ""))]
16660   "TARGET_USE_FANCY_MATH_387"
16661 {
16662   rtx label = gen_label_rtx ();
16663
16664   rtx op1 = gen_reg_rtx (XFmode);
16665   rtx op2 = gen_reg_rtx (XFmode);
16666
16667   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16668   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16669
16670   emit_label (label);
16671
16672   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16673   ix86_emit_fp_unordered_jump (label);
16674   LABEL_NUSES (label) = 1;
16675
16676   /* Truncate the result properly for strict SSE math.  */
16677   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16678       && !TARGET_MIX_SSE_I387)
16679     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16680   else
16681     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16682
16683   DONE;
16684 })
16685
16686 (define_insn "*sinxf2_i387"
16687   [(set (match_operand:XF 0 "register_operand" "=f")
16688         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16689   "TARGET_USE_FANCY_MATH_387
16690    && flag_unsafe_math_optimizations"
16691   "fsin"
16692   [(set_attr "type" "fpspc")
16693    (set_attr "mode" "XF")])
16694
16695 (define_insn "*sin_extend<mode>xf2_i387"
16696   [(set (match_operand:XF 0 "register_operand" "=f")
16697         (unspec:XF [(float_extend:XF
16698                       (match_operand:MODEF 1 "register_operand" "0"))]
16699                    UNSPEC_SIN))]
16700   "TARGET_USE_FANCY_MATH_387
16701    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16702        || TARGET_MIX_SSE_I387)
16703    && flag_unsafe_math_optimizations"
16704   "fsin"
16705   [(set_attr "type" "fpspc")
16706    (set_attr "mode" "XF")])
16707
16708 (define_insn "*cosxf2_i387"
16709   [(set (match_operand:XF 0 "register_operand" "=f")
16710         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16711   "TARGET_USE_FANCY_MATH_387
16712    && flag_unsafe_math_optimizations"
16713   "fcos"
16714   [(set_attr "type" "fpspc")
16715    (set_attr "mode" "XF")])
16716
16717 (define_insn "*cos_extend<mode>xf2_i387"
16718   [(set (match_operand:XF 0 "register_operand" "=f")
16719         (unspec:XF [(float_extend:XF
16720                       (match_operand:MODEF 1 "register_operand" "0"))]
16721                    UNSPEC_COS))]
16722   "TARGET_USE_FANCY_MATH_387
16723    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16724        || TARGET_MIX_SSE_I387)
16725    && flag_unsafe_math_optimizations"
16726   "fcos"
16727   [(set_attr "type" "fpspc")
16728    (set_attr "mode" "XF")])
16729
16730 ;; When sincos pattern is defined, sin and cos builtin functions will be
16731 ;; expanded to sincos pattern with one of its outputs left unused.
16732 ;; CSE pass will figure out if two sincos patterns can be combined,
16733 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16734 ;; depending on the unused output.
16735
16736 (define_insn "sincosxf3"
16737   [(set (match_operand:XF 0 "register_operand" "=f")
16738         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16739                    UNSPEC_SINCOS_COS))
16740    (set (match_operand:XF 1 "register_operand" "=u")
16741         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16742   "TARGET_USE_FANCY_MATH_387
16743    && flag_unsafe_math_optimizations"
16744   "fsincos"
16745   [(set_attr "type" "fpspc")
16746    (set_attr "mode" "XF")])
16747
16748 (define_split
16749   [(set (match_operand:XF 0 "register_operand" "")
16750         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16751                    UNSPEC_SINCOS_COS))
16752    (set (match_operand:XF 1 "register_operand" "")
16753         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16754   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16755    && !(reload_completed || reload_in_progress)"
16756   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16757   "")
16758
16759 (define_split
16760   [(set (match_operand:XF 0 "register_operand" "")
16761         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16762                    UNSPEC_SINCOS_COS))
16763    (set (match_operand:XF 1 "register_operand" "")
16764         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16765   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16766    && !(reload_completed || reload_in_progress)"
16767   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16768   "")
16769
16770 (define_insn "sincos_extend<mode>xf3_i387"
16771   [(set (match_operand:XF 0 "register_operand" "=f")
16772         (unspec:XF [(float_extend:XF
16773                       (match_operand:MODEF 2 "register_operand" "0"))]
16774                    UNSPEC_SINCOS_COS))
16775    (set (match_operand:XF 1 "register_operand" "=u")
16776         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16777   "TARGET_USE_FANCY_MATH_387
16778    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16779        || TARGET_MIX_SSE_I387)
16780    && flag_unsafe_math_optimizations"
16781   "fsincos"
16782   [(set_attr "type" "fpspc")
16783    (set_attr "mode" "XF")])
16784
16785 (define_split
16786   [(set (match_operand:XF 0 "register_operand" "")
16787         (unspec:XF [(float_extend:XF
16788                       (match_operand:MODEF 2 "register_operand" ""))]
16789                    UNSPEC_SINCOS_COS))
16790    (set (match_operand:XF 1 "register_operand" "")
16791         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16792   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16793    && !(reload_completed || reload_in_progress)"
16794   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16795   "")
16796
16797 (define_split
16798   [(set (match_operand:XF 0 "register_operand" "")
16799         (unspec:XF [(float_extend:XF
16800                       (match_operand:MODEF 2 "register_operand" ""))]
16801                    UNSPEC_SINCOS_COS))
16802    (set (match_operand:XF 1 "register_operand" "")
16803         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16804   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16805    && !(reload_completed || reload_in_progress)"
16806   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16807   "")
16808
16809 (define_expand "sincos<mode>3"
16810   [(use (match_operand:MODEF 0 "register_operand" ""))
16811    (use (match_operand:MODEF 1 "register_operand" ""))
16812    (use (match_operand:MODEF 2 "register_operand" ""))]
16813   "TARGET_USE_FANCY_MATH_387
16814    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16815        || TARGET_MIX_SSE_I387)
16816    && flag_unsafe_math_optimizations"
16817 {
16818   rtx op0 = gen_reg_rtx (XFmode);
16819   rtx op1 = gen_reg_rtx (XFmode);
16820
16821   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16822   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16823   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16824   DONE;
16825 })
16826
16827 (define_insn "fptanxf4_i387"
16828   [(set (match_operand:XF 0 "register_operand" "=f")
16829         (match_operand:XF 3 "const_double_operand" "F"))
16830    (set (match_operand:XF 1 "register_operand" "=u")
16831         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16832                    UNSPEC_TAN))]
16833   "TARGET_USE_FANCY_MATH_387
16834    && flag_unsafe_math_optimizations
16835    && standard_80387_constant_p (operands[3]) == 2"
16836   "fptan"
16837   [(set_attr "type" "fpspc")
16838    (set_attr "mode" "XF")])
16839
16840 (define_insn "fptan_extend<mode>xf4_i387"
16841   [(set (match_operand:MODEF 0 "register_operand" "=f")
16842         (match_operand:MODEF 3 "const_double_operand" "F"))
16843    (set (match_operand:XF 1 "register_operand" "=u")
16844         (unspec:XF [(float_extend:XF
16845                       (match_operand:MODEF 2 "register_operand" "0"))]
16846                    UNSPEC_TAN))]
16847   "TARGET_USE_FANCY_MATH_387
16848    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16849        || TARGET_MIX_SSE_I387)
16850    && flag_unsafe_math_optimizations
16851    && standard_80387_constant_p (operands[3]) == 2"
16852   "fptan"
16853   [(set_attr "type" "fpspc")
16854    (set_attr "mode" "XF")])
16855
16856 (define_expand "tanxf2"
16857   [(use (match_operand:XF 0 "register_operand" ""))
16858    (use (match_operand:XF 1 "register_operand" ""))]
16859   "TARGET_USE_FANCY_MATH_387
16860    && flag_unsafe_math_optimizations"
16861 {
16862   rtx one = gen_reg_rtx (XFmode);
16863   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16864
16865   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16866   DONE;
16867 })
16868
16869 (define_expand "tan<mode>2"
16870   [(use (match_operand:MODEF 0 "register_operand" ""))
16871    (use (match_operand:MODEF 1 "register_operand" ""))]
16872   "TARGET_USE_FANCY_MATH_387
16873    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16874        || TARGET_MIX_SSE_I387)
16875    && flag_unsafe_math_optimizations"
16876 {
16877   rtx op0 = gen_reg_rtx (XFmode);
16878
16879   rtx one = gen_reg_rtx (<MODE>mode);
16880   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16881
16882   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16883                                              operands[1], op2));
16884   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16885   DONE;
16886 })
16887
16888 (define_insn "*fpatanxf3_i387"
16889   [(set (match_operand:XF 0 "register_operand" "=f")
16890         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16891                     (match_operand:XF 2 "register_operand" "u")]
16892                    UNSPEC_FPATAN))
16893    (clobber (match_scratch:XF 3 "=2"))]
16894   "TARGET_USE_FANCY_MATH_387
16895    && flag_unsafe_math_optimizations"
16896   "fpatan"
16897   [(set_attr "type" "fpspc")
16898    (set_attr "mode" "XF")])
16899
16900 (define_insn "fpatan_extend<mode>xf3_i387"
16901   [(set (match_operand:XF 0 "register_operand" "=f")
16902         (unspec:XF [(float_extend:XF
16903                       (match_operand:MODEF 1 "register_operand" "0"))
16904                     (float_extend:XF
16905                       (match_operand:MODEF 2 "register_operand" "u"))]
16906                    UNSPEC_FPATAN))
16907    (clobber (match_scratch:XF 3 "=2"))]
16908   "TARGET_USE_FANCY_MATH_387
16909    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16910        || TARGET_MIX_SSE_I387)
16911    && flag_unsafe_math_optimizations"
16912   "fpatan"
16913   [(set_attr "type" "fpspc")
16914    (set_attr "mode" "XF")])
16915
16916 (define_expand "atan2xf3"
16917   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16918                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16919                                (match_operand:XF 1 "register_operand" "")]
16920                               UNSPEC_FPATAN))
16921               (clobber (match_scratch:XF 3 ""))])]
16922   "TARGET_USE_FANCY_MATH_387
16923    && flag_unsafe_math_optimizations"
16924   "")
16925
16926 (define_expand "atan2<mode>3"
16927   [(use (match_operand:MODEF 0 "register_operand" ""))
16928    (use (match_operand:MODEF 1 "register_operand" ""))
16929    (use (match_operand:MODEF 2 "register_operand" ""))]
16930   "TARGET_USE_FANCY_MATH_387
16931    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16932        || TARGET_MIX_SSE_I387)
16933    && flag_unsafe_math_optimizations"
16934 {
16935   rtx op0 = gen_reg_rtx (XFmode);
16936
16937   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16938   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16939   DONE;
16940 })
16941
16942 (define_expand "atanxf2"
16943   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16944                    (unspec:XF [(match_dup 2)
16945                                (match_operand:XF 1 "register_operand" "")]
16946                               UNSPEC_FPATAN))
16947               (clobber (match_scratch:XF 3 ""))])]
16948   "TARGET_USE_FANCY_MATH_387
16949    && flag_unsafe_math_optimizations"
16950 {
16951   operands[2] = gen_reg_rtx (XFmode);
16952   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16953 })
16954
16955 (define_expand "atan<mode>2"
16956   [(use (match_operand:MODEF 0 "register_operand" ""))
16957    (use (match_operand:MODEF 1 "register_operand" ""))]
16958   "TARGET_USE_FANCY_MATH_387
16959    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16960        || TARGET_MIX_SSE_I387)
16961    && flag_unsafe_math_optimizations"
16962 {
16963   rtx op0 = gen_reg_rtx (XFmode);
16964
16965   rtx op2 = gen_reg_rtx (<MODE>mode);
16966   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16967
16968   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16969   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16970   DONE;
16971 })
16972
16973 (define_expand "asinxf2"
16974   [(set (match_dup 2)
16975         (mult:XF (match_operand:XF 1 "register_operand" "")
16976                  (match_dup 1)))
16977    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16978    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16979    (parallel [(set (match_operand:XF 0 "register_operand" "")
16980                    (unspec:XF [(match_dup 5) (match_dup 1)]
16981                               UNSPEC_FPATAN))
16982               (clobber (match_scratch:XF 6 ""))])]
16983   "TARGET_USE_FANCY_MATH_387
16984    && flag_unsafe_math_optimizations && !optimize_size"
16985 {
16986   int i;
16987
16988   for (i = 2; i < 6; i++)
16989     operands[i] = gen_reg_rtx (XFmode);
16990
16991   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16992 })
16993
16994 (define_expand "asin<mode>2"
16995   [(use (match_operand:MODEF 0 "register_operand" ""))
16996    (use (match_operand:MODEF 1 "general_operand" ""))]
16997  "TARGET_USE_FANCY_MATH_387
16998    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16999        || TARGET_MIX_SSE_I387)
17000    && flag_unsafe_math_optimizations && !optimize_size"
17001 {
17002   rtx op0 = gen_reg_rtx (XFmode);
17003   rtx op1 = gen_reg_rtx (XFmode);
17004
17005   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17006   emit_insn (gen_asinxf2 (op0, op1));
17007   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17008   DONE;
17009 })
17010
17011 (define_expand "acosxf2"
17012   [(set (match_dup 2)
17013         (mult:XF (match_operand:XF 1 "register_operand" "")
17014                  (match_dup 1)))
17015    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17016    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17017    (parallel [(set (match_operand:XF 0 "register_operand" "")
17018                    (unspec:XF [(match_dup 1) (match_dup 5)]
17019                               UNSPEC_FPATAN))
17020               (clobber (match_scratch:XF 6 ""))])]
17021   "TARGET_USE_FANCY_MATH_387
17022    && flag_unsafe_math_optimizations && !optimize_size"
17023 {
17024   int i;
17025
17026   for (i = 2; i < 6; i++)
17027     operands[i] = gen_reg_rtx (XFmode);
17028
17029   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17030 })
17031
17032 (define_expand "acos<mode>2"
17033   [(use (match_operand:MODEF 0 "register_operand" ""))
17034    (use (match_operand:MODEF 1 "general_operand" ""))]
17035  "TARGET_USE_FANCY_MATH_387
17036    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17037        || TARGET_MIX_SSE_I387)
17038    && flag_unsafe_math_optimizations && !optimize_size"
17039 {
17040   rtx op0 = gen_reg_rtx (XFmode);
17041   rtx op1 = gen_reg_rtx (XFmode);
17042
17043   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17044   emit_insn (gen_acosxf2 (op0, op1));
17045   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17046   DONE;
17047 })
17048
17049 (define_insn "fyl2xxf3_i387"
17050   [(set (match_operand:XF 0 "register_operand" "=f")
17051         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17052                     (match_operand:XF 2 "register_operand" "u")]
17053                    UNSPEC_FYL2X))
17054    (clobber (match_scratch:XF 3 "=2"))]
17055   "TARGET_USE_FANCY_MATH_387
17056    && flag_unsafe_math_optimizations"
17057   "fyl2x"
17058   [(set_attr "type" "fpspc")
17059    (set_attr "mode" "XF")])
17060
17061 (define_insn "fyl2x_extend<mode>xf3_i387"
17062   [(set (match_operand:XF 0 "register_operand" "=f")
17063         (unspec:XF [(float_extend:XF
17064                       (match_operand:MODEF 1 "register_operand" "0"))
17065                     (match_operand:XF 2 "register_operand" "u")]
17066                    UNSPEC_FYL2X))
17067    (clobber (match_scratch:XF 3 "=2"))]
17068   "TARGET_USE_FANCY_MATH_387
17069    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17070        || TARGET_MIX_SSE_I387)
17071    && flag_unsafe_math_optimizations"
17072   "fyl2x"
17073   [(set_attr "type" "fpspc")
17074    (set_attr "mode" "XF")])
17075
17076 (define_expand "logxf2"
17077   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17078                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17079                                (match_dup 2)] UNSPEC_FYL2X))
17080               (clobber (match_scratch:XF 3 ""))])]
17081   "TARGET_USE_FANCY_MATH_387
17082    && flag_unsafe_math_optimizations"
17083 {
17084   operands[2] = gen_reg_rtx (XFmode);
17085   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17086 })
17087
17088 (define_expand "log<mode>2"
17089   [(use (match_operand:MODEF 0 "register_operand" ""))
17090    (use (match_operand:MODEF 1 "register_operand" ""))]
17091   "TARGET_USE_FANCY_MATH_387
17092    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17093        || TARGET_MIX_SSE_I387)
17094    && flag_unsafe_math_optimizations"
17095 {
17096   rtx op0 = gen_reg_rtx (XFmode);
17097
17098   rtx op2 = gen_reg_rtx (XFmode);
17099   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17100
17101   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17102   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17103   DONE;
17104 })
17105
17106 (define_expand "log10xf2"
17107   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17108                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17109                                (match_dup 2)] UNSPEC_FYL2X))
17110               (clobber (match_scratch:XF 3 ""))])]
17111   "TARGET_USE_FANCY_MATH_387
17112    && flag_unsafe_math_optimizations"
17113 {
17114   operands[2] = gen_reg_rtx (XFmode);
17115   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17116 })
17117
17118 (define_expand "log10<mode>2"
17119   [(use (match_operand:MODEF 0 "register_operand" ""))
17120    (use (match_operand:MODEF 1 "register_operand" ""))]
17121   "TARGET_USE_FANCY_MATH_387
17122    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17123        || TARGET_MIX_SSE_I387)
17124    && flag_unsafe_math_optimizations"
17125 {
17126   rtx op0 = gen_reg_rtx (XFmode);
17127
17128   rtx op2 = gen_reg_rtx (XFmode);
17129   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17130
17131   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17132   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17133   DONE;
17134 })
17135
17136 (define_expand "log2xf2"
17137   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17138                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17139                                (match_dup 2)] UNSPEC_FYL2X))
17140               (clobber (match_scratch:XF 3 ""))])]
17141   "TARGET_USE_FANCY_MATH_387
17142    && flag_unsafe_math_optimizations"
17143 {
17144   operands[2] = gen_reg_rtx (XFmode);
17145   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17146 })
17147
17148 (define_expand "log2<mode>2"
17149   [(use (match_operand:MODEF 0 "register_operand" ""))
17150    (use (match_operand:MODEF 1 "register_operand" ""))]
17151   "TARGET_USE_FANCY_MATH_387
17152    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17153        || TARGET_MIX_SSE_I387)
17154    && flag_unsafe_math_optimizations"
17155 {
17156   rtx op0 = gen_reg_rtx (XFmode);
17157
17158   rtx op2 = gen_reg_rtx (XFmode);
17159   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17160
17161   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17162   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17163   DONE;
17164 })
17165
17166 (define_insn "fyl2xp1xf3_i387"
17167   [(set (match_operand:XF 0 "register_operand" "=f")
17168         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17169                     (match_operand:XF 2 "register_operand" "u")]
17170                    UNSPEC_FYL2XP1))
17171    (clobber (match_scratch:XF 3 "=2"))]
17172   "TARGET_USE_FANCY_MATH_387
17173    && flag_unsafe_math_optimizations"
17174   "fyl2xp1"
17175   [(set_attr "type" "fpspc")
17176    (set_attr "mode" "XF")])
17177
17178 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17179   [(set (match_operand:XF 0 "register_operand" "=f")
17180         (unspec:XF [(float_extend:XF
17181                       (match_operand:MODEF 1 "register_operand" "0"))
17182                     (match_operand:XF 2 "register_operand" "u")]
17183                    UNSPEC_FYL2XP1))
17184    (clobber (match_scratch:XF 3 "=2"))]
17185   "TARGET_USE_FANCY_MATH_387
17186    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17187        || TARGET_MIX_SSE_I387)
17188    && flag_unsafe_math_optimizations"
17189   "fyl2xp1"
17190   [(set_attr "type" "fpspc")
17191    (set_attr "mode" "XF")])
17192
17193 (define_expand "log1pxf2"
17194   [(use (match_operand:XF 0 "register_operand" ""))
17195    (use (match_operand:XF 1 "register_operand" ""))]
17196   "TARGET_USE_FANCY_MATH_387
17197    && flag_unsafe_math_optimizations && !optimize_size"
17198 {
17199   ix86_emit_i387_log1p (operands[0], operands[1]);
17200   DONE;
17201 })
17202
17203 (define_expand "log1p<mode>2"
17204   [(use (match_operand:MODEF 0 "register_operand" ""))
17205    (use (match_operand:MODEF 1 "register_operand" ""))]
17206   "TARGET_USE_FANCY_MATH_387
17207    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17208        || TARGET_MIX_SSE_I387)
17209    && flag_unsafe_math_optimizations && !optimize_size"
17210 {
17211   rtx op0 = gen_reg_rtx (XFmode);
17212
17213   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17214
17215   ix86_emit_i387_log1p (op0, operands[1]);
17216   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17217   DONE;
17218 })
17219
17220 (define_insn "fxtractxf3_i387"
17221   [(set (match_operand:XF 0 "register_operand" "=f")
17222         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17223                    UNSPEC_XTRACT_FRACT))
17224    (set (match_operand:XF 1 "register_operand" "=u")
17225         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17226   "TARGET_USE_FANCY_MATH_387
17227    && flag_unsafe_math_optimizations"
17228   "fxtract"
17229   [(set_attr "type" "fpspc")
17230    (set_attr "mode" "XF")])
17231
17232 (define_insn "fxtract_extend<mode>xf3_i387"
17233   [(set (match_operand:XF 0 "register_operand" "=f")
17234         (unspec:XF [(float_extend:XF
17235                       (match_operand:MODEF 2 "register_operand" "0"))]
17236                    UNSPEC_XTRACT_FRACT))
17237    (set (match_operand:XF 1 "register_operand" "=u")
17238         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17239   "TARGET_USE_FANCY_MATH_387
17240    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17241        || TARGET_MIX_SSE_I387)
17242    && flag_unsafe_math_optimizations"
17243   "fxtract"
17244   [(set_attr "type" "fpspc")
17245    (set_attr "mode" "XF")])
17246
17247 (define_expand "logbxf2"
17248   [(parallel [(set (match_dup 2)
17249                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17250                               UNSPEC_XTRACT_FRACT))
17251               (set (match_operand:XF 0 "register_operand" "")
17252                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17253   "TARGET_USE_FANCY_MATH_387
17254    && flag_unsafe_math_optimizations"
17255 {
17256   operands[2] = gen_reg_rtx (XFmode);
17257 })
17258
17259 (define_expand "logb<mode>2"
17260   [(use (match_operand:MODEF 0 "register_operand" ""))
17261    (use (match_operand:MODEF 1 "register_operand" ""))]
17262   "TARGET_USE_FANCY_MATH_387
17263    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17264        || TARGET_MIX_SSE_I387)
17265    && flag_unsafe_math_optimizations"
17266 {
17267   rtx op0 = gen_reg_rtx (XFmode);
17268   rtx op1 = gen_reg_rtx (XFmode);
17269
17270   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17271   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17272   DONE;
17273 })
17274
17275 (define_expand "ilogbxf2"
17276   [(use (match_operand:SI 0 "register_operand" ""))
17277    (use (match_operand:XF 1 "register_operand" ""))]
17278   "TARGET_USE_FANCY_MATH_387
17279    && flag_unsafe_math_optimizations && !optimize_size"
17280 {
17281   rtx op0 = gen_reg_rtx (XFmode);
17282   rtx op1 = gen_reg_rtx (XFmode);
17283
17284   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17285   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17286   DONE;
17287 })
17288
17289 (define_expand "ilogb<mode>2"
17290   [(use (match_operand:SI 0 "register_operand" ""))
17291    (use (match_operand:MODEF 1 "register_operand" ""))]
17292   "TARGET_USE_FANCY_MATH_387
17293    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17294        || TARGET_MIX_SSE_I387)
17295    && flag_unsafe_math_optimizations && !optimize_size"
17296 {
17297   rtx op0 = gen_reg_rtx (XFmode);
17298   rtx op1 = gen_reg_rtx (XFmode);
17299
17300   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17301   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17302   DONE;
17303 })
17304
17305 (define_insn "*f2xm1xf2_i387"
17306   [(set (match_operand:XF 0 "register_operand" "=f")
17307         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17308                    UNSPEC_F2XM1))]
17309   "TARGET_USE_FANCY_MATH_387
17310    && flag_unsafe_math_optimizations"
17311   "f2xm1"
17312   [(set_attr "type" "fpspc")
17313    (set_attr "mode" "XF")])
17314
17315 (define_insn "*fscalexf4_i387"
17316   [(set (match_operand:XF 0 "register_operand" "=f")
17317         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17318                     (match_operand:XF 3 "register_operand" "1")]
17319                    UNSPEC_FSCALE_FRACT))
17320    (set (match_operand:XF 1 "register_operand" "=u")
17321         (unspec:XF [(match_dup 2) (match_dup 3)]
17322                    UNSPEC_FSCALE_EXP))]
17323   "TARGET_USE_FANCY_MATH_387
17324    && flag_unsafe_math_optimizations"
17325   "fscale"
17326   [(set_attr "type" "fpspc")
17327    (set_attr "mode" "XF")])
17328
17329 (define_expand "expNcorexf3"
17330   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17331                                (match_operand:XF 2 "register_operand" "")))
17332    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17333    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17334    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17335    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17336    (parallel [(set (match_operand:XF 0 "register_operand" "")
17337                    (unspec:XF [(match_dup 8) (match_dup 4)]
17338                               UNSPEC_FSCALE_FRACT))
17339               (set (match_dup 9)
17340                    (unspec:XF [(match_dup 8) (match_dup 4)]
17341                               UNSPEC_FSCALE_EXP))])]
17342   "TARGET_USE_FANCY_MATH_387
17343    && flag_unsafe_math_optimizations && !optimize_size"
17344 {
17345   int i;
17346
17347   for (i = 3; i < 10; i++)
17348     operands[i] = gen_reg_rtx (XFmode);
17349
17350   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17351 })
17352
17353 (define_expand "expxf2"
17354   [(use (match_operand:XF 0 "register_operand" ""))
17355    (use (match_operand:XF 1 "register_operand" ""))]
17356   "TARGET_USE_FANCY_MATH_387
17357    && flag_unsafe_math_optimizations && !optimize_size"
17358 {
17359   rtx op2 = gen_reg_rtx (XFmode);
17360   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17361
17362   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17363   DONE;
17364 })
17365
17366 (define_expand "exp<mode>2"
17367   [(use (match_operand:MODEF 0 "register_operand" ""))
17368    (use (match_operand:MODEF 1 "general_operand" ""))]
17369  "TARGET_USE_FANCY_MATH_387
17370    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17371        || TARGET_MIX_SSE_I387)
17372    && flag_unsafe_math_optimizations && !optimize_size"
17373 {
17374   rtx op0 = gen_reg_rtx (XFmode);
17375   rtx op1 = gen_reg_rtx (XFmode);
17376
17377   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17378   emit_insn (gen_expxf2 (op0, op1));
17379   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17380   DONE;
17381 })
17382
17383 (define_expand "exp10xf2"
17384   [(use (match_operand:XF 0 "register_operand" ""))
17385    (use (match_operand:XF 1 "register_operand" ""))]
17386   "TARGET_USE_FANCY_MATH_387
17387    && flag_unsafe_math_optimizations && !optimize_size"
17388 {
17389   rtx op2 = gen_reg_rtx (XFmode);
17390   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17391
17392   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17393   DONE;
17394 })
17395
17396 (define_expand "exp10<mode>2"
17397   [(use (match_operand:MODEF 0 "register_operand" ""))
17398    (use (match_operand:MODEF 1 "general_operand" ""))]
17399  "TARGET_USE_FANCY_MATH_387
17400    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17401        || TARGET_MIX_SSE_I387)
17402    && flag_unsafe_math_optimizations && !optimize_size"
17403 {
17404   rtx op0 = gen_reg_rtx (XFmode);
17405   rtx op1 = gen_reg_rtx (XFmode);
17406
17407   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17408   emit_insn (gen_exp10xf2 (op0, op1));
17409   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17410   DONE;
17411 })
17412
17413 (define_expand "exp2xf2"
17414   [(use (match_operand:XF 0 "register_operand" ""))
17415    (use (match_operand:XF 1 "register_operand" ""))]
17416   "TARGET_USE_FANCY_MATH_387
17417    && flag_unsafe_math_optimizations && !optimize_size"
17418 {
17419   rtx op2 = gen_reg_rtx (XFmode);
17420   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17421
17422   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17423   DONE;
17424 })
17425
17426 (define_expand "exp2<mode>2"
17427   [(use (match_operand:MODEF 0 "register_operand" ""))
17428    (use (match_operand:MODEF 1 "general_operand" ""))]
17429  "TARGET_USE_FANCY_MATH_387
17430    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17431        || TARGET_MIX_SSE_I387)
17432    && flag_unsafe_math_optimizations && !optimize_size"
17433 {
17434   rtx op0 = gen_reg_rtx (XFmode);
17435   rtx op1 = gen_reg_rtx (XFmode);
17436
17437   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17438   emit_insn (gen_exp2xf2 (op0, op1));
17439   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17440   DONE;
17441 })
17442
17443 (define_expand "expm1xf2"
17444   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17445                                (match_dup 2)))
17446    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17447    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17448    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17449    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17450    (parallel [(set (match_dup 7)
17451                    (unspec:XF [(match_dup 6) (match_dup 4)]
17452                               UNSPEC_FSCALE_FRACT))
17453               (set (match_dup 8)
17454                    (unspec:XF [(match_dup 6) (match_dup 4)]
17455                               UNSPEC_FSCALE_EXP))])
17456    (parallel [(set (match_dup 10)
17457                    (unspec:XF [(match_dup 9) (match_dup 8)]
17458                               UNSPEC_FSCALE_FRACT))
17459               (set (match_dup 11)
17460                    (unspec:XF [(match_dup 9) (match_dup 8)]
17461                               UNSPEC_FSCALE_EXP))])
17462    (set (match_dup 12) (minus:XF (match_dup 10)
17463                                  (float_extend:XF (match_dup 13))))
17464    (set (match_operand:XF 0 "register_operand" "")
17465         (plus:XF (match_dup 12) (match_dup 7)))]
17466   "TARGET_USE_FANCY_MATH_387
17467    && flag_unsafe_math_optimizations && !optimize_size"
17468 {
17469   int i;
17470
17471   for (i = 2; i < 13; i++)
17472     operands[i] = gen_reg_rtx (XFmode);
17473
17474   operands[13]
17475     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17476
17477   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17478 })
17479
17480 (define_expand "expm1<mode>2"
17481   [(use (match_operand:MODEF 0 "register_operand" ""))
17482    (use (match_operand:MODEF 1 "general_operand" ""))]
17483  "TARGET_USE_FANCY_MATH_387
17484    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17485        || TARGET_MIX_SSE_I387)
17486    && flag_unsafe_math_optimizations && !optimize_size"
17487 {
17488   rtx op0 = gen_reg_rtx (XFmode);
17489   rtx op1 = gen_reg_rtx (XFmode);
17490
17491   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17492   emit_insn (gen_expm1xf2 (op0, op1));
17493   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17494   DONE;
17495 })
17496
17497 (define_expand "ldexpxf3"
17498   [(set (match_dup 3)
17499         (float:XF (match_operand:SI 2 "register_operand" "")))
17500    (parallel [(set (match_operand:XF 0 " register_operand" "")
17501                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17502                                (match_dup 3)]
17503                               UNSPEC_FSCALE_FRACT))
17504               (set (match_dup 4)
17505                    (unspec:XF [(match_dup 1) (match_dup 3)]
17506                               UNSPEC_FSCALE_EXP))])]
17507   "TARGET_USE_FANCY_MATH_387
17508    && flag_unsafe_math_optimizations && !optimize_size"
17509 {
17510   operands[3] = gen_reg_rtx (XFmode);
17511   operands[4] = gen_reg_rtx (XFmode);
17512 })
17513
17514 (define_expand "ldexp<mode>3"
17515   [(use (match_operand:MODEF 0 "register_operand" ""))
17516    (use (match_operand:MODEF 1 "general_operand" ""))
17517    (use (match_operand:SI 2 "register_operand" ""))]
17518  "TARGET_USE_FANCY_MATH_387
17519    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17520        || TARGET_MIX_SSE_I387)
17521    && flag_unsafe_math_optimizations && !optimize_size"
17522 {
17523   rtx op0 = gen_reg_rtx (XFmode);
17524   rtx op1 = gen_reg_rtx (XFmode);
17525
17526   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17527   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17528   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17529   DONE;
17530 })
17531
17532 (define_expand "scalbxf3"
17533   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17534                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17535                                (match_operand:XF 2 "register_operand" "")]
17536                               UNSPEC_FSCALE_FRACT))
17537               (set (match_dup 3)
17538                    (unspec:XF [(match_dup 1) (match_dup 2)]
17539                               UNSPEC_FSCALE_EXP))])]
17540   "TARGET_USE_FANCY_MATH_387
17541    && flag_unsafe_math_optimizations && !optimize_size"
17542 {
17543   operands[3] = gen_reg_rtx (XFmode);
17544 })
17545
17546 (define_expand "scalb<mode>3"
17547   [(use (match_operand:MODEF 0 "register_operand" ""))
17548    (use (match_operand:MODEF 1 "general_operand" ""))
17549    (use (match_operand:MODEF 2 "register_operand" ""))]
17550  "TARGET_USE_FANCY_MATH_387
17551    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17552        || TARGET_MIX_SSE_I387)
17553    && flag_unsafe_math_optimizations && !optimize_size"
17554 {
17555   rtx op0 = gen_reg_rtx (XFmode);
17556   rtx op1 = gen_reg_rtx (XFmode);
17557   rtx op2 = gen_reg_rtx (XFmode);
17558
17559   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17560   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17561   emit_insn (gen_scalbxf3 (op0, op1, op2));
17562   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17563   DONE;
17564 })
17565 \f
17566
17567 (define_insn "sse4_1_round<mode>2"
17568   [(set (match_operand:MODEF 0 "register_operand" "=x")
17569         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17570                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
17571                       UNSPEC_ROUND))]
17572   "TARGET_ROUND"
17573   "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17574   [(set_attr "type" "ssecvt")
17575    (set_attr "prefix_extra" "1")
17576    (set_attr "mode" "<MODE>")])
17577
17578 (define_insn "rintxf2"
17579   [(set (match_operand:XF 0 "register_operand" "=f")
17580         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17581                    UNSPEC_FRNDINT))]
17582   "TARGET_USE_FANCY_MATH_387
17583    && flag_unsafe_math_optimizations"
17584   "frndint"
17585   [(set_attr "type" "fpspc")
17586    (set_attr "mode" "XF")])
17587
17588 (define_expand "rint<mode>2"
17589   [(use (match_operand:MODEF 0 "register_operand" ""))
17590    (use (match_operand:MODEF 1 "register_operand" ""))]
17591   "(TARGET_USE_FANCY_MATH_387
17592     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17593         || TARGET_MIX_SSE_I387)
17594     && flag_unsafe_math_optimizations)
17595    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17596        && !flag_trapping_math
17597        && (TARGET_ROUND || !optimize_size))"
17598 {
17599   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17600       && !flag_trapping_math
17601       && (TARGET_ROUND || !optimize_size))
17602     {
17603       if (TARGET_ROUND)
17604         emit_insn (gen_sse4_1_round<mode>2
17605                    (operands[0], operands[1], GEN_INT (0x04)));
17606       else
17607         ix86_expand_rint (operand0, operand1);
17608     }
17609   else
17610     {
17611       rtx op0 = gen_reg_rtx (XFmode);
17612       rtx op1 = gen_reg_rtx (XFmode);
17613
17614       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17615       emit_insn (gen_rintxf2 (op0, op1));
17616
17617       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17618     }
17619   DONE;
17620 })
17621
17622 (define_expand "round<mode>2"
17623   [(match_operand:MODEF 0 "register_operand" "")
17624    (match_operand:MODEF 1 "nonimmediate_operand" "")]
17625   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17626    && !flag_trapping_math && !flag_rounding_math
17627    && !optimize_size"
17628 {
17629   if (TARGET_64BIT || (<MODE>mode != DFmode))
17630     ix86_expand_round (operand0, operand1);
17631   else
17632     ix86_expand_rounddf_32 (operand0, operand1);
17633   DONE;
17634 })
17635
17636 (define_insn_and_split "*fistdi2_1"
17637   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17638         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17639                    UNSPEC_FIST))]
17640   "TARGET_USE_FANCY_MATH_387
17641    && !(reload_completed || reload_in_progress)"
17642   "#"
17643   "&& 1"
17644   [(const_int 0)]
17645 {
17646   if (memory_operand (operands[0], VOIDmode))
17647     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17648   else
17649     {
17650       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17651       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17652                                          operands[2]));
17653     }
17654   DONE;
17655 }
17656   [(set_attr "type" "fpspc")
17657    (set_attr "mode" "DI")])
17658
17659 (define_insn "fistdi2"
17660   [(set (match_operand:DI 0 "memory_operand" "=m")
17661         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17662                    UNSPEC_FIST))
17663    (clobber (match_scratch:XF 2 "=&1f"))]
17664   "TARGET_USE_FANCY_MATH_387"
17665   "* return output_fix_trunc (insn, operands, 0);"
17666   [(set_attr "type" "fpspc")
17667    (set_attr "mode" "DI")])
17668
17669 (define_insn "fistdi2_with_temp"
17670   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17671         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17672                    UNSPEC_FIST))
17673    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17674    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17675   "TARGET_USE_FANCY_MATH_387"
17676   "#"
17677   [(set_attr "type" "fpspc")
17678    (set_attr "mode" "DI")])
17679
17680 (define_split
17681   [(set (match_operand:DI 0 "register_operand" "")
17682         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17683                    UNSPEC_FIST))
17684    (clobber (match_operand:DI 2 "memory_operand" ""))
17685    (clobber (match_scratch 3 ""))]
17686   "reload_completed"
17687   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17688               (clobber (match_dup 3))])
17689    (set (match_dup 0) (match_dup 2))]
17690   "")
17691
17692 (define_split
17693   [(set (match_operand:DI 0 "memory_operand" "")
17694         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17695                    UNSPEC_FIST))
17696    (clobber (match_operand:DI 2 "memory_operand" ""))
17697    (clobber (match_scratch 3 ""))]
17698   "reload_completed"
17699   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17700               (clobber (match_dup 3))])]
17701   "")
17702
17703 (define_insn_and_split "*fist<mode>2_1"
17704   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17705         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17706                            UNSPEC_FIST))]
17707   "TARGET_USE_FANCY_MATH_387
17708    && !(reload_completed || reload_in_progress)"
17709   "#"
17710   "&& 1"
17711   [(const_int 0)]
17712 {
17713   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17714   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17715                                         operands[2]));
17716   DONE;
17717 }
17718   [(set_attr "type" "fpspc")
17719    (set_attr "mode" "<MODE>")])
17720
17721 (define_insn "fist<mode>2"
17722   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17723         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17724                            UNSPEC_FIST))]
17725   "TARGET_USE_FANCY_MATH_387"
17726   "* return output_fix_trunc (insn, operands, 0);"
17727   [(set_attr "type" "fpspc")
17728    (set_attr "mode" "<MODE>")])
17729
17730 (define_insn "fist<mode>2_with_temp"
17731   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17732         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17733                            UNSPEC_FIST))
17734    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17735   "TARGET_USE_FANCY_MATH_387"
17736   "#"
17737   [(set_attr "type" "fpspc")
17738    (set_attr "mode" "<MODE>")])
17739
17740 (define_split
17741   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17742         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17743                            UNSPEC_FIST))
17744    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17745   "reload_completed"
17746   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17747    (set (match_dup 0) (match_dup 2))]
17748   "")
17749
17750 (define_split
17751   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17752         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17753                            UNSPEC_FIST))
17754    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17755   "reload_completed"
17756   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17757   "")
17758
17759 (define_expand "lrintxf<mode>2"
17760   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17761      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17762                       UNSPEC_FIST))]
17763   "TARGET_USE_FANCY_MATH_387"
17764   "")
17765
17766 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17767   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17768      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17769                         UNSPEC_FIX_NOTRUNC))]
17770   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17771    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17772   "")
17773
17774 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17775   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17776    (match_operand:MODEF 1 "register_operand" "")]
17777   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17778    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17779    && !flag_trapping_math && !flag_rounding_math
17780    && !optimize_size"
17781 {
17782   ix86_expand_lround (operand0, operand1);
17783   DONE;
17784 })
17785
17786 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17787 (define_insn_and_split "frndintxf2_floor"
17788   [(set (match_operand:XF 0 "register_operand" "")
17789         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17790          UNSPEC_FRNDINT_FLOOR))
17791    (clobber (reg:CC FLAGS_REG))]
17792   "TARGET_USE_FANCY_MATH_387
17793    && flag_unsafe_math_optimizations
17794    && !(reload_completed || reload_in_progress)"
17795   "#"
17796   "&& 1"
17797   [(const_int 0)]
17798 {
17799   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17800
17801   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17802   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17803
17804   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17805                                         operands[2], operands[3]));
17806   DONE;
17807 }
17808   [(set_attr "type" "frndint")
17809    (set_attr "i387_cw" "floor")
17810    (set_attr "mode" "XF")])
17811
17812 (define_insn "frndintxf2_floor_i387"
17813   [(set (match_operand:XF 0 "register_operand" "=f")
17814         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17815          UNSPEC_FRNDINT_FLOOR))
17816    (use (match_operand:HI 2 "memory_operand" "m"))
17817    (use (match_operand:HI 3 "memory_operand" "m"))]
17818   "TARGET_USE_FANCY_MATH_387
17819    && flag_unsafe_math_optimizations"
17820   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17821   [(set_attr "type" "frndint")
17822    (set_attr "i387_cw" "floor")
17823    (set_attr "mode" "XF")])
17824
17825 (define_expand "floorxf2"
17826   [(use (match_operand:XF 0 "register_operand" ""))
17827    (use (match_operand:XF 1 "register_operand" ""))]
17828   "TARGET_USE_FANCY_MATH_387
17829    && flag_unsafe_math_optimizations && !optimize_size"
17830 {
17831   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17832   DONE;
17833 })
17834
17835 (define_expand "floor<mode>2"
17836   [(use (match_operand:MODEF 0 "register_operand" ""))
17837    (use (match_operand:MODEF 1 "register_operand" ""))]
17838   "(TARGET_USE_FANCY_MATH_387
17839     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17840         || TARGET_MIX_SSE_I387)
17841     && flag_unsafe_math_optimizations && !optimize_size)
17842    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17843        && !flag_trapping_math
17844        && (TARGET_ROUND || !optimize_size))"
17845 {
17846   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17847       && !flag_trapping_math
17848       && (TARGET_ROUND || !optimize_size))
17849     {
17850       if (TARGET_ROUND)
17851         emit_insn (gen_sse4_1_round<mode>2
17852                    (operands[0], operands[1], GEN_INT (0x01)));
17853       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17854         ix86_expand_floorceil (operand0, operand1, true);
17855       else
17856         ix86_expand_floorceildf_32 (operand0, operand1, true);
17857     }
17858   else
17859     {
17860       rtx op0 = gen_reg_rtx (XFmode);
17861       rtx op1 = gen_reg_rtx (XFmode);
17862
17863       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17864       emit_insn (gen_frndintxf2_floor (op0, op1));
17865
17866       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17867     }
17868   DONE;
17869 })
17870
17871 (define_insn_and_split "*fist<mode>2_floor_1"
17872   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17873         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17874          UNSPEC_FIST_FLOOR))
17875    (clobber (reg:CC FLAGS_REG))]
17876   "TARGET_USE_FANCY_MATH_387
17877    && flag_unsafe_math_optimizations
17878    && !(reload_completed || reload_in_progress)"
17879   "#"
17880   "&& 1"
17881   [(const_int 0)]
17882 {
17883   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17884
17885   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17886   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17887   if (memory_operand (operands[0], VOIDmode))
17888     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17889                                       operands[2], operands[3]));
17890   else
17891     {
17892       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17893       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17894                                                   operands[2], operands[3],
17895                                                   operands[4]));
17896     }
17897   DONE;
17898 }
17899   [(set_attr "type" "fistp")
17900    (set_attr "i387_cw" "floor")
17901    (set_attr "mode" "<MODE>")])
17902
17903 (define_insn "fistdi2_floor"
17904   [(set (match_operand:DI 0 "memory_operand" "=m")
17905         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17906          UNSPEC_FIST_FLOOR))
17907    (use (match_operand:HI 2 "memory_operand" "m"))
17908    (use (match_operand:HI 3 "memory_operand" "m"))
17909    (clobber (match_scratch:XF 4 "=&1f"))]
17910   "TARGET_USE_FANCY_MATH_387
17911    && flag_unsafe_math_optimizations"
17912   "* return output_fix_trunc (insn, operands, 0);"
17913   [(set_attr "type" "fistp")
17914    (set_attr "i387_cw" "floor")
17915    (set_attr "mode" "DI")])
17916
17917 (define_insn "fistdi2_floor_with_temp"
17918   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17919         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17920          UNSPEC_FIST_FLOOR))
17921    (use (match_operand:HI 2 "memory_operand" "m,m"))
17922    (use (match_operand:HI 3 "memory_operand" "m,m"))
17923    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17924    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17925   "TARGET_USE_FANCY_MATH_387
17926    && flag_unsafe_math_optimizations"
17927   "#"
17928   [(set_attr "type" "fistp")
17929    (set_attr "i387_cw" "floor")
17930    (set_attr "mode" "DI")])
17931
17932 (define_split
17933   [(set (match_operand:DI 0 "register_operand" "")
17934         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17935          UNSPEC_FIST_FLOOR))
17936    (use (match_operand:HI 2 "memory_operand" ""))
17937    (use (match_operand:HI 3 "memory_operand" ""))
17938    (clobber (match_operand:DI 4 "memory_operand" ""))
17939    (clobber (match_scratch 5 ""))]
17940   "reload_completed"
17941   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17942               (use (match_dup 2))
17943               (use (match_dup 3))
17944               (clobber (match_dup 5))])
17945    (set (match_dup 0) (match_dup 4))]
17946   "")
17947
17948 (define_split
17949   [(set (match_operand:DI 0 "memory_operand" "")
17950         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17951          UNSPEC_FIST_FLOOR))
17952    (use (match_operand:HI 2 "memory_operand" ""))
17953    (use (match_operand:HI 3 "memory_operand" ""))
17954    (clobber (match_operand:DI 4 "memory_operand" ""))
17955    (clobber (match_scratch 5 ""))]
17956   "reload_completed"
17957   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17958               (use (match_dup 2))
17959               (use (match_dup 3))
17960               (clobber (match_dup 5))])]
17961   "")
17962
17963 (define_insn "fist<mode>2_floor"
17964   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17965         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17966          UNSPEC_FIST_FLOOR))
17967    (use (match_operand:HI 2 "memory_operand" "m"))
17968    (use (match_operand:HI 3 "memory_operand" "m"))]
17969   "TARGET_USE_FANCY_MATH_387
17970    && flag_unsafe_math_optimizations"
17971   "* return output_fix_trunc (insn, operands, 0);"
17972   [(set_attr "type" "fistp")
17973    (set_attr "i387_cw" "floor")
17974    (set_attr "mode" "<MODE>")])
17975
17976 (define_insn "fist<mode>2_floor_with_temp"
17977   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17978         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17979          UNSPEC_FIST_FLOOR))
17980    (use (match_operand:HI 2 "memory_operand" "m,m"))
17981    (use (match_operand:HI 3 "memory_operand" "m,m"))
17982    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17983   "TARGET_USE_FANCY_MATH_387
17984    && flag_unsafe_math_optimizations"
17985   "#"
17986   [(set_attr "type" "fistp")
17987    (set_attr "i387_cw" "floor")
17988    (set_attr "mode" "<MODE>")])
17989
17990 (define_split
17991   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17992         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17993          UNSPEC_FIST_FLOOR))
17994    (use (match_operand:HI 2 "memory_operand" ""))
17995    (use (match_operand:HI 3 "memory_operand" ""))
17996    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17997   "reload_completed"
17998   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17999                                   UNSPEC_FIST_FLOOR))
18000               (use (match_dup 2))
18001               (use (match_dup 3))])
18002    (set (match_dup 0) (match_dup 4))]
18003   "")
18004
18005 (define_split
18006   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18007         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18008          UNSPEC_FIST_FLOOR))
18009    (use (match_operand:HI 2 "memory_operand" ""))
18010    (use (match_operand:HI 3 "memory_operand" ""))
18011    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18012   "reload_completed"
18013   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18014                                   UNSPEC_FIST_FLOOR))
18015               (use (match_dup 2))
18016               (use (match_dup 3))])]
18017   "")
18018
18019 (define_expand "lfloorxf<mode>2"
18020   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18021                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18022                     UNSPEC_FIST_FLOOR))
18023               (clobber (reg:CC FLAGS_REG))])]
18024   "TARGET_USE_FANCY_MATH_387
18025    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18026    && flag_unsafe_math_optimizations"
18027   "")
18028
18029 (define_expand "lfloor<mode>di2"
18030   [(match_operand:DI 0 "nonimmediate_operand" "")
18031    (match_operand:MODEF 1 "register_operand" "")]
18032   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18033    && !flag_trapping_math
18034    && !optimize_size"
18035 {
18036   ix86_expand_lfloorceil (operand0, operand1, true);
18037   DONE;
18038 })
18039
18040 (define_expand "lfloor<mode>si2"
18041   [(match_operand:SI 0 "nonimmediate_operand" "")
18042    (match_operand:MODEF 1 "register_operand" "")]
18043   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18044    && !flag_trapping_math
18045    && (!optimize_size || !TARGET_64BIT)"
18046 {
18047   ix86_expand_lfloorceil (operand0, operand1, true);
18048   DONE;
18049 })
18050
18051 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18052 (define_insn_and_split "frndintxf2_ceil"
18053   [(set (match_operand:XF 0 "register_operand" "")
18054         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18055          UNSPEC_FRNDINT_CEIL))
18056    (clobber (reg:CC FLAGS_REG))]
18057   "TARGET_USE_FANCY_MATH_387
18058    && flag_unsafe_math_optimizations
18059    && !(reload_completed || reload_in_progress)"
18060   "#"
18061   "&& 1"
18062   [(const_int 0)]
18063 {
18064   ix86_optimize_mode_switching[I387_CEIL] = 1;
18065
18066   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18067   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18068
18069   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18070                                        operands[2], operands[3]));
18071   DONE;
18072 }
18073   [(set_attr "type" "frndint")
18074    (set_attr "i387_cw" "ceil")
18075    (set_attr "mode" "XF")])
18076
18077 (define_insn "frndintxf2_ceil_i387"
18078   [(set (match_operand:XF 0 "register_operand" "=f")
18079         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18080          UNSPEC_FRNDINT_CEIL))
18081    (use (match_operand:HI 2 "memory_operand" "m"))
18082    (use (match_operand:HI 3 "memory_operand" "m"))]
18083   "TARGET_USE_FANCY_MATH_387
18084    && flag_unsafe_math_optimizations"
18085   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18086   [(set_attr "type" "frndint")
18087    (set_attr "i387_cw" "ceil")
18088    (set_attr "mode" "XF")])
18089
18090 (define_expand "ceilxf2"
18091   [(use (match_operand:XF 0 "register_operand" ""))
18092    (use (match_operand:XF 1 "register_operand" ""))]
18093   "TARGET_USE_FANCY_MATH_387
18094    && flag_unsafe_math_optimizations && !optimize_size"
18095 {
18096   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18097   DONE;
18098 })
18099
18100 (define_expand "ceil<mode>2"
18101   [(use (match_operand:MODEF 0 "register_operand" ""))
18102    (use (match_operand:MODEF 1 "register_operand" ""))]
18103   "(TARGET_USE_FANCY_MATH_387
18104     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18105         || TARGET_MIX_SSE_I387)
18106     && flag_unsafe_math_optimizations && !optimize_size)
18107    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18108        && !flag_trapping_math
18109        && (TARGET_ROUND || !optimize_size))"
18110 {
18111   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18112       && !flag_trapping_math
18113       && (TARGET_ROUND || !optimize_size))
18114     {
18115       if (TARGET_ROUND)
18116         emit_insn (gen_sse4_1_round<mode>2
18117                    (operands[0], operands[1], GEN_INT (0x02)));
18118       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18119         ix86_expand_floorceil (operand0, operand1, false);
18120       else
18121         ix86_expand_floorceildf_32 (operand0, operand1, false);
18122     }
18123   else
18124     {
18125       rtx op0 = gen_reg_rtx (XFmode);
18126       rtx op1 = gen_reg_rtx (XFmode);
18127
18128       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18129       emit_insn (gen_frndintxf2_ceil (op0, op1));
18130
18131       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18132     }
18133   DONE;
18134 })
18135
18136 (define_insn_and_split "*fist<mode>2_ceil_1"
18137   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18138         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18139          UNSPEC_FIST_CEIL))
18140    (clobber (reg:CC FLAGS_REG))]
18141   "TARGET_USE_FANCY_MATH_387
18142    && flag_unsafe_math_optimizations
18143    && !(reload_completed || reload_in_progress)"
18144   "#"
18145   "&& 1"
18146   [(const_int 0)]
18147 {
18148   ix86_optimize_mode_switching[I387_CEIL] = 1;
18149
18150   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18151   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18152   if (memory_operand (operands[0], VOIDmode))
18153     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18154                                      operands[2], operands[3]));
18155   else
18156     {
18157       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18158       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18159                                                  operands[2], operands[3],
18160                                                  operands[4]));
18161     }
18162   DONE;
18163 }
18164   [(set_attr "type" "fistp")
18165    (set_attr "i387_cw" "ceil")
18166    (set_attr "mode" "<MODE>")])
18167
18168 (define_insn "fistdi2_ceil"
18169   [(set (match_operand:DI 0 "memory_operand" "=m")
18170         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18171          UNSPEC_FIST_CEIL))
18172    (use (match_operand:HI 2 "memory_operand" "m"))
18173    (use (match_operand:HI 3 "memory_operand" "m"))
18174    (clobber (match_scratch:XF 4 "=&1f"))]
18175   "TARGET_USE_FANCY_MATH_387
18176    && flag_unsafe_math_optimizations"
18177   "* return output_fix_trunc (insn, operands, 0);"
18178   [(set_attr "type" "fistp")
18179    (set_attr "i387_cw" "ceil")
18180    (set_attr "mode" "DI")])
18181
18182 (define_insn "fistdi2_ceil_with_temp"
18183   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18184         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18185          UNSPEC_FIST_CEIL))
18186    (use (match_operand:HI 2 "memory_operand" "m,m"))
18187    (use (match_operand:HI 3 "memory_operand" "m,m"))
18188    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
18189    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18190   "TARGET_USE_FANCY_MATH_387
18191    && flag_unsafe_math_optimizations"
18192   "#"
18193   [(set_attr "type" "fistp")
18194    (set_attr "i387_cw" "ceil")
18195    (set_attr "mode" "DI")])
18196
18197 (define_split
18198   [(set (match_operand:DI 0 "register_operand" "")
18199         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18200          UNSPEC_FIST_CEIL))
18201    (use (match_operand:HI 2 "memory_operand" ""))
18202    (use (match_operand:HI 3 "memory_operand" ""))
18203    (clobber (match_operand:DI 4 "memory_operand" ""))
18204    (clobber (match_scratch 5 ""))]
18205   "reload_completed"
18206   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18207               (use (match_dup 2))
18208               (use (match_dup 3))
18209               (clobber (match_dup 5))])
18210    (set (match_dup 0) (match_dup 4))]
18211   "")
18212
18213 (define_split
18214   [(set (match_operand:DI 0 "memory_operand" "")
18215         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18216          UNSPEC_FIST_CEIL))
18217    (use (match_operand:HI 2 "memory_operand" ""))
18218    (use (match_operand:HI 3 "memory_operand" ""))
18219    (clobber (match_operand:DI 4 "memory_operand" ""))
18220    (clobber (match_scratch 5 ""))]
18221   "reload_completed"
18222   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18223               (use (match_dup 2))
18224               (use (match_dup 3))
18225               (clobber (match_dup 5))])]
18226   "")
18227
18228 (define_insn "fist<mode>2_ceil"
18229   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18230         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18231          UNSPEC_FIST_CEIL))
18232    (use (match_operand:HI 2 "memory_operand" "m"))
18233    (use (match_operand:HI 3 "memory_operand" "m"))]
18234   "TARGET_USE_FANCY_MATH_387
18235    && flag_unsafe_math_optimizations"
18236   "* return output_fix_trunc (insn, operands, 0);"
18237   [(set_attr "type" "fistp")
18238    (set_attr "i387_cw" "ceil")
18239    (set_attr "mode" "<MODE>")])
18240
18241 (define_insn "fist<mode>2_ceil_with_temp"
18242   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18243         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18244          UNSPEC_FIST_CEIL))
18245    (use (match_operand:HI 2 "memory_operand" "m,m"))
18246    (use (match_operand:HI 3 "memory_operand" "m,m"))
18247    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18248   "TARGET_USE_FANCY_MATH_387
18249    && flag_unsafe_math_optimizations"
18250   "#"
18251   [(set_attr "type" "fistp")
18252    (set_attr "i387_cw" "ceil")
18253    (set_attr "mode" "<MODE>")])
18254
18255 (define_split
18256   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18257         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18258          UNSPEC_FIST_CEIL))
18259    (use (match_operand:HI 2 "memory_operand" ""))
18260    (use (match_operand:HI 3 "memory_operand" ""))
18261    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18262   "reload_completed"
18263   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18264                                   UNSPEC_FIST_CEIL))
18265               (use (match_dup 2))
18266               (use (match_dup 3))])
18267    (set (match_dup 0) (match_dup 4))]
18268   "")
18269
18270 (define_split
18271   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18272         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18273          UNSPEC_FIST_CEIL))
18274    (use (match_operand:HI 2 "memory_operand" ""))
18275    (use (match_operand:HI 3 "memory_operand" ""))
18276    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18277   "reload_completed"
18278   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18279                                   UNSPEC_FIST_CEIL))
18280               (use (match_dup 2))
18281               (use (match_dup 3))])]
18282   "")
18283
18284 (define_expand "lceilxf<mode>2"
18285   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18286                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18287                     UNSPEC_FIST_CEIL))
18288               (clobber (reg:CC FLAGS_REG))])]
18289   "TARGET_USE_FANCY_MATH_387
18290    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18291    && flag_unsafe_math_optimizations"
18292   "")
18293
18294 (define_expand "lceil<mode>di2"
18295   [(match_operand:DI 0 "nonimmediate_operand" "")
18296    (match_operand:MODEF 1 "register_operand" "")]
18297   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18298    && !flag_trapping_math"
18299 {
18300   ix86_expand_lfloorceil (operand0, operand1, false);
18301   DONE;
18302 })
18303
18304 (define_expand "lceil<mode>si2"
18305   [(match_operand:SI 0 "nonimmediate_operand" "")
18306    (match_operand:MODEF 1 "register_operand" "")]
18307   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18308    && !flag_trapping_math"
18309 {
18310   ix86_expand_lfloorceil (operand0, operand1, false);
18311   DONE;
18312 })
18313
18314 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18315 (define_insn_and_split "frndintxf2_trunc"
18316   [(set (match_operand:XF 0 "register_operand" "")
18317         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18318          UNSPEC_FRNDINT_TRUNC))
18319    (clobber (reg:CC FLAGS_REG))]
18320   "TARGET_USE_FANCY_MATH_387
18321    && flag_unsafe_math_optimizations
18322    && !(reload_completed || reload_in_progress)"
18323   "#"
18324   "&& 1"
18325   [(const_int 0)]
18326 {
18327   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18328
18329   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18330   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18331
18332   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18333                                         operands[2], operands[3]));
18334   DONE;
18335 }
18336   [(set_attr "type" "frndint")
18337    (set_attr "i387_cw" "trunc")
18338    (set_attr "mode" "XF")])
18339
18340 (define_insn "frndintxf2_trunc_i387"
18341   [(set (match_operand:XF 0 "register_operand" "=f")
18342         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18343          UNSPEC_FRNDINT_TRUNC))
18344    (use (match_operand:HI 2 "memory_operand" "m"))
18345    (use (match_operand:HI 3 "memory_operand" "m"))]
18346   "TARGET_USE_FANCY_MATH_387
18347    && flag_unsafe_math_optimizations"
18348   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18349   [(set_attr "type" "frndint")
18350    (set_attr "i387_cw" "trunc")
18351    (set_attr "mode" "XF")])
18352
18353 (define_expand "btruncxf2"
18354   [(use (match_operand:XF 0 "register_operand" ""))
18355    (use (match_operand:XF 1 "register_operand" ""))]
18356   "TARGET_USE_FANCY_MATH_387
18357    && flag_unsafe_math_optimizations && !optimize_size"
18358 {
18359   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18360   DONE;
18361 })
18362
18363 (define_expand "btrunc<mode>2"
18364   [(use (match_operand:MODEF 0 "register_operand" ""))
18365    (use (match_operand:MODEF 1 "register_operand" ""))]
18366   "(TARGET_USE_FANCY_MATH_387
18367     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18368         || TARGET_MIX_SSE_I387)
18369     && flag_unsafe_math_optimizations && !optimize_size)
18370    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18371        && !flag_trapping_math
18372        && (TARGET_ROUND || !optimize_size))"
18373 {
18374   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18375       && !flag_trapping_math
18376       && (TARGET_ROUND || !optimize_size))
18377     {
18378       if (TARGET_ROUND)
18379         emit_insn (gen_sse4_1_round<mode>2
18380                    (operands[0], operands[1], GEN_INT (0x03)));
18381       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18382         ix86_expand_trunc (operand0, operand1);
18383       else
18384         ix86_expand_truncdf_32 (operand0, operand1);
18385     }
18386   else
18387     {
18388       rtx op0 = gen_reg_rtx (XFmode);
18389       rtx op1 = gen_reg_rtx (XFmode);
18390
18391       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18392       emit_insn (gen_frndintxf2_trunc (op0, op1));
18393
18394       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18395     }
18396   DONE;
18397 })
18398
18399 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18400 (define_insn_and_split "frndintxf2_mask_pm"
18401   [(set (match_operand:XF 0 "register_operand" "")
18402         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18403          UNSPEC_FRNDINT_MASK_PM))
18404    (clobber (reg:CC FLAGS_REG))]
18405   "TARGET_USE_FANCY_MATH_387
18406    && flag_unsafe_math_optimizations
18407    && !(reload_completed || reload_in_progress)"
18408   "#"
18409   "&& 1"
18410   [(const_int 0)]
18411 {
18412   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18413
18414   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18415   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18416
18417   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18418                                           operands[2], operands[3]));
18419   DONE;
18420 }
18421   [(set_attr "type" "frndint")
18422    (set_attr "i387_cw" "mask_pm")
18423    (set_attr "mode" "XF")])
18424
18425 (define_insn "frndintxf2_mask_pm_i387"
18426   [(set (match_operand:XF 0 "register_operand" "=f")
18427         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18428          UNSPEC_FRNDINT_MASK_PM))
18429    (use (match_operand:HI 2 "memory_operand" "m"))
18430    (use (match_operand:HI 3 "memory_operand" "m"))]
18431   "TARGET_USE_FANCY_MATH_387
18432    && flag_unsafe_math_optimizations"
18433   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18434   [(set_attr "type" "frndint")
18435    (set_attr "i387_cw" "mask_pm")
18436    (set_attr "mode" "XF")])
18437
18438 (define_expand "nearbyintxf2"
18439   [(use (match_operand:XF 0 "register_operand" ""))
18440    (use (match_operand:XF 1 "register_operand" ""))]
18441   "TARGET_USE_FANCY_MATH_387
18442    && flag_unsafe_math_optimizations"
18443 {
18444   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18445
18446   DONE;
18447 })
18448
18449 (define_expand "nearbyint<mode>2"
18450   [(use (match_operand:MODEF 0 "register_operand" ""))
18451    (use (match_operand:MODEF 1 "register_operand" ""))]
18452   "TARGET_USE_FANCY_MATH_387
18453    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18454        || TARGET_MIX_SSE_I387)
18455    && flag_unsafe_math_optimizations"
18456 {
18457   rtx op0 = gen_reg_rtx (XFmode);
18458   rtx op1 = gen_reg_rtx (XFmode);
18459
18460   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18461   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18462
18463   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18464   DONE;
18465 })
18466
18467 (define_insn "fxam<mode>2_i387"
18468   [(set (match_operand:HI 0 "register_operand" "=a")
18469         (unspec:HI
18470           [(match_operand:X87MODEF 1 "register_operand" "f")]
18471           UNSPEC_FXAM))]
18472   "TARGET_USE_FANCY_MATH_387"
18473   "fxam\n\tfnstsw\t%0"
18474   [(set_attr "type" "multi")
18475    (set_attr "unit" "i387")
18476    (set_attr "mode" "<MODE>")])
18477
18478 (define_expand "isinf<mode>2"
18479   [(use (match_operand:SI 0 "register_operand" ""))
18480    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18481   "TARGET_USE_FANCY_MATH_387
18482    && TARGET_C99_FUNCTIONS
18483    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18484 {
18485   rtx mask = GEN_INT (0x45);
18486   rtx val = GEN_INT (0x05);
18487
18488   rtx cond;
18489
18490   rtx scratch = gen_reg_rtx (HImode);
18491   rtx res = gen_reg_rtx (QImode);
18492
18493   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18494   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18495   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18496   cond = gen_rtx_fmt_ee (EQ, QImode,
18497                          gen_rtx_REG (CCmode, FLAGS_REG),
18498                          const0_rtx);
18499   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18500   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18501   DONE;
18502 })
18503
18504 (define_expand "signbit<mode>2"
18505   [(use (match_operand:SI 0 "register_operand" ""))
18506    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18507   "TARGET_USE_FANCY_MATH_387
18508    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18509 {
18510   rtx mask = GEN_INT (0x0200);
18511
18512   rtx scratch = gen_reg_rtx (HImode);
18513
18514   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18515   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18516   DONE;
18517 })
18518 \f
18519 ;; Block operation instructions
18520
18521 (define_expand "movmemsi"
18522   [(use (match_operand:BLK 0 "memory_operand" ""))
18523    (use (match_operand:BLK 1 "memory_operand" ""))
18524    (use (match_operand:SI 2 "nonmemory_operand" ""))
18525    (use (match_operand:SI 3 "const_int_operand" ""))
18526    (use (match_operand:SI 4 "const_int_operand" ""))
18527    (use (match_operand:SI 5 "const_int_operand" ""))]
18528   ""
18529 {
18530  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18531                          operands[4], operands[5]))
18532    DONE;
18533  else
18534    FAIL;
18535 })
18536
18537 (define_expand "movmemdi"
18538   [(use (match_operand:BLK 0 "memory_operand" ""))
18539    (use (match_operand:BLK 1 "memory_operand" ""))
18540    (use (match_operand:DI 2 "nonmemory_operand" ""))
18541    (use (match_operand:DI 3 "const_int_operand" ""))
18542    (use (match_operand:SI 4 "const_int_operand" ""))
18543    (use (match_operand:SI 5 "const_int_operand" ""))]
18544   "TARGET_64BIT"
18545 {
18546  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18547                          operands[4], operands[5]))
18548    DONE;
18549  else
18550    FAIL;
18551 })
18552
18553 ;; Most CPUs don't like single string operations
18554 ;; Handle this case here to simplify previous expander.
18555
18556 (define_expand "strmov"
18557   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18558    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18559    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18560               (clobber (reg:CC FLAGS_REG))])
18561    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18562               (clobber (reg:CC FLAGS_REG))])]
18563   ""
18564 {
18565   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18566
18567   /* If .md ever supports :P for Pmode, these can be directly
18568      in the pattern above.  */
18569   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18570   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18571
18572   /* Can't use this if the user has appropriated esi or edi.  */
18573   if ((TARGET_SINGLE_STRINGOP || optimize_size)
18574       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18575     {
18576       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18577                                       operands[2], operands[3],
18578                                       operands[5], operands[6]));
18579       DONE;
18580     }
18581
18582   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18583 })
18584
18585 (define_expand "strmov_singleop"
18586   [(parallel [(set (match_operand 1 "memory_operand" "")
18587                    (match_operand 3 "memory_operand" ""))
18588               (set (match_operand 0 "register_operand" "")
18589                    (match_operand 4 "" ""))
18590               (set (match_operand 2 "register_operand" "")
18591                    (match_operand 5 "" ""))])]
18592   "TARGET_SINGLE_STRINGOP || optimize_size"
18593   "")
18594
18595 (define_insn "*strmovdi_rex_1"
18596   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18597         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18598    (set (match_operand:DI 0 "register_operand" "=D")
18599         (plus:DI (match_dup 2)
18600                  (const_int 8)))
18601    (set (match_operand:DI 1 "register_operand" "=S")
18602         (plus:DI (match_dup 3)
18603                  (const_int 8)))]
18604   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18605   "movsq"
18606   [(set_attr "type" "str")
18607    (set_attr "mode" "DI")
18608    (set_attr "memory" "both")])
18609
18610 (define_insn "*strmovsi_1"
18611   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18612         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18613    (set (match_operand:SI 0 "register_operand" "=D")
18614         (plus:SI (match_dup 2)
18615                  (const_int 4)))
18616    (set (match_operand:SI 1 "register_operand" "=S")
18617         (plus:SI (match_dup 3)
18618                  (const_int 4)))]
18619   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18620   "{movsl|movsd}"
18621   [(set_attr "type" "str")
18622    (set_attr "mode" "SI")
18623    (set_attr "memory" "both")])
18624
18625 (define_insn "*strmovsi_rex_1"
18626   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18627         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18628    (set (match_operand:DI 0 "register_operand" "=D")
18629         (plus:DI (match_dup 2)
18630                  (const_int 4)))
18631    (set (match_operand:DI 1 "register_operand" "=S")
18632         (plus:DI (match_dup 3)
18633                  (const_int 4)))]
18634   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18635   "{movsl|movsd}"
18636   [(set_attr "type" "str")
18637    (set_attr "mode" "SI")
18638    (set_attr "memory" "both")])
18639
18640 (define_insn "*strmovhi_1"
18641   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18642         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18643    (set (match_operand:SI 0 "register_operand" "=D")
18644         (plus:SI (match_dup 2)
18645                  (const_int 2)))
18646    (set (match_operand:SI 1 "register_operand" "=S")
18647         (plus:SI (match_dup 3)
18648                  (const_int 2)))]
18649   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18650   "movsw"
18651   [(set_attr "type" "str")
18652    (set_attr "memory" "both")
18653    (set_attr "mode" "HI")])
18654
18655 (define_insn "*strmovhi_rex_1"
18656   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18657         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18658    (set (match_operand:DI 0 "register_operand" "=D")
18659         (plus:DI (match_dup 2)
18660                  (const_int 2)))
18661    (set (match_operand:DI 1 "register_operand" "=S")
18662         (plus:DI (match_dup 3)
18663                  (const_int 2)))]
18664   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18665   "movsw"
18666   [(set_attr "type" "str")
18667    (set_attr "memory" "both")
18668    (set_attr "mode" "HI")])
18669
18670 (define_insn "*strmovqi_1"
18671   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18672         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18673    (set (match_operand:SI 0 "register_operand" "=D")
18674         (plus:SI (match_dup 2)
18675                  (const_int 1)))
18676    (set (match_operand:SI 1 "register_operand" "=S")
18677         (plus:SI (match_dup 3)
18678                  (const_int 1)))]
18679   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18680   "movsb"
18681   [(set_attr "type" "str")
18682    (set_attr "memory" "both")
18683    (set_attr "mode" "QI")])
18684
18685 (define_insn "*strmovqi_rex_1"
18686   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18687         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18688    (set (match_operand:DI 0 "register_operand" "=D")
18689         (plus:DI (match_dup 2)
18690                  (const_int 1)))
18691    (set (match_operand:DI 1 "register_operand" "=S")
18692         (plus:DI (match_dup 3)
18693                  (const_int 1)))]
18694   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18695   "movsb"
18696   [(set_attr "type" "str")
18697    (set_attr "memory" "both")
18698    (set_attr "mode" "QI")])
18699
18700 (define_expand "rep_mov"
18701   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18702               (set (match_operand 0 "register_operand" "")
18703                    (match_operand 5 "" ""))
18704               (set (match_operand 2 "register_operand" "")
18705                    (match_operand 6 "" ""))
18706               (set (match_operand 1 "memory_operand" "")
18707                    (match_operand 3 "memory_operand" ""))
18708               (use (match_dup 4))])]
18709   ""
18710   "")
18711
18712 (define_insn "*rep_movdi_rex64"
18713   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18714    (set (match_operand:DI 0 "register_operand" "=D")
18715         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18716                             (const_int 3))
18717                  (match_operand:DI 3 "register_operand" "0")))
18718    (set (match_operand:DI 1 "register_operand" "=S")
18719         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18720                  (match_operand:DI 4 "register_operand" "1")))
18721    (set (mem:BLK (match_dup 3))
18722         (mem:BLK (match_dup 4)))
18723    (use (match_dup 5))]
18724   "TARGET_64BIT"
18725   "rep movsq"
18726   [(set_attr "type" "str")
18727    (set_attr "prefix_rep" "1")
18728    (set_attr "memory" "both")
18729    (set_attr "mode" "DI")])
18730
18731 (define_insn "*rep_movsi"
18732   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18733    (set (match_operand:SI 0 "register_operand" "=D")
18734         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18735                             (const_int 2))
18736                  (match_operand:SI 3 "register_operand" "0")))
18737    (set (match_operand:SI 1 "register_operand" "=S")
18738         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18739                  (match_operand:SI 4 "register_operand" "1")))
18740    (set (mem:BLK (match_dup 3))
18741         (mem:BLK (match_dup 4)))
18742    (use (match_dup 5))]
18743   "!TARGET_64BIT"
18744   "rep movs{l|d}"
18745   [(set_attr "type" "str")
18746    (set_attr "prefix_rep" "1")
18747    (set_attr "memory" "both")
18748    (set_attr "mode" "SI")])
18749
18750 (define_insn "*rep_movsi_rex64"
18751   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18752    (set (match_operand:DI 0 "register_operand" "=D")
18753         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18754                             (const_int 2))
18755                  (match_operand:DI 3 "register_operand" "0")))
18756    (set (match_operand:DI 1 "register_operand" "=S")
18757         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18758                  (match_operand:DI 4 "register_operand" "1")))
18759    (set (mem:BLK (match_dup 3))
18760         (mem:BLK (match_dup 4)))
18761    (use (match_dup 5))]
18762   "TARGET_64BIT"
18763   "rep movs{l|d}"
18764   [(set_attr "type" "str")
18765    (set_attr "prefix_rep" "1")
18766    (set_attr "memory" "both")
18767    (set_attr "mode" "SI")])
18768
18769 (define_insn "*rep_movqi"
18770   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18771    (set (match_operand:SI 0 "register_operand" "=D")
18772         (plus:SI (match_operand:SI 3 "register_operand" "0")
18773                  (match_operand:SI 5 "register_operand" "2")))
18774    (set (match_operand:SI 1 "register_operand" "=S")
18775         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18776    (set (mem:BLK (match_dup 3))
18777         (mem:BLK (match_dup 4)))
18778    (use (match_dup 5))]
18779   "!TARGET_64BIT"
18780   "rep movsb"
18781   [(set_attr "type" "str")
18782    (set_attr "prefix_rep" "1")
18783    (set_attr "memory" "both")
18784    (set_attr "mode" "SI")])
18785
18786 (define_insn "*rep_movqi_rex64"
18787   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18788    (set (match_operand:DI 0 "register_operand" "=D")
18789         (plus:DI (match_operand:DI 3 "register_operand" "0")
18790                  (match_operand:DI 5 "register_operand" "2")))
18791    (set (match_operand:DI 1 "register_operand" "=S")
18792         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18793    (set (mem:BLK (match_dup 3))
18794         (mem:BLK (match_dup 4)))
18795    (use (match_dup 5))]
18796   "TARGET_64BIT"
18797   "rep movsb"
18798   [(set_attr "type" "str")
18799    (set_attr "prefix_rep" "1")
18800    (set_attr "memory" "both")
18801    (set_attr "mode" "SI")])
18802
18803 (define_expand "setmemsi"
18804    [(use (match_operand:BLK 0 "memory_operand" ""))
18805     (use (match_operand:SI 1 "nonmemory_operand" ""))
18806     (use (match_operand 2 "const_int_operand" ""))
18807     (use (match_operand 3 "const_int_operand" ""))
18808     (use (match_operand:SI 4 "const_int_operand" ""))
18809     (use (match_operand:SI 5 "const_int_operand" ""))]
18810   ""
18811 {
18812  if (ix86_expand_setmem (operands[0], operands[1],
18813                          operands[2], operands[3],
18814                          operands[4], operands[5]))
18815    DONE;
18816  else
18817    FAIL;
18818 })
18819
18820 (define_expand "setmemdi"
18821    [(use (match_operand:BLK 0 "memory_operand" ""))
18822     (use (match_operand:DI 1 "nonmemory_operand" ""))
18823     (use (match_operand 2 "const_int_operand" ""))
18824     (use (match_operand 3 "const_int_operand" ""))
18825     (use (match_operand 4 "const_int_operand" ""))
18826     (use (match_operand 5 "const_int_operand" ""))]
18827   "TARGET_64BIT"
18828 {
18829  if (ix86_expand_setmem (operands[0], operands[1],
18830                          operands[2], operands[3],
18831                          operands[4], operands[5]))
18832    DONE;
18833  else
18834    FAIL;
18835 })
18836
18837 ;; Most CPUs don't like single string operations
18838 ;; Handle this case here to simplify previous expander.
18839
18840 (define_expand "strset"
18841   [(set (match_operand 1 "memory_operand" "")
18842         (match_operand 2 "register_operand" ""))
18843    (parallel [(set (match_operand 0 "register_operand" "")
18844                    (match_dup 3))
18845               (clobber (reg:CC FLAGS_REG))])]
18846   ""
18847 {
18848   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18849     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18850
18851   /* If .md ever supports :P for Pmode, this can be directly
18852      in the pattern above.  */
18853   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18854                               GEN_INT (GET_MODE_SIZE (GET_MODE
18855                                                       (operands[2]))));
18856   if (TARGET_SINGLE_STRINGOP || optimize_size)
18857     {
18858       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18859                                       operands[3]));
18860       DONE;
18861     }
18862 })
18863
18864 (define_expand "strset_singleop"
18865   [(parallel [(set (match_operand 1 "memory_operand" "")
18866                    (match_operand 2 "register_operand" ""))
18867               (set (match_operand 0 "register_operand" "")
18868                    (match_operand 3 "" ""))])]
18869   "TARGET_SINGLE_STRINGOP || optimize_size"
18870   "")
18871
18872 (define_insn "*strsetdi_rex_1"
18873   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18874         (match_operand:DI 2 "register_operand" "a"))
18875    (set (match_operand:DI 0 "register_operand" "=D")
18876         (plus:DI (match_dup 1)
18877                  (const_int 8)))]
18878   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18879   "stosq"
18880   [(set_attr "type" "str")
18881    (set_attr "memory" "store")
18882    (set_attr "mode" "DI")])
18883
18884 (define_insn "*strsetsi_1"
18885   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18886         (match_operand:SI 2 "register_operand" "a"))
18887    (set (match_operand:SI 0 "register_operand" "=D")
18888         (plus:SI (match_dup 1)
18889                  (const_int 4)))]
18890   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18891   "{stosl|stosd}"
18892   [(set_attr "type" "str")
18893    (set_attr "memory" "store")
18894    (set_attr "mode" "SI")])
18895
18896 (define_insn "*strsetsi_rex_1"
18897   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18898         (match_operand:SI 2 "register_operand" "a"))
18899    (set (match_operand:DI 0 "register_operand" "=D")
18900         (plus:DI (match_dup 1)
18901                  (const_int 4)))]
18902   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18903   "{stosl|stosd}"
18904   [(set_attr "type" "str")
18905    (set_attr "memory" "store")
18906    (set_attr "mode" "SI")])
18907
18908 (define_insn "*strsethi_1"
18909   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18910         (match_operand:HI 2 "register_operand" "a"))
18911    (set (match_operand:SI 0 "register_operand" "=D")
18912         (plus:SI (match_dup 1)
18913                  (const_int 2)))]
18914   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18915   "stosw"
18916   [(set_attr "type" "str")
18917    (set_attr "memory" "store")
18918    (set_attr "mode" "HI")])
18919
18920 (define_insn "*strsethi_rex_1"
18921   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18922         (match_operand:HI 2 "register_operand" "a"))
18923    (set (match_operand:DI 0 "register_operand" "=D")
18924         (plus:DI (match_dup 1)
18925                  (const_int 2)))]
18926   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18927   "stosw"
18928   [(set_attr "type" "str")
18929    (set_attr "memory" "store")
18930    (set_attr "mode" "HI")])
18931
18932 (define_insn "*strsetqi_1"
18933   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18934         (match_operand:QI 2 "register_operand" "a"))
18935    (set (match_operand:SI 0 "register_operand" "=D")
18936         (plus:SI (match_dup 1)
18937                  (const_int 1)))]
18938   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18939   "stosb"
18940   [(set_attr "type" "str")
18941    (set_attr "memory" "store")
18942    (set_attr "mode" "QI")])
18943
18944 (define_insn "*strsetqi_rex_1"
18945   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18946         (match_operand:QI 2 "register_operand" "a"))
18947    (set (match_operand:DI 0 "register_operand" "=D")
18948         (plus:DI (match_dup 1)
18949                  (const_int 1)))]
18950   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18951   "stosb"
18952   [(set_attr "type" "str")
18953    (set_attr "memory" "store")
18954    (set_attr "mode" "QI")])
18955
18956 (define_expand "rep_stos"
18957   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18958               (set (match_operand 0 "register_operand" "")
18959                    (match_operand 4 "" ""))
18960               (set (match_operand 2 "memory_operand" "") (const_int 0))
18961               (use (match_operand 3 "register_operand" ""))
18962               (use (match_dup 1))])]
18963   ""
18964   "")
18965
18966 (define_insn "*rep_stosdi_rex64"
18967   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18968    (set (match_operand:DI 0 "register_operand" "=D")
18969         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18970                             (const_int 3))
18971                  (match_operand:DI 3 "register_operand" "0")))
18972    (set (mem:BLK (match_dup 3))
18973         (const_int 0))
18974    (use (match_operand:DI 2 "register_operand" "a"))
18975    (use (match_dup 4))]
18976   "TARGET_64BIT"
18977   "rep stosq"
18978   [(set_attr "type" "str")
18979    (set_attr "prefix_rep" "1")
18980    (set_attr "memory" "store")
18981    (set_attr "mode" "DI")])
18982
18983 (define_insn "*rep_stossi"
18984   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18985    (set (match_operand:SI 0 "register_operand" "=D")
18986         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18987                             (const_int 2))
18988                  (match_operand:SI 3 "register_operand" "0")))
18989    (set (mem:BLK (match_dup 3))
18990         (const_int 0))
18991    (use (match_operand:SI 2 "register_operand" "a"))
18992    (use (match_dup 4))]
18993   "!TARGET_64BIT"
18994   "rep stos{l|d}"
18995   [(set_attr "type" "str")
18996    (set_attr "prefix_rep" "1")
18997    (set_attr "memory" "store")
18998    (set_attr "mode" "SI")])
18999
19000 (define_insn "*rep_stossi_rex64"
19001   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19002    (set (match_operand:DI 0 "register_operand" "=D")
19003         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19004                             (const_int 2))
19005                  (match_operand:DI 3 "register_operand" "0")))
19006    (set (mem:BLK (match_dup 3))
19007         (const_int 0))
19008    (use (match_operand:SI 2 "register_operand" "a"))
19009    (use (match_dup 4))]
19010   "TARGET_64BIT"
19011   "rep stos{l|d}"
19012   [(set_attr "type" "str")
19013    (set_attr "prefix_rep" "1")
19014    (set_attr "memory" "store")
19015    (set_attr "mode" "SI")])
19016
19017 (define_insn "*rep_stosqi"
19018   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19019    (set (match_operand:SI 0 "register_operand" "=D")
19020         (plus:SI (match_operand:SI 3 "register_operand" "0")
19021                  (match_operand:SI 4 "register_operand" "1")))
19022    (set (mem:BLK (match_dup 3))
19023         (const_int 0))
19024    (use (match_operand:QI 2 "register_operand" "a"))
19025    (use (match_dup 4))]
19026   "!TARGET_64BIT"
19027   "rep stosb"
19028   [(set_attr "type" "str")
19029    (set_attr "prefix_rep" "1")
19030    (set_attr "memory" "store")
19031    (set_attr "mode" "QI")])
19032
19033 (define_insn "*rep_stosqi_rex64"
19034   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19035    (set (match_operand:DI 0 "register_operand" "=D")
19036         (plus:DI (match_operand:DI 3 "register_operand" "0")
19037                  (match_operand:DI 4 "register_operand" "1")))
19038    (set (mem:BLK (match_dup 3))
19039         (const_int 0))
19040    (use (match_operand:QI 2 "register_operand" "a"))
19041    (use (match_dup 4))]
19042   "TARGET_64BIT"
19043   "rep stosb"
19044   [(set_attr "type" "str")
19045    (set_attr "prefix_rep" "1")
19046    (set_attr "memory" "store")
19047    (set_attr "mode" "QI")])
19048
19049 (define_expand "cmpstrnsi"
19050   [(set (match_operand:SI 0 "register_operand" "")
19051         (compare:SI (match_operand:BLK 1 "general_operand" "")
19052                     (match_operand:BLK 2 "general_operand" "")))
19053    (use (match_operand 3 "general_operand" ""))
19054    (use (match_operand 4 "immediate_operand" ""))]
19055   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
19056 {
19057   rtx addr1, addr2, out, outlow, count, countreg, align;
19058
19059   /* Can't use this if the user has appropriated esi or edi.  */
19060   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19061     FAIL;
19062
19063   out = operands[0];
19064   if (!REG_P (out))
19065     out = gen_reg_rtx (SImode);
19066
19067   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19068   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19069   if (addr1 != XEXP (operands[1], 0))
19070     operands[1] = replace_equiv_address_nv (operands[1], addr1);
19071   if (addr2 != XEXP (operands[2], 0))
19072     operands[2] = replace_equiv_address_nv (operands[2], addr2);
19073
19074   count = operands[3];
19075   countreg = ix86_zero_extend_to_Pmode (count);
19076
19077   /* %%% Iff we are testing strict equality, we can use known alignment
19078      to good advantage.  This may be possible with combine, particularly
19079      once cc0 is dead.  */
19080   align = operands[4];
19081
19082   if (CONST_INT_P (count))
19083     {
19084       if (INTVAL (count) == 0)
19085         {
19086           emit_move_insn (operands[0], const0_rtx);
19087           DONE;
19088         }
19089       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19090                                      operands[1], operands[2]));
19091     }
19092   else
19093     {
19094       if (TARGET_64BIT)
19095         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19096       else
19097         emit_insn (gen_cmpsi_1 (countreg, countreg));
19098       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19099                                   operands[1], operands[2]));
19100     }
19101
19102   outlow = gen_lowpart (QImode, out);
19103   emit_insn (gen_cmpintqi (outlow));
19104   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19105
19106   if (operands[0] != out)
19107     emit_move_insn (operands[0], out);
19108
19109   DONE;
19110 })
19111
19112 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19113
19114 (define_expand "cmpintqi"
19115   [(set (match_dup 1)
19116         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19117    (set (match_dup 2)
19118         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19119    (parallel [(set (match_operand:QI 0 "register_operand" "")
19120                    (minus:QI (match_dup 1)
19121                              (match_dup 2)))
19122               (clobber (reg:CC FLAGS_REG))])]
19123   ""
19124   "operands[1] = gen_reg_rtx (QImode);
19125    operands[2] = gen_reg_rtx (QImode);")
19126
19127 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
19128 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
19129
19130 (define_expand "cmpstrnqi_nz_1"
19131   [(parallel [(set (reg:CC FLAGS_REG)
19132                    (compare:CC (match_operand 4 "memory_operand" "")
19133                                (match_operand 5 "memory_operand" "")))
19134               (use (match_operand 2 "register_operand" ""))
19135               (use (match_operand:SI 3 "immediate_operand" ""))
19136               (clobber (match_operand 0 "register_operand" ""))
19137               (clobber (match_operand 1 "register_operand" ""))
19138               (clobber (match_dup 2))])]
19139   ""
19140   "")
19141
19142 (define_insn "*cmpstrnqi_nz_1"
19143   [(set (reg:CC FLAGS_REG)
19144         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19145                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19146    (use (match_operand:SI 6 "register_operand" "2"))
19147    (use (match_operand:SI 3 "immediate_operand" "i"))
19148    (clobber (match_operand:SI 0 "register_operand" "=S"))
19149    (clobber (match_operand:SI 1 "register_operand" "=D"))
19150    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19151   "!TARGET_64BIT"
19152   "repz cmpsb"
19153   [(set_attr "type" "str")
19154    (set_attr "mode" "QI")
19155    (set_attr "prefix_rep" "1")])
19156
19157 (define_insn "*cmpstrnqi_nz_rex_1"
19158   [(set (reg:CC FLAGS_REG)
19159         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19160                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19161    (use (match_operand:DI 6 "register_operand" "2"))
19162    (use (match_operand:SI 3 "immediate_operand" "i"))
19163    (clobber (match_operand:DI 0 "register_operand" "=S"))
19164    (clobber (match_operand:DI 1 "register_operand" "=D"))
19165    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19166   "TARGET_64BIT"
19167   "repz cmpsb"
19168   [(set_attr "type" "str")
19169    (set_attr "mode" "QI")
19170    (set_attr "prefix_rep" "1")])
19171
19172 ;; The same, but the count is not known to not be zero.
19173
19174 (define_expand "cmpstrnqi_1"
19175   [(parallel [(set (reg:CC FLAGS_REG)
19176                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19177                                      (const_int 0))
19178                   (compare:CC (match_operand 4 "memory_operand" "")
19179                               (match_operand 5 "memory_operand" ""))
19180                   (const_int 0)))
19181               (use (match_operand:SI 3 "immediate_operand" ""))
19182               (use (reg:CC FLAGS_REG))
19183               (clobber (match_operand 0 "register_operand" ""))
19184               (clobber (match_operand 1 "register_operand" ""))
19185               (clobber (match_dup 2))])]
19186   ""
19187   "")
19188
19189 (define_insn "*cmpstrnqi_1"
19190   [(set (reg:CC FLAGS_REG)
19191         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19192                              (const_int 0))
19193           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19194                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19195           (const_int 0)))
19196    (use (match_operand:SI 3 "immediate_operand" "i"))
19197    (use (reg:CC FLAGS_REG))
19198    (clobber (match_operand:SI 0 "register_operand" "=S"))
19199    (clobber (match_operand:SI 1 "register_operand" "=D"))
19200    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19201   "!TARGET_64BIT"
19202   "repz cmpsb"
19203   [(set_attr "type" "str")
19204    (set_attr "mode" "QI")
19205    (set_attr "prefix_rep" "1")])
19206
19207 (define_insn "*cmpstrnqi_rex_1"
19208   [(set (reg:CC FLAGS_REG)
19209         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19210                              (const_int 0))
19211           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19212                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19213           (const_int 0)))
19214    (use (match_operand:SI 3 "immediate_operand" "i"))
19215    (use (reg:CC FLAGS_REG))
19216    (clobber (match_operand:DI 0 "register_operand" "=S"))
19217    (clobber (match_operand:DI 1 "register_operand" "=D"))
19218    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19219   "TARGET_64BIT"
19220   "repz cmpsb"
19221   [(set_attr "type" "str")
19222    (set_attr "mode" "QI")
19223    (set_attr "prefix_rep" "1")])
19224
19225 (define_expand "strlensi"
19226   [(set (match_operand:SI 0 "register_operand" "")
19227         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19228                     (match_operand:QI 2 "immediate_operand" "")
19229                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19230   ""
19231 {
19232  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19233    DONE;
19234  else
19235    FAIL;
19236 })
19237
19238 (define_expand "strlendi"
19239   [(set (match_operand:DI 0 "register_operand" "")
19240         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19241                     (match_operand:QI 2 "immediate_operand" "")
19242                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19243   ""
19244 {
19245  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19246    DONE;
19247  else
19248    FAIL;
19249 })
19250
19251 (define_expand "strlenqi_1"
19252   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19253               (clobber (match_operand 1 "register_operand" ""))
19254               (clobber (reg:CC FLAGS_REG))])]
19255   ""
19256   "")
19257
19258 (define_insn "*strlenqi_1"
19259   [(set (match_operand:SI 0 "register_operand" "=&c")
19260         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19261                     (match_operand:QI 2 "register_operand" "a")
19262                     (match_operand:SI 3 "immediate_operand" "i")
19263                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19264    (clobber (match_operand:SI 1 "register_operand" "=D"))
19265    (clobber (reg:CC FLAGS_REG))]
19266   "!TARGET_64BIT"
19267   "repnz scasb"
19268   [(set_attr "type" "str")
19269    (set_attr "mode" "QI")
19270    (set_attr "prefix_rep" "1")])
19271
19272 (define_insn "*strlenqi_rex_1"
19273   [(set (match_operand:DI 0 "register_operand" "=&c")
19274         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19275                     (match_operand:QI 2 "register_operand" "a")
19276                     (match_operand:DI 3 "immediate_operand" "i")
19277                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19278    (clobber (match_operand:DI 1 "register_operand" "=D"))
19279    (clobber (reg:CC FLAGS_REG))]
19280   "TARGET_64BIT"
19281   "repnz scasb"
19282   [(set_attr "type" "str")
19283    (set_attr "mode" "QI")
19284    (set_attr "prefix_rep" "1")])
19285
19286 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19287 ;; handled in combine, but it is not currently up to the task.
19288 ;; When used for their truth value, the cmpstrn* expanders generate
19289 ;; code like this:
19290 ;;
19291 ;;   repz cmpsb
19292 ;;   seta       %al
19293 ;;   setb       %dl
19294 ;;   cmpb       %al, %dl
19295 ;;   jcc        label
19296 ;;
19297 ;; The intermediate three instructions are unnecessary.
19298
19299 ;; This one handles cmpstrn*_nz_1...
19300 (define_peephole2
19301   [(parallel[
19302      (set (reg:CC FLAGS_REG)
19303           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19304                       (mem:BLK (match_operand 5 "register_operand" ""))))
19305      (use (match_operand 6 "register_operand" ""))
19306      (use (match_operand:SI 3 "immediate_operand" ""))
19307      (clobber (match_operand 0 "register_operand" ""))
19308      (clobber (match_operand 1 "register_operand" ""))
19309      (clobber (match_operand 2 "register_operand" ""))])
19310    (set (match_operand:QI 7 "register_operand" "")
19311         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19312    (set (match_operand:QI 8 "register_operand" "")
19313         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19314    (set (reg FLAGS_REG)
19315         (compare (match_dup 7) (match_dup 8)))
19316   ]
19317   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19318   [(parallel[
19319      (set (reg:CC FLAGS_REG)
19320           (compare:CC (mem:BLK (match_dup 4))
19321                       (mem:BLK (match_dup 5))))
19322      (use (match_dup 6))
19323      (use (match_dup 3))
19324      (clobber (match_dup 0))
19325      (clobber (match_dup 1))
19326      (clobber (match_dup 2))])]
19327   "")
19328
19329 ;; ...and this one handles cmpstrn*_1.
19330 (define_peephole2
19331   [(parallel[
19332      (set (reg:CC FLAGS_REG)
19333           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19334                                (const_int 0))
19335             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19336                         (mem:BLK (match_operand 5 "register_operand" "")))
19337             (const_int 0)))
19338      (use (match_operand:SI 3 "immediate_operand" ""))
19339      (use (reg:CC FLAGS_REG))
19340      (clobber (match_operand 0 "register_operand" ""))
19341      (clobber (match_operand 1 "register_operand" ""))
19342      (clobber (match_operand 2 "register_operand" ""))])
19343    (set (match_operand:QI 7 "register_operand" "")
19344         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19345    (set (match_operand:QI 8 "register_operand" "")
19346         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19347    (set (reg FLAGS_REG)
19348         (compare (match_dup 7) (match_dup 8)))
19349   ]
19350   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19351   [(parallel[
19352      (set (reg:CC FLAGS_REG)
19353           (if_then_else:CC (ne (match_dup 6)
19354                                (const_int 0))
19355             (compare:CC (mem:BLK (match_dup 4))
19356                         (mem:BLK (match_dup 5)))
19357             (const_int 0)))
19358      (use (match_dup 3))
19359      (use (reg:CC FLAGS_REG))
19360      (clobber (match_dup 0))
19361      (clobber (match_dup 1))
19362      (clobber (match_dup 2))])]
19363   "")
19364
19365
19366 \f
19367 ;; Conditional move instructions.
19368
19369 (define_expand "movdicc"
19370   [(set (match_operand:DI 0 "register_operand" "")
19371         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19372                          (match_operand:DI 2 "general_operand" "")
19373                          (match_operand:DI 3 "general_operand" "")))]
19374   "TARGET_64BIT"
19375   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19376
19377 (define_insn "x86_movdicc_0_m1_rex64"
19378   [(set (match_operand:DI 0 "register_operand" "=r")
19379         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19380           (const_int -1)
19381           (const_int 0)))
19382    (clobber (reg:CC FLAGS_REG))]
19383   "TARGET_64BIT"
19384   "sbb{q}\t%0, %0"
19385   ; Since we don't have the proper number of operands for an alu insn,
19386   ; fill in all the blanks.
19387   [(set_attr "type" "alu")
19388    (set_attr "pent_pair" "pu")
19389    (set_attr "memory" "none")
19390    (set_attr "imm_disp" "false")
19391    (set_attr "mode" "DI")
19392    (set_attr "length_immediate" "0")])
19393
19394 (define_insn "*x86_movdicc_0_m1_se"
19395   [(set (match_operand:DI 0 "register_operand" "=r")
19396         (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19397                          (const_int 1)
19398                          (const_int 0)))
19399    (clobber (reg:CC FLAGS_REG))]
19400   ""
19401   "sbb{q}\t%0, %0"
19402   [(set_attr "type" "alu")
19403    (set_attr "pent_pair" "pu")
19404    (set_attr "memory" "none")
19405    (set_attr "imm_disp" "false")
19406    (set_attr "mode" "DI")
19407    (set_attr "length_immediate" "0")])
19408
19409 (define_insn "*movdicc_c_rex64"
19410   [(set (match_operand:DI 0 "register_operand" "=r,r")
19411         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19412                                 [(reg FLAGS_REG) (const_int 0)])
19413                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19414                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19415   "TARGET_64BIT && TARGET_CMOVE
19416    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19417   "@
19418    cmov%O2%C1\t{%2, %0|%0, %2}
19419    cmov%O2%c1\t{%3, %0|%0, %3}"
19420   [(set_attr "type" "icmov")
19421    (set_attr "mode" "DI")])
19422
19423 (define_expand "movsicc"
19424   [(set (match_operand:SI 0 "register_operand" "")
19425         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19426                          (match_operand:SI 2 "general_operand" "")
19427                          (match_operand:SI 3 "general_operand" "")))]
19428   ""
19429   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19430
19431 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19432 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19433 ;; So just document what we're doing explicitly.
19434
19435 (define_insn "x86_movsicc_0_m1"
19436   [(set (match_operand:SI 0 "register_operand" "=r")
19437         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19438           (const_int -1)
19439           (const_int 0)))
19440    (clobber (reg:CC FLAGS_REG))]
19441   ""
19442   "sbb{l}\t%0, %0"
19443   ; Since we don't have the proper number of operands for an alu insn,
19444   ; fill in all the blanks.
19445   [(set_attr "type" "alu")
19446    (set_attr "pent_pair" "pu")
19447    (set_attr "memory" "none")
19448    (set_attr "imm_disp" "false")
19449    (set_attr "mode" "SI")
19450    (set_attr "length_immediate" "0")])
19451
19452 (define_insn "*x86_movsicc_0_m1_se"
19453   [(set (match_operand:SI 0 "register_operand" "=r")
19454         (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19455                          (const_int 1)
19456                          (const_int 0)))
19457    (clobber (reg:CC FLAGS_REG))]
19458   ""
19459   "sbb{l}\t%0, %0"
19460   [(set_attr "type" "alu")
19461    (set_attr "pent_pair" "pu")
19462    (set_attr "memory" "none")
19463    (set_attr "imm_disp" "false")
19464    (set_attr "mode" "SI")
19465    (set_attr "length_immediate" "0")])
19466
19467 (define_insn "*movsicc_noc"
19468   [(set (match_operand:SI 0 "register_operand" "=r,r")
19469         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19470                                 [(reg FLAGS_REG) (const_int 0)])
19471                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19472                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19473   "TARGET_CMOVE
19474    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19475   "@
19476    cmov%O2%C1\t{%2, %0|%0, %2}
19477    cmov%O2%c1\t{%3, %0|%0, %3}"
19478   [(set_attr "type" "icmov")
19479    (set_attr "mode" "SI")])
19480
19481 (define_expand "movhicc"
19482   [(set (match_operand:HI 0 "register_operand" "")
19483         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19484                          (match_operand:HI 2 "general_operand" "")
19485                          (match_operand:HI 3 "general_operand" "")))]
19486   "TARGET_HIMODE_MATH"
19487   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19488
19489 (define_insn "*movhicc_noc"
19490   [(set (match_operand:HI 0 "register_operand" "=r,r")
19491         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19492                                 [(reg FLAGS_REG) (const_int 0)])
19493                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19494                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19495   "TARGET_CMOVE
19496    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19497   "@
19498    cmov%O2%C1\t{%2, %0|%0, %2}
19499    cmov%O2%c1\t{%3, %0|%0, %3}"
19500   [(set_attr "type" "icmov")
19501    (set_attr "mode" "HI")])
19502
19503 (define_expand "movqicc"
19504   [(set (match_operand:QI 0 "register_operand" "")
19505         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19506                          (match_operand:QI 2 "general_operand" "")
19507                          (match_operand:QI 3 "general_operand" "")))]
19508   "TARGET_QIMODE_MATH"
19509   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19510
19511 (define_insn_and_split "*movqicc_noc"
19512   [(set (match_operand:QI 0 "register_operand" "=r,r")
19513         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19514                                 [(match_operand 4 "flags_reg_operand" "")
19515                                  (const_int 0)])
19516                       (match_operand:QI 2 "register_operand" "r,0")
19517                       (match_operand:QI 3 "register_operand" "0,r")))]
19518   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19519   "#"
19520   "&& reload_completed"
19521   [(set (match_dup 0)
19522         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19523                       (match_dup 2)
19524                       (match_dup 3)))]
19525   "operands[0] = gen_lowpart (SImode, operands[0]);
19526    operands[2] = gen_lowpart (SImode, operands[2]);
19527    operands[3] = gen_lowpart (SImode, operands[3]);"
19528   [(set_attr "type" "icmov")
19529    (set_attr "mode" "SI")])
19530
19531 (define_expand "mov<mode>cc"
19532   [(set (match_operand:X87MODEF 0 "register_operand" "")
19533         (if_then_else:X87MODEF
19534           (match_operand 1 "comparison_operator" "")
19535           (match_operand:X87MODEF 2 "register_operand" "")
19536           (match_operand:X87MODEF 3 "register_operand" "")))]
19537   "(TARGET_80387 && TARGET_CMOVE)
19538    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19539   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19540
19541 (define_insn "*movsfcc_1_387"
19542   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19543         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19544                                 [(reg FLAGS_REG) (const_int 0)])
19545                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19546                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19547   "TARGET_80387 && TARGET_CMOVE
19548    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19549   "@
19550    fcmov%F1\t{%2, %0|%0, %2}
19551    fcmov%f1\t{%3, %0|%0, %3}
19552    cmov%O2%C1\t{%2, %0|%0, %2}
19553    cmov%O2%c1\t{%3, %0|%0, %3}"
19554   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19555    (set_attr "mode" "SF,SF,SI,SI")])
19556
19557 (define_insn "*movdfcc_1"
19558   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19559         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19560                                 [(reg FLAGS_REG) (const_int 0)])
19561                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19562                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19563   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19564    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19565   "@
19566    fcmov%F1\t{%2, %0|%0, %2}
19567    fcmov%f1\t{%3, %0|%0, %3}
19568    #
19569    #"
19570   [(set_attr "type" "fcmov,fcmov,multi,multi")
19571    (set_attr "mode" "DF")])
19572
19573 (define_insn "*movdfcc_1_rex64"
19574   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19575         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19576                                 [(reg FLAGS_REG) (const_int 0)])
19577                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19578                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19579   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19580    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19581   "@
19582    fcmov%F1\t{%2, %0|%0, %2}
19583    fcmov%f1\t{%3, %0|%0, %3}
19584    cmov%O2%C1\t{%2, %0|%0, %2}
19585    cmov%O2%c1\t{%3, %0|%0, %3}"
19586   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19587    (set_attr "mode" "DF")])
19588
19589 (define_split
19590   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19591         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19592                                 [(match_operand 4 "flags_reg_operand" "")
19593                                  (const_int 0)])
19594                       (match_operand:DF 2 "nonimmediate_operand" "")
19595                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19596   "!TARGET_64BIT && reload_completed"
19597   [(set (match_dup 2)
19598         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19599                       (match_dup 5)
19600                       (match_dup 7)))
19601    (set (match_dup 3)
19602         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19603                       (match_dup 6)
19604                       (match_dup 8)))]
19605   "split_di (operands+2, 1, operands+5, operands+6);
19606    split_di (operands+3, 1, operands+7, operands+8);
19607    split_di (operands, 1, operands+2, operands+3);")
19608
19609 (define_insn "*movxfcc_1"
19610   [(set (match_operand:XF 0 "register_operand" "=f,f")
19611         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19612                                 [(reg FLAGS_REG) (const_int 0)])
19613                       (match_operand:XF 2 "register_operand" "f,0")
19614                       (match_operand:XF 3 "register_operand" "0,f")))]
19615   "TARGET_80387 && TARGET_CMOVE"
19616   "@
19617    fcmov%F1\t{%2, %0|%0, %2}
19618    fcmov%f1\t{%3, %0|%0, %3}"
19619   [(set_attr "type" "fcmov")
19620    (set_attr "mode" "XF")])
19621
19622 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19623 ;; the scalar versions to have only XMM registers as operands.
19624
19625 ;; SSE5 conditional move
19626 (define_insn "*sse5_pcmov_<mode>"
19627   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19628         (if_then_else:MODEF
19629           (match_operand:MODEF 1 "register_operand" "x,0")
19630           (match_operand:MODEF 2 "register_operand" "0,x")
19631           (match_operand:MODEF 3 "register_operand" "x,x")))]
19632   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19633   "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19634   [(set_attr "type" "sse4arg")])
19635
19636 ;; These versions of the min/max patterns are intentionally ignorant of
19637 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19638 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19639 ;; are undefined in this condition, we're certain this is correct.
19640
19641 (define_insn "smin<mode>3"
19642   [(set (match_operand:MODEF 0 "register_operand" "=x")
19643         (smin:MODEF
19644           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19645           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19646   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19647   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19648   [(set_attr "type" "sseadd")
19649    (set_attr "mode" "<MODE>")])
19650
19651 (define_insn "smax<mode>3"
19652   [(set (match_operand:MODEF 0 "register_operand" "=x")
19653         (smax:MODEF
19654           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19655           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19656   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19657   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19658   [(set_attr "type" "sseadd")
19659    (set_attr "mode" "<MODE>")])
19660
19661 ;; These versions of the min/max patterns implement exactly the operations
19662 ;;   min = (op1 < op2 ? op1 : op2)
19663 ;;   max = (!(op1 < op2) ? op1 : op2)
19664 ;; Their operands are not commutative, and thus they may be used in the
19665 ;; presence of -0.0 and NaN.
19666
19667 (define_insn "*ieee_smin<mode>3"
19668   [(set (match_operand:MODEF 0 "register_operand" "=x")
19669         (unspec:MODEF
19670           [(match_operand:MODEF 1 "register_operand" "0")
19671            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19672          UNSPEC_IEEE_MIN))]
19673   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19674   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19675   [(set_attr "type" "sseadd")
19676    (set_attr "mode" "<MODE>")])
19677
19678 (define_insn "*ieee_smax<mode>3"
19679   [(set (match_operand:MODEF 0 "register_operand" "=x")
19680         (unspec:MODEF
19681           [(match_operand:MODEF 1 "register_operand" "0")
19682            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19683          UNSPEC_IEEE_MAX))]
19684   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19685   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19686   [(set_attr "type" "sseadd")
19687    (set_attr "mode" "<MODE>")])
19688
19689 ;; Make two stack loads independent:
19690 ;;   fld aa              fld aa
19691 ;;   fld %st(0)     ->   fld bb
19692 ;;   fmul bb             fmul %st(1), %st
19693 ;;
19694 ;; Actually we only match the last two instructions for simplicity.
19695 (define_peephole2
19696   [(set (match_operand 0 "fp_register_operand" "")
19697         (match_operand 1 "fp_register_operand" ""))
19698    (set (match_dup 0)
19699         (match_operator 2 "binary_fp_operator"
19700            [(match_dup 0)
19701             (match_operand 3 "memory_operand" "")]))]
19702   "REGNO (operands[0]) != REGNO (operands[1])"
19703   [(set (match_dup 0) (match_dup 3))
19704    (set (match_dup 0) (match_dup 4))]
19705
19706   ;; The % modifier is not operational anymore in peephole2's, so we have to
19707   ;; swap the operands manually in the case of addition and multiplication.
19708   "if (COMMUTATIVE_ARITH_P (operands[2]))
19709      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19710                                  operands[0], operands[1]);
19711    else
19712      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19713                                  operands[1], operands[0]);")
19714
19715 ;; Conditional addition patterns
19716 (define_expand "addqicc"
19717   [(match_operand:QI 0 "register_operand" "")
19718    (match_operand 1 "comparison_operator" "")
19719    (match_operand:QI 2 "register_operand" "")
19720    (match_operand:QI 3 "const_int_operand" "")]
19721   ""
19722   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19723
19724 (define_expand "addhicc"
19725   [(match_operand:HI 0 "register_operand" "")
19726    (match_operand 1 "comparison_operator" "")
19727    (match_operand:HI 2 "register_operand" "")
19728    (match_operand:HI 3 "const_int_operand" "")]
19729   ""
19730   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19731
19732 (define_expand "addsicc"
19733   [(match_operand:SI 0 "register_operand" "")
19734    (match_operand 1 "comparison_operator" "")
19735    (match_operand:SI 2 "register_operand" "")
19736    (match_operand:SI 3 "const_int_operand" "")]
19737   ""
19738   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19739
19740 (define_expand "adddicc"
19741   [(match_operand:DI 0 "register_operand" "")
19742    (match_operand 1 "comparison_operator" "")
19743    (match_operand:DI 2 "register_operand" "")
19744    (match_operand:DI 3 "const_int_operand" "")]
19745   "TARGET_64BIT"
19746   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19747
19748 \f
19749 ;; Misc patterns (?)
19750
19751 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19752 ;; Otherwise there will be nothing to keep
19753 ;;
19754 ;; [(set (reg ebp) (reg esp))]
19755 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19756 ;;  (clobber (eflags)]
19757 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19758 ;;
19759 ;; in proper program order.
19760 (define_insn "pro_epilogue_adjust_stack_1"
19761   [(set (match_operand:SI 0 "register_operand" "=r,r")
19762         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19763                  (match_operand:SI 2 "immediate_operand" "i,i")))
19764    (clobber (reg:CC FLAGS_REG))
19765    (clobber (mem:BLK (scratch)))]
19766   "!TARGET_64BIT"
19767 {
19768   switch (get_attr_type (insn))
19769     {
19770     case TYPE_IMOV:
19771       return "mov{l}\t{%1, %0|%0, %1}";
19772
19773     case TYPE_ALU:
19774       if (CONST_INT_P (operands[2])
19775           && (INTVAL (operands[2]) == 128
19776               || (INTVAL (operands[2]) < 0
19777                   && INTVAL (operands[2]) != -128)))
19778         {
19779           operands[2] = GEN_INT (-INTVAL (operands[2]));
19780           return "sub{l}\t{%2, %0|%0, %2}";
19781         }
19782       return "add{l}\t{%2, %0|%0, %2}";
19783
19784     case TYPE_LEA:
19785       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19786       return "lea{l}\t{%a2, %0|%0, %a2}";
19787
19788     default:
19789       gcc_unreachable ();
19790     }
19791 }
19792   [(set (attr "type")
19793         (cond [(eq_attr "alternative" "0")
19794                  (const_string "alu")
19795                (match_operand:SI 2 "const0_operand" "")
19796                  (const_string "imov")
19797               ]
19798               (const_string "lea")))
19799    (set_attr "mode" "SI")])
19800
19801 (define_insn "pro_epilogue_adjust_stack_rex64"
19802   [(set (match_operand:DI 0 "register_operand" "=r,r")
19803         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19804                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19805    (clobber (reg:CC FLAGS_REG))
19806    (clobber (mem:BLK (scratch)))]
19807   "TARGET_64BIT"
19808 {
19809   switch (get_attr_type (insn))
19810     {
19811     case TYPE_IMOV:
19812       return "mov{q}\t{%1, %0|%0, %1}";
19813
19814     case TYPE_ALU:
19815       if (CONST_INT_P (operands[2])
19816           /* Avoid overflows.  */
19817           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19818           && (INTVAL (operands[2]) == 128
19819               || (INTVAL (operands[2]) < 0
19820                   && INTVAL (operands[2]) != -128)))
19821         {
19822           operands[2] = GEN_INT (-INTVAL (operands[2]));
19823           return "sub{q}\t{%2, %0|%0, %2}";
19824         }
19825       return "add{q}\t{%2, %0|%0, %2}";
19826
19827     case TYPE_LEA:
19828       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19829       return "lea{q}\t{%a2, %0|%0, %a2}";
19830
19831     default:
19832       gcc_unreachable ();
19833     }
19834 }
19835   [(set (attr "type")
19836         (cond [(eq_attr "alternative" "0")
19837                  (const_string "alu")
19838                (match_operand:DI 2 "const0_operand" "")
19839                  (const_string "imov")
19840               ]
19841               (const_string "lea")))
19842    (set_attr "mode" "DI")])
19843
19844 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19845   [(set (match_operand:DI 0 "register_operand" "=r,r")
19846         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19847                  (match_operand:DI 3 "immediate_operand" "i,i")))
19848    (use (match_operand:DI 2 "register_operand" "r,r"))
19849    (clobber (reg:CC FLAGS_REG))
19850    (clobber (mem:BLK (scratch)))]
19851   "TARGET_64BIT"
19852 {
19853   switch (get_attr_type (insn))
19854     {
19855     case TYPE_ALU:
19856       return "add{q}\t{%2, %0|%0, %2}";
19857
19858     case TYPE_LEA:
19859       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19860       return "lea{q}\t{%a2, %0|%0, %a2}";
19861
19862     default:
19863       gcc_unreachable ();
19864     }
19865 }
19866   [(set_attr "type" "alu,lea")
19867    (set_attr "mode" "DI")])
19868
19869 (define_insn "allocate_stack_worker_32"
19870   [(set (match_operand:SI 0 "register_operand" "+a")
19871         (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19872    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19873    (clobber (reg:CC FLAGS_REG))]
19874   "!TARGET_64BIT && TARGET_STACK_PROBE"
19875   "call\t___chkstk"
19876   [(set_attr "type" "multi")
19877    (set_attr "length" "5")])
19878
19879 (define_insn "allocate_stack_worker_64"
19880   [(set (match_operand:DI 0 "register_operand" "=a")
19881         (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19882    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19883    (clobber (reg:DI R10_REG))
19884    (clobber (reg:DI R11_REG))
19885    (clobber (reg:CC FLAGS_REG))]
19886   "TARGET_64BIT && TARGET_STACK_PROBE"
19887   "call\t___chkstk"
19888   [(set_attr "type" "multi")
19889    (set_attr "length" "5")])
19890
19891 (define_expand "allocate_stack"
19892   [(match_operand 0 "register_operand" "")
19893    (match_operand 1 "general_operand" "")]
19894   "TARGET_STACK_PROBE"
19895 {
19896   rtx x;
19897
19898 #ifndef CHECK_STACK_LIMIT
19899 #define CHECK_STACK_LIMIT 0
19900 #endif
19901
19902   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19903       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19904     {
19905       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19906                                stack_pointer_rtx, 0, OPTAB_DIRECT);
19907       if (x != stack_pointer_rtx)
19908         emit_move_insn (stack_pointer_rtx, x);
19909     }
19910   else
19911     {
19912       x = copy_to_mode_reg (Pmode, operands[1]);
19913       if (TARGET_64BIT)
19914         x = gen_allocate_stack_worker_64 (x);
19915       else
19916         x = gen_allocate_stack_worker_32 (x);
19917       emit_insn (x);
19918     }
19919
19920   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19921   DONE;
19922 })
19923
19924 (define_expand "builtin_setjmp_receiver"
19925   [(label_ref (match_operand 0 "" ""))]
19926   "!TARGET_64BIT && flag_pic"
19927 {
19928   if (TARGET_MACHO)
19929     {
19930       rtx xops[3];
19931       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19932       rtx label_rtx = gen_label_rtx ();
19933       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19934       xops[0] = xops[1] = picreg;
19935       xops[2] = gen_rtx_CONST (SImode,
19936                   gen_rtx_MINUS (SImode,
19937                     gen_rtx_LABEL_REF (SImode, label_rtx),
19938                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19939       ix86_expand_binary_operator (MINUS, SImode, xops);
19940     }
19941   else
19942     emit_insn (gen_set_got (pic_offset_table_rtx));
19943   DONE;
19944 })
19945 \f
19946 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19947
19948 (define_split
19949   [(set (match_operand 0 "register_operand" "")
19950         (match_operator 3 "promotable_binary_operator"
19951            [(match_operand 1 "register_operand" "")
19952             (match_operand 2 "aligned_operand" "")]))
19953    (clobber (reg:CC FLAGS_REG))]
19954   "! TARGET_PARTIAL_REG_STALL && reload_completed
19955    && ((GET_MODE (operands[0]) == HImode
19956         && ((!optimize_size && !TARGET_FAST_PREFIX)
19957             /* ??? next two lines just !satisfies_constraint_K (...) */
19958             || !CONST_INT_P (operands[2])
19959             || satisfies_constraint_K (operands[2])))
19960        || (GET_MODE (operands[0]) == QImode
19961            && (TARGET_PROMOTE_QImode || optimize_size)))"
19962   [(parallel [(set (match_dup 0)
19963                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19964               (clobber (reg:CC FLAGS_REG))])]
19965   "operands[0] = gen_lowpart (SImode, operands[0]);
19966    operands[1] = gen_lowpart (SImode, operands[1]);
19967    if (GET_CODE (operands[3]) != ASHIFT)
19968      operands[2] = gen_lowpart (SImode, operands[2]);
19969    PUT_MODE (operands[3], SImode);")
19970
19971 ; Promote the QImode tests, as i386 has encoding of the AND
19972 ; instruction with 32-bit sign-extended immediate and thus the
19973 ; instruction size is unchanged, except in the %eax case for
19974 ; which it is increased by one byte, hence the ! optimize_size.
19975 (define_split
19976   [(set (match_operand 0 "flags_reg_operand" "")
19977         (match_operator 2 "compare_operator"
19978           [(and (match_operand 3 "aligned_operand" "")
19979                 (match_operand 4 "const_int_operand" ""))
19980            (const_int 0)]))
19981    (set (match_operand 1 "register_operand" "")
19982         (and (match_dup 3) (match_dup 4)))]
19983   "! TARGET_PARTIAL_REG_STALL && reload_completed
19984    && ! optimize_size
19985    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19986        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19987    /* Ensure that the operand will remain sign-extended immediate.  */
19988    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19989   [(parallel [(set (match_dup 0)
19990                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19991                                     (const_int 0)]))
19992               (set (match_dup 1)
19993                    (and:SI (match_dup 3) (match_dup 4)))])]
19994 {
19995   operands[4]
19996     = gen_int_mode (INTVAL (operands[4])
19997                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19998   operands[1] = gen_lowpart (SImode, operands[1]);
19999   operands[3] = gen_lowpart (SImode, operands[3]);
20000 })
20001
20002 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20003 ; the TEST instruction with 32-bit sign-extended immediate and thus
20004 ; the instruction size would at least double, which is not what we
20005 ; want even with ! optimize_size.
20006 (define_split
20007   [(set (match_operand 0 "flags_reg_operand" "")
20008         (match_operator 1 "compare_operator"
20009           [(and (match_operand:HI 2 "aligned_operand" "")
20010                 (match_operand:HI 3 "const_int_operand" ""))
20011            (const_int 0)]))]
20012   "! TARGET_PARTIAL_REG_STALL && reload_completed
20013    && ! TARGET_FAST_PREFIX
20014    && ! optimize_size
20015    /* Ensure that the operand will remain sign-extended immediate.  */
20016    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20017   [(set (match_dup 0)
20018         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20019                          (const_int 0)]))]
20020 {
20021   operands[3]
20022     = gen_int_mode (INTVAL (operands[3])
20023                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20024   operands[2] = gen_lowpart (SImode, operands[2]);
20025 })
20026
20027 (define_split
20028   [(set (match_operand 0 "register_operand" "")
20029         (neg (match_operand 1 "register_operand" "")))
20030    (clobber (reg:CC FLAGS_REG))]
20031   "! TARGET_PARTIAL_REG_STALL && reload_completed
20032    && (GET_MODE (operands[0]) == HImode
20033        || (GET_MODE (operands[0]) == QImode
20034            && (TARGET_PROMOTE_QImode || optimize_size)))"
20035   [(parallel [(set (match_dup 0)
20036                    (neg:SI (match_dup 1)))
20037               (clobber (reg:CC FLAGS_REG))])]
20038   "operands[0] = gen_lowpart (SImode, operands[0]);
20039    operands[1] = gen_lowpart (SImode, operands[1]);")
20040
20041 (define_split
20042   [(set (match_operand 0 "register_operand" "")
20043         (not (match_operand 1 "register_operand" "")))]
20044   "! TARGET_PARTIAL_REG_STALL && reload_completed
20045    && (GET_MODE (operands[0]) == HImode
20046        || (GET_MODE (operands[0]) == QImode
20047            && (TARGET_PROMOTE_QImode || optimize_size)))"
20048   [(set (match_dup 0)
20049         (not:SI (match_dup 1)))]
20050   "operands[0] = gen_lowpart (SImode, operands[0]);
20051    operands[1] = gen_lowpart (SImode, operands[1]);")
20052
20053 (define_split
20054   [(set (match_operand 0 "register_operand" "")
20055         (if_then_else (match_operator 1 "comparison_operator"
20056                                 [(reg FLAGS_REG) (const_int 0)])
20057                       (match_operand 2 "register_operand" "")
20058                       (match_operand 3 "register_operand" "")))]
20059   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20060    && (GET_MODE (operands[0]) == HImode
20061        || (GET_MODE (operands[0]) == QImode
20062            && (TARGET_PROMOTE_QImode || optimize_size)))"
20063   [(set (match_dup 0)
20064         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20065   "operands[0] = gen_lowpart (SImode, operands[0]);
20066    operands[2] = gen_lowpart (SImode, operands[2]);
20067    operands[3] = gen_lowpart (SImode, operands[3]);")
20068
20069 \f
20070 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
20071 ;; transform a complex memory operation into two memory to register operations.
20072
20073 ;; Don't push memory operands
20074 (define_peephole2
20075   [(set (match_operand:SI 0 "push_operand" "")
20076         (match_operand:SI 1 "memory_operand" ""))
20077    (match_scratch:SI 2 "r")]
20078   "!optimize_size && !TARGET_PUSH_MEMORY
20079    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20080   [(set (match_dup 2) (match_dup 1))
20081    (set (match_dup 0) (match_dup 2))]
20082   "")
20083
20084 (define_peephole2
20085   [(set (match_operand:DI 0 "push_operand" "")
20086         (match_operand:DI 1 "memory_operand" ""))
20087    (match_scratch:DI 2 "r")]
20088   "!optimize_size && !TARGET_PUSH_MEMORY
20089    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20090   [(set (match_dup 2) (match_dup 1))
20091    (set (match_dup 0) (match_dup 2))]
20092   "")
20093
20094 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20095 ;; SImode pushes.
20096 (define_peephole2
20097   [(set (match_operand:SF 0 "push_operand" "")
20098         (match_operand:SF 1 "memory_operand" ""))
20099    (match_scratch:SF 2 "r")]
20100   "!optimize_size && !TARGET_PUSH_MEMORY
20101    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20102   [(set (match_dup 2) (match_dup 1))
20103    (set (match_dup 0) (match_dup 2))]
20104   "")
20105
20106 (define_peephole2
20107   [(set (match_operand:HI 0 "push_operand" "")
20108         (match_operand:HI 1 "memory_operand" ""))
20109    (match_scratch:HI 2 "r")]
20110   "!optimize_size && !TARGET_PUSH_MEMORY
20111    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20112   [(set (match_dup 2) (match_dup 1))
20113    (set (match_dup 0) (match_dup 2))]
20114   "")
20115
20116 (define_peephole2
20117   [(set (match_operand:QI 0 "push_operand" "")
20118         (match_operand:QI 1 "memory_operand" ""))
20119    (match_scratch:QI 2 "q")]
20120   "!optimize_size && !TARGET_PUSH_MEMORY
20121    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20122   [(set (match_dup 2) (match_dup 1))
20123    (set (match_dup 0) (match_dup 2))]
20124   "")
20125
20126 ;; Don't move an immediate directly to memory when the instruction
20127 ;; gets too big.
20128 (define_peephole2
20129   [(match_scratch:SI 1 "r")
20130    (set (match_operand:SI 0 "memory_operand" "")
20131         (const_int 0))]
20132   "! optimize_size
20133    && ! TARGET_USE_MOV0
20134    && TARGET_SPLIT_LONG_MOVES
20135    && get_attr_length (insn) >= ix86_cost->large_insn
20136    && peep2_regno_dead_p (0, FLAGS_REG)"
20137   [(parallel [(set (match_dup 1) (const_int 0))
20138               (clobber (reg:CC FLAGS_REG))])
20139    (set (match_dup 0) (match_dup 1))]
20140   "")
20141
20142 (define_peephole2
20143   [(match_scratch:HI 1 "r")
20144    (set (match_operand:HI 0 "memory_operand" "")
20145         (const_int 0))]
20146   "! optimize_size
20147    && ! TARGET_USE_MOV0
20148    && TARGET_SPLIT_LONG_MOVES
20149    && get_attr_length (insn) >= ix86_cost->large_insn
20150    && peep2_regno_dead_p (0, FLAGS_REG)"
20151   [(parallel [(set (match_dup 2) (const_int 0))
20152               (clobber (reg:CC FLAGS_REG))])
20153    (set (match_dup 0) (match_dup 1))]
20154   "operands[2] = gen_lowpart (SImode, operands[1]);")
20155
20156 (define_peephole2
20157   [(match_scratch:QI 1 "q")
20158    (set (match_operand:QI 0 "memory_operand" "")
20159         (const_int 0))]
20160   "! optimize_size
20161    && ! TARGET_USE_MOV0
20162    && TARGET_SPLIT_LONG_MOVES
20163    && get_attr_length (insn) >= ix86_cost->large_insn
20164    && peep2_regno_dead_p (0, FLAGS_REG)"
20165   [(parallel [(set (match_dup 2) (const_int 0))
20166               (clobber (reg:CC FLAGS_REG))])
20167    (set (match_dup 0) (match_dup 1))]
20168   "operands[2] = gen_lowpart (SImode, operands[1]);")
20169
20170 (define_peephole2
20171   [(match_scratch:SI 2 "r")
20172    (set (match_operand:SI 0 "memory_operand" "")
20173         (match_operand:SI 1 "immediate_operand" ""))]
20174   "! optimize_size
20175    && TARGET_SPLIT_LONG_MOVES
20176    && get_attr_length (insn) >= ix86_cost->large_insn"
20177   [(set (match_dup 2) (match_dup 1))
20178    (set (match_dup 0) (match_dup 2))]
20179   "")
20180
20181 (define_peephole2
20182   [(match_scratch:HI 2 "r")
20183    (set (match_operand:HI 0 "memory_operand" "")
20184         (match_operand:HI 1 "immediate_operand" ""))]
20185   "! optimize_size
20186    && TARGET_SPLIT_LONG_MOVES
20187    && get_attr_length (insn) >= ix86_cost->large_insn"
20188   [(set (match_dup 2) (match_dup 1))
20189    (set (match_dup 0) (match_dup 2))]
20190   "")
20191
20192 (define_peephole2
20193   [(match_scratch:QI 2 "q")
20194    (set (match_operand:QI 0 "memory_operand" "")
20195         (match_operand:QI 1 "immediate_operand" ""))]
20196   "! optimize_size
20197    && TARGET_SPLIT_LONG_MOVES
20198    && get_attr_length (insn) >= ix86_cost->large_insn"
20199   [(set (match_dup 2) (match_dup 1))
20200    (set (match_dup 0) (match_dup 2))]
20201   "")
20202
20203 ;; Don't compare memory with zero, load and use a test instead.
20204 (define_peephole2
20205   [(set (match_operand 0 "flags_reg_operand" "")
20206         (match_operator 1 "compare_operator"
20207           [(match_operand:SI 2 "memory_operand" "")
20208            (const_int 0)]))
20209    (match_scratch:SI 3 "r")]
20210   " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20211   [(set (match_dup 3) (match_dup 2))
20212    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20213   "")
20214
20215 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20216 ;; Don't split NOTs with a displacement operand, because resulting XOR
20217 ;; will not be pairable anyway.
20218 ;;
20219 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20220 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20221 ;; so this split helps here as well.
20222 ;;
20223 ;; Note: Can't do this as a regular split because we can't get proper
20224 ;; lifetime information then.
20225
20226 (define_peephole2
20227   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20228         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20229   "!optimize_size
20230    && ((TARGET_NOT_UNPAIRABLE
20231         && (!MEM_P (operands[0])
20232             || !memory_displacement_operand (operands[0], SImode)))
20233        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20234    && peep2_regno_dead_p (0, FLAGS_REG)"
20235   [(parallel [(set (match_dup 0)
20236                    (xor:SI (match_dup 1) (const_int -1)))
20237               (clobber (reg:CC FLAGS_REG))])]
20238   "")
20239
20240 (define_peephole2
20241   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20242         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20243   "!optimize_size
20244    && ((TARGET_NOT_UNPAIRABLE
20245         && (!MEM_P (operands[0])
20246             || !memory_displacement_operand (operands[0], HImode)))
20247        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20248    && peep2_regno_dead_p (0, FLAGS_REG)"
20249   [(parallel [(set (match_dup 0)
20250                    (xor:HI (match_dup 1) (const_int -1)))
20251               (clobber (reg:CC FLAGS_REG))])]
20252   "")
20253
20254 (define_peephole2
20255   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20256         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20257   "!optimize_size
20258    && ((TARGET_NOT_UNPAIRABLE
20259         && (!MEM_P (operands[0])
20260             || !memory_displacement_operand (operands[0], QImode)))
20261        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20262    && peep2_regno_dead_p (0, FLAGS_REG)"
20263   [(parallel [(set (match_dup 0)
20264                    (xor:QI (match_dup 1) (const_int -1)))
20265               (clobber (reg:CC FLAGS_REG))])]
20266   "")
20267
20268 ;; Non pairable "test imm, reg" instructions can be translated to
20269 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20270 ;; byte opcode instead of two, have a short form for byte operands),
20271 ;; so do it for other CPUs as well.  Given that the value was dead,
20272 ;; this should not create any new dependencies.  Pass on the sub-word
20273 ;; versions if we're concerned about partial register stalls.
20274
20275 (define_peephole2
20276   [(set (match_operand 0 "flags_reg_operand" "")
20277         (match_operator 1 "compare_operator"
20278           [(and:SI (match_operand:SI 2 "register_operand" "")
20279                    (match_operand:SI 3 "immediate_operand" ""))
20280            (const_int 0)]))]
20281   "ix86_match_ccmode (insn, CCNOmode)
20282    && (true_regnum (operands[2]) != AX_REG
20283        || satisfies_constraint_K (operands[3]))
20284    && peep2_reg_dead_p (1, operands[2])"
20285   [(parallel
20286      [(set (match_dup 0)
20287            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20288                             (const_int 0)]))
20289       (set (match_dup 2)
20290            (and:SI (match_dup 2) (match_dup 3)))])]
20291   "")
20292
20293 ;; We don't need to handle HImode case, because it will be promoted to SImode
20294 ;; on ! TARGET_PARTIAL_REG_STALL
20295
20296 (define_peephole2
20297   [(set (match_operand 0 "flags_reg_operand" "")
20298         (match_operator 1 "compare_operator"
20299           [(and:QI (match_operand:QI 2 "register_operand" "")
20300                    (match_operand:QI 3 "immediate_operand" ""))
20301            (const_int 0)]))]
20302   "! TARGET_PARTIAL_REG_STALL
20303    && ix86_match_ccmode (insn, CCNOmode)
20304    && true_regnum (operands[2]) != AX_REG
20305    && peep2_reg_dead_p (1, operands[2])"
20306   [(parallel
20307      [(set (match_dup 0)
20308            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20309                             (const_int 0)]))
20310       (set (match_dup 2)
20311            (and:QI (match_dup 2) (match_dup 3)))])]
20312   "")
20313
20314 (define_peephole2
20315   [(set (match_operand 0 "flags_reg_operand" "")
20316         (match_operator 1 "compare_operator"
20317           [(and:SI
20318              (zero_extract:SI
20319                (match_operand 2 "ext_register_operand" "")
20320                (const_int 8)
20321                (const_int 8))
20322              (match_operand 3 "const_int_operand" ""))
20323            (const_int 0)]))]
20324   "! TARGET_PARTIAL_REG_STALL
20325    && ix86_match_ccmode (insn, CCNOmode)
20326    && true_regnum (operands[2]) != AX_REG
20327    && peep2_reg_dead_p (1, operands[2])"
20328   [(parallel [(set (match_dup 0)
20329                    (match_op_dup 1
20330                      [(and:SI
20331                         (zero_extract:SI
20332                           (match_dup 2)
20333                           (const_int 8)
20334                           (const_int 8))
20335                         (match_dup 3))
20336                       (const_int 0)]))
20337               (set (zero_extract:SI (match_dup 2)
20338                                     (const_int 8)
20339                                     (const_int 8))
20340                    (and:SI
20341                      (zero_extract:SI
20342                        (match_dup 2)
20343                        (const_int 8)
20344                        (const_int 8))
20345                      (match_dup 3)))])]
20346   "")
20347
20348 ;; Don't do logical operations with memory inputs.
20349 (define_peephole2
20350   [(match_scratch:SI 2 "r")
20351    (parallel [(set (match_operand:SI 0 "register_operand" "")
20352                    (match_operator:SI 3 "arith_or_logical_operator"
20353                      [(match_dup 0)
20354                       (match_operand:SI 1 "memory_operand" "")]))
20355               (clobber (reg:CC FLAGS_REG))])]
20356   "! optimize_size && ! TARGET_READ_MODIFY"
20357   [(set (match_dup 2) (match_dup 1))
20358    (parallel [(set (match_dup 0)
20359                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20360               (clobber (reg:CC FLAGS_REG))])]
20361   "")
20362
20363 (define_peephole2
20364   [(match_scratch:SI 2 "r")
20365    (parallel [(set (match_operand:SI 0 "register_operand" "")
20366                    (match_operator:SI 3 "arith_or_logical_operator"
20367                      [(match_operand:SI 1 "memory_operand" "")
20368                       (match_dup 0)]))
20369               (clobber (reg:CC FLAGS_REG))])]
20370   "! optimize_size && ! TARGET_READ_MODIFY"
20371   [(set (match_dup 2) (match_dup 1))
20372    (parallel [(set (match_dup 0)
20373                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20374               (clobber (reg:CC FLAGS_REG))])]
20375   "")
20376
20377 ; Don't do logical operations with memory outputs
20378 ;
20379 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20380 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20381 ; the same decoder scheduling characteristics as the original.
20382
20383 (define_peephole2
20384   [(match_scratch:SI 2 "r")
20385    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20386                    (match_operator:SI 3 "arith_or_logical_operator"
20387                      [(match_dup 0)
20388                       (match_operand:SI 1 "nonmemory_operand" "")]))
20389               (clobber (reg:CC FLAGS_REG))])]
20390   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20391   [(set (match_dup 2) (match_dup 0))
20392    (parallel [(set (match_dup 2)
20393                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20394               (clobber (reg:CC FLAGS_REG))])
20395    (set (match_dup 0) (match_dup 2))]
20396   "")
20397
20398 (define_peephole2
20399   [(match_scratch:SI 2 "r")
20400    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20401                    (match_operator:SI 3 "arith_or_logical_operator"
20402                      [(match_operand:SI 1 "nonmemory_operand" "")
20403                       (match_dup 0)]))
20404               (clobber (reg:CC FLAGS_REG))])]
20405   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20406   [(set (match_dup 2) (match_dup 0))
20407    (parallel [(set (match_dup 2)
20408                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20409               (clobber (reg:CC FLAGS_REG))])
20410    (set (match_dup 0) (match_dup 2))]
20411   "")
20412
20413 ;; Attempt to always use XOR for zeroing registers.
20414 (define_peephole2
20415   [(set (match_operand 0 "register_operand" "")
20416         (match_operand 1 "const0_operand" ""))]
20417   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20418    && (! TARGET_USE_MOV0 || optimize_size)
20419    && GENERAL_REG_P (operands[0])
20420    && peep2_regno_dead_p (0, FLAGS_REG)"
20421   [(parallel [(set (match_dup 0) (const_int 0))
20422               (clobber (reg:CC FLAGS_REG))])]
20423 {
20424   operands[0] = gen_lowpart (word_mode, operands[0]);
20425 })
20426
20427 (define_peephole2
20428   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20429         (const_int 0))]
20430   "(GET_MODE (operands[0]) == QImode
20431     || GET_MODE (operands[0]) == HImode)
20432    && (! TARGET_USE_MOV0 || optimize_size)
20433    && peep2_regno_dead_p (0, FLAGS_REG)"
20434   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20435               (clobber (reg:CC FLAGS_REG))])])
20436
20437 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20438 (define_peephole2
20439   [(set (match_operand 0 "register_operand" "")
20440         (const_int -1))]
20441   "(GET_MODE (operands[0]) == HImode
20442     || GET_MODE (operands[0]) == SImode
20443     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20444    && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20445    && peep2_regno_dead_p (0, FLAGS_REG)"
20446   [(parallel [(set (match_dup 0) (const_int -1))
20447               (clobber (reg:CC FLAGS_REG))])]
20448   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20449                               operands[0]);")
20450
20451 ;; Attempt to convert simple leas to adds. These can be created by
20452 ;; move expanders.
20453 (define_peephole2
20454   [(set (match_operand:SI 0 "register_operand" "")
20455         (plus:SI (match_dup 0)
20456                  (match_operand:SI 1 "nonmemory_operand" "")))]
20457   "peep2_regno_dead_p (0, FLAGS_REG)"
20458   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20459               (clobber (reg:CC FLAGS_REG))])]
20460   "")
20461
20462 (define_peephole2
20463   [(set (match_operand:SI 0 "register_operand" "")
20464         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20465                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20466   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20467   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20468               (clobber (reg:CC FLAGS_REG))])]
20469   "operands[2] = gen_lowpart (SImode, operands[2]);")
20470
20471 (define_peephole2
20472   [(set (match_operand:DI 0 "register_operand" "")
20473         (plus:DI (match_dup 0)
20474                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20475   "peep2_regno_dead_p (0, FLAGS_REG)"
20476   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20477               (clobber (reg:CC FLAGS_REG))])]
20478   "")
20479
20480 (define_peephole2
20481   [(set (match_operand:SI 0 "register_operand" "")
20482         (mult:SI (match_dup 0)
20483                  (match_operand:SI 1 "const_int_operand" "")))]
20484   "exact_log2 (INTVAL (operands[1])) >= 0
20485    && peep2_regno_dead_p (0, FLAGS_REG)"
20486   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20487               (clobber (reg:CC FLAGS_REG))])]
20488   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20489
20490 (define_peephole2
20491   [(set (match_operand:DI 0 "register_operand" "")
20492         (mult:DI (match_dup 0)
20493                  (match_operand:DI 1 "const_int_operand" "")))]
20494   "exact_log2 (INTVAL (operands[1])) >= 0
20495    && peep2_regno_dead_p (0, FLAGS_REG)"
20496   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20497               (clobber (reg:CC FLAGS_REG))])]
20498   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20499
20500 (define_peephole2
20501   [(set (match_operand:SI 0 "register_operand" "")
20502         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20503                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20504   "exact_log2 (INTVAL (operands[2])) >= 0
20505    && REGNO (operands[0]) == REGNO (operands[1])
20506    && peep2_regno_dead_p (0, FLAGS_REG)"
20507   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20508               (clobber (reg:CC FLAGS_REG))])]
20509   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20510
20511 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20512 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20513 ;; many CPUs it is also faster, since special hardware to avoid esp
20514 ;; dependencies is present.
20515
20516 ;; While some of these conversions may be done using splitters, we use peepholes
20517 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20518
20519 ;; Convert prologue esp subtractions to push.
20520 ;; We need register to push.  In order to keep verify_flow_info happy we have
20521 ;; two choices
20522 ;; - use scratch and clobber it in order to avoid dependencies
20523 ;; - use already live register
20524 ;; We can't use the second way right now, since there is no reliable way how to
20525 ;; verify that given register is live.  First choice will also most likely in
20526 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20527 ;; call clobbered registers are dead.  We may want to use base pointer as an
20528 ;; alternative when no register is available later.
20529
20530 (define_peephole2
20531   [(match_scratch:SI 0 "r")
20532    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20533               (clobber (reg:CC FLAGS_REG))
20534               (clobber (mem:BLK (scratch)))])]
20535   "optimize_size || !TARGET_SUB_ESP_4"
20536   [(clobber (match_dup 0))
20537    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20538               (clobber (mem:BLK (scratch)))])])
20539
20540 (define_peephole2
20541   [(match_scratch:SI 0 "r")
20542    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20543               (clobber (reg:CC FLAGS_REG))
20544               (clobber (mem:BLK (scratch)))])]
20545   "optimize_size || !TARGET_SUB_ESP_8"
20546   [(clobber (match_dup 0))
20547    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20548    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20549               (clobber (mem:BLK (scratch)))])])
20550
20551 ;; Convert esp subtractions to push.
20552 (define_peephole2
20553   [(match_scratch:SI 0 "r")
20554    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20555               (clobber (reg:CC FLAGS_REG))])]
20556   "optimize_size || !TARGET_SUB_ESP_4"
20557   [(clobber (match_dup 0))
20558    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20559
20560 (define_peephole2
20561   [(match_scratch:SI 0 "r")
20562    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20563               (clobber (reg:CC FLAGS_REG))])]
20564   "optimize_size || !TARGET_SUB_ESP_8"
20565   [(clobber (match_dup 0))
20566    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20567    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20568
20569 ;; Convert epilogue deallocator to pop.
20570 (define_peephole2
20571   [(match_scratch:SI 0 "r")
20572    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20573               (clobber (reg:CC FLAGS_REG))
20574               (clobber (mem:BLK (scratch)))])]
20575   "optimize_size || !TARGET_ADD_ESP_4"
20576   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20577               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20578               (clobber (mem:BLK (scratch)))])]
20579   "")
20580
20581 ;; Two pops case is tricky, since pop causes dependency on destination register.
20582 ;; We use two registers if available.
20583 (define_peephole2
20584   [(match_scratch:SI 0 "r")
20585    (match_scratch:SI 1 "r")
20586    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20587               (clobber (reg:CC FLAGS_REG))
20588               (clobber (mem:BLK (scratch)))])]
20589   "optimize_size || !TARGET_ADD_ESP_8"
20590   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20591               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20592               (clobber (mem:BLK (scratch)))])
20593    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20594               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20595   "")
20596
20597 (define_peephole2
20598   [(match_scratch:SI 0 "r")
20599    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20600               (clobber (reg:CC FLAGS_REG))
20601               (clobber (mem:BLK (scratch)))])]
20602   "optimize_size"
20603   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20604               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20605               (clobber (mem:BLK (scratch)))])
20606    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20607               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20608   "")
20609
20610 ;; Convert esp additions to pop.
20611 (define_peephole2
20612   [(match_scratch:SI 0 "r")
20613    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20614               (clobber (reg:CC FLAGS_REG))])]
20615   ""
20616   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20617               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20618   "")
20619
20620 ;; Two pops case is tricky, since pop causes dependency on destination register.
20621 ;; We use two registers if available.
20622 (define_peephole2
20623   [(match_scratch:SI 0 "r")
20624    (match_scratch:SI 1 "r")
20625    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20626               (clobber (reg:CC FLAGS_REG))])]
20627   ""
20628   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20629               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20630    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20631               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20632   "")
20633
20634 (define_peephole2
20635   [(match_scratch:SI 0 "r")
20636    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20637               (clobber (reg:CC FLAGS_REG))])]
20638   "optimize_size"
20639   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20640               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20641    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20642               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20643   "")
20644 \f
20645 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20646 ;; required and register dies.  Similarly for 128 to plus -128.
20647 (define_peephole2
20648   [(set (match_operand 0 "flags_reg_operand" "")
20649         (match_operator 1 "compare_operator"
20650           [(match_operand 2 "register_operand" "")
20651            (match_operand 3 "const_int_operand" "")]))]
20652   "(INTVAL (operands[3]) == -1
20653     || INTVAL (operands[3]) == 1
20654     || INTVAL (operands[3]) == 128)
20655    && ix86_match_ccmode (insn, CCGCmode)
20656    && peep2_reg_dead_p (1, operands[2])"
20657   [(parallel [(set (match_dup 0)
20658                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20659               (clobber (match_dup 2))])]
20660   "")
20661 \f
20662 (define_peephole2
20663   [(match_scratch:DI 0 "r")
20664    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20665               (clobber (reg:CC FLAGS_REG))
20666               (clobber (mem:BLK (scratch)))])]
20667   "optimize_size || !TARGET_SUB_ESP_4"
20668   [(clobber (match_dup 0))
20669    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20670               (clobber (mem:BLK (scratch)))])])
20671
20672 (define_peephole2
20673   [(match_scratch:DI 0 "r")
20674    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20675               (clobber (reg:CC FLAGS_REG))
20676               (clobber (mem:BLK (scratch)))])]
20677   "optimize_size || !TARGET_SUB_ESP_8"
20678   [(clobber (match_dup 0))
20679    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20680    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20681               (clobber (mem:BLK (scratch)))])])
20682
20683 ;; Convert esp subtractions to push.
20684 (define_peephole2
20685   [(match_scratch:DI 0 "r")
20686    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20687               (clobber (reg:CC FLAGS_REG))])]
20688   "optimize_size || !TARGET_SUB_ESP_4"
20689   [(clobber (match_dup 0))
20690    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20691
20692 (define_peephole2
20693   [(match_scratch:DI 0 "r")
20694    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20695               (clobber (reg:CC FLAGS_REG))])]
20696   "optimize_size || !TARGET_SUB_ESP_8"
20697   [(clobber (match_dup 0))
20698    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20699    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20700
20701 ;; Convert epilogue deallocator to pop.
20702 (define_peephole2
20703   [(match_scratch:DI 0 "r")
20704    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20705               (clobber (reg:CC FLAGS_REG))
20706               (clobber (mem:BLK (scratch)))])]
20707   "optimize_size || !TARGET_ADD_ESP_4"
20708   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20709               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20710               (clobber (mem:BLK (scratch)))])]
20711   "")
20712
20713 ;; Two pops case is tricky, since pop causes dependency on destination register.
20714 ;; We use two registers if available.
20715 (define_peephole2
20716   [(match_scratch:DI 0 "r")
20717    (match_scratch:DI 1 "r")
20718    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20719               (clobber (reg:CC FLAGS_REG))
20720               (clobber (mem:BLK (scratch)))])]
20721   "optimize_size || !TARGET_ADD_ESP_8"
20722   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20723               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20724               (clobber (mem:BLK (scratch)))])
20725    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20726               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20727   "")
20728
20729 (define_peephole2
20730   [(match_scratch:DI 0 "r")
20731    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20732               (clobber (reg:CC FLAGS_REG))
20733               (clobber (mem:BLK (scratch)))])]
20734   "optimize_size"
20735   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20736               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20737               (clobber (mem:BLK (scratch)))])
20738    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20739               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20740   "")
20741
20742 ;; Convert esp additions to pop.
20743 (define_peephole2
20744   [(match_scratch:DI 0 "r")
20745    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20746               (clobber (reg:CC FLAGS_REG))])]
20747   ""
20748   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20749               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20750   "")
20751
20752 ;; Two pops case is tricky, since pop causes dependency on destination register.
20753 ;; We use two registers if available.
20754 (define_peephole2
20755   [(match_scratch:DI 0 "r")
20756    (match_scratch:DI 1 "r")
20757    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20758               (clobber (reg:CC FLAGS_REG))])]
20759   ""
20760   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20761               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20762    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20763               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20764   "")
20765
20766 (define_peephole2
20767   [(match_scratch:DI 0 "r")
20768    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20769               (clobber (reg:CC FLAGS_REG))])]
20770   "optimize_size"
20771   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20772               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20773    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20774               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20775   "")
20776 \f
20777 ;; Convert imul by three, five and nine into lea
20778 (define_peephole2
20779   [(parallel
20780     [(set (match_operand:SI 0 "register_operand" "")
20781           (mult:SI (match_operand:SI 1 "register_operand" "")
20782                    (match_operand:SI 2 "const_int_operand" "")))
20783      (clobber (reg:CC FLAGS_REG))])]
20784   "INTVAL (operands[2]) == 3
20785    || INTVAL (operands[2]) == 5
20786    || INTVAL (operands[2]) == 9"
20787   [(set (match_dup 0)
20788         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20789                  (match_dup 1)))]
20790   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20791
20792 (define_peephole2
20793   [(parallel
20794     [(set (match_operand:SI 0 "register_operand" "")
20795           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20796                    (match_operand:SI 2 "const_int_operand" "")))
20797      (clobber (reg:CC FLAGS_REG))])]
20798   "!optimize_size
20799    && (INTVAL (operands[2]) == 3
20800        || INTVAL (operands[2]) == 5
20801        || INTVAL (operands[2]) == 9)"
20802   [(set (match_dup 0) (match_dup 1))
20803    (set (match_dup 0)
20804         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20805                  (match_dup 0)))]
20806   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20807
20808 (define_peephole2
20809   [(parallel
20810     [(set (match_operand:DI 0 "register_operand" "")
20811           (mult:DI (match_operand:DI 1 "register_operand" "")
20812                    (match_operand:DI 2 "const_int_operand" "")))
20813      (clobber (reg:CC FLAGS_REG))])]
20814   "TARGET_64BIT
20815    && (INTVAL (operands[2]) == 3
20816        || INTVAL (operands[2]) == 5
20817        || INTVAL (operands[2]) == 9)"
20818   [(set (match_dup 0)
20819         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20820                  (match_dup 1)))]
20821   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20822
20823 (define_peephole2
20824   [(parallel
20825     [(set (match_operand:DI 0 "register_operand" "")
20826           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20827                    (match_operand:DI 2 "const_int_operand" "")))
20828      (clobber (reg:CC FLAGS_REG))])]
20829   "TARGET_64BIT
20830    && !optimize_size
20831    && (INTVAL (operands[2]) == 3
20832        || INTVAL (operands[2]) == 5
20833        || INTVAL (operands[2]) == 9)"
20834   [(set (match_dup 0) (match_dup 1))
20835    (set (match_dup 0)
20836         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20837                  (match_dup 0)))]
20838   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20839
20840 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20841 ;; imul $32bit_imm, reg, reg is direct decoded.
20842 (define_peephole2
20843   [(match_scratch:DI 3 "r")
20844    (parallel [(set (match_operand:DI 0 "register_operand" "")
20845                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20846                             (match_operand:DI 2 "immediate_operand" "")))
20847               (clobber (reg:CC FLAGS_REG))])]
20848   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20849    && !satisfies_constraint_K (operands[2])"
20850   [(set (match_dup 3) (match_dup 1))
20851    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20852               (clobber (reg:CC FLAGS_REG))])]
20853 "")
20854
20855 (define_peephole2
20856   [(match_scratch:SI 3 "r")
20857    (parallel [(set (match_operand:SI 0 "register_operand" "")
20858                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20859                             (match_operand:SI 2 "immediate_operand" "")))
20860               (clobber (reg:CC FLAGS_REG))])]
20861   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20862    && !satisfies_constraint_K (operands[2])"
20863   [(set (match_dup 3) (match_dup 1))
20864    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20865               (clobber (reg:CC FLAGS_REG))])]
20866 "")
20867
20868 (define_peephole2
20869   [(match_scratch:SI 3 "r")
20870    (parallel [(set (match_operand:DI 0 "register_operand" "")
20871                    (zero_extend:DI
20872                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20873                               (match_operand:SI 2 "immediate_operand" ""))))
20874               (clobber (reg:CC FLAGS_REG))])]
20875   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20876    && !satisfies_constraint_K (operands[2])"
20877   [(set (match_dup 3) (match_dup 1))
20878    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20879               (clobber (reg:CC FLAGS_REG))])]
20880 "")
20881
20882 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20883 ;; Convert it into imul reg, reg
20884 ;; It would be better to force assembler to encode instruction using long
20885 ;; immediate, but there is apparently no way to do so.
20886 (define_peephole2
20887   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20888                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20889                             (match_operand:DI 2 "const_int_operand" "")))
20890               (clobber (reg:CC FLAGS_REG))])
20891    (match_scratch:DI 3 "r")]
20892   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20893    && satisfies_constraint_K (operands[2])"
20894   [(set (match_dup 3) (match_dup 2))
20895    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20896               (clobber (reg:CC FLAGS_REG))])]
20897 {
20898   if (!rtx_equal_p (operands[0], operands[1]))
20899     emit_move_insn (operands[0], operands[1]);
20900 })
20901
20902 (define_peephole2
20903   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20904                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20905                             (match_operand:SI 2 "const_int_operand" "")))
20906               (clobber (reg:CC FLAGS_REG))])
20907    (match_scratch:SI 3 "r")]
20908   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20909    && satisfies_constraint_K (operands[2])"
20910   [(set (match_dup 3) (match_dup 2))
20911    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20912               (clobber (reg:CC FLAGS_REG))])]
20913 {
20914   if (!rtx_equal_p (operands[0], operands[1]))
20915     emit_move_insn (operands[0], operands[1]);
20916 })
20917
20918 (define_peephole2
20919   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20920                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20921                             (match_operand:HI 2 "immediate_operand" "")))
20922               (clobber (reg:CC FLAGS_REG))])
20923    (match_scratch:HI 3 "r")]
20924   "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20925   [(set (match_dup 3) (match_dup 2))
20926    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20927               (clobber (reg:CC FLAGS_REG))])]
20928 {
20929   if (!rtx_equal_p (operands[0], operands[1]))
20930     emit_move_insn (operands[0], operands[1]);
20931 })
20932
20933 ;; After splitting up read-modify operations, array accesses with memory
20934 ;; operands might end up in form:
20935 ;;  sall    $2, %eax
20936 ;;  movl    4(%esp), %edx
20937 ;;  addl    %edx, %eax
20938 ;; instead of pre-splitting:
20939 ;;  sall    $2, %eax
20940 ;;  addl    4(%esp), %eax
20941 ;; Turn it into:
20942 ;;  movl    4(%esp), %edx
20943 ;;  leal    (%edx,%eax,4), %eax
20944
20945 (define_peephole2
20946   [(parallel [(set (match_operand 0 "register_operand" "")
20947                    (ashift (match_operand 1 "register_operand" "")
20948                            (match_operand 2 "const_int_operand" "")))
20949                (clobber (reg:CC FLAGS_REG))])
20950    (set (match_operand 3 "register_operand")
20951         (match_operand 4 "x86_64_general_operand" ""))
20952    (parallel [(set (match_operand 5 "register_operand" "")
20953                    (plus (match_operand 6 "register_operand" "")
20954                          (match_operand 7 "register_operand" "")))
20955                    (clobber (reg:CC FLAGS_REG))])]
20956   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20957    /* Validate MODE for lea.  */
20958    && ((!TARGET_PARTIAL_REG_STALL
20959         && (GET_MODE (operands[0]) == QImode
20960             || GET_MODE (operands[0]) == HImode))
20961        || GET_MODE (operands[0]) == SImode
20962        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20963    /* We reorder load and the shift.  */
20964    && !rtx_equal_p (operands[1], operands[3])
20965    && !reg_overlap_mentioned_p (operands[0], operands[4])
20966    /* Last PLUS must consist of operand 0 and 3.  */
20967    && !rtx_equal_p (operands[0], operands[3])
20968    && (rtx_equal_p (operands[3], operands[6])
20969        || rtx_equal_p (operands[3], operands[7]))
20970    && (rtx_equal_p (operands[0], operands[6])
20971        || rtx_equal_p (operands[0], operands[7]))
20972    /* The intermediate operand 0 must die or be same as output.  */
20973    && (rtx_equal_p (operands[0], operands[5])
20974        || peep2_reg_dead_p (3, operands[0]))"
20975   [(set (match_dup 3) (match_dup 4))
20976    (set (match_dup 0) (match_dup 1))]
20977 {
20978   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20979   int scale = 1 << INTVAL (operands[2]);
20980   rtx index = gen_lowpart (Pmode, operands[1]);
20981   rtx base = gen_lowpart (Pmode, operands[3]);
20982   rtx dest = gen_lowpart (mode, operands[5]);
20983
20984   operands[1] = gen_rtx_PLUS (Pmode, base,
20985                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20986   if (mode != Pmode)
20987     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20988   operands[0] = dest;
20989 })
20990 \f
20991 ;; Call-value patterns last so that the wildcard operand does not
20992 ;; disrupt insn-recog's switch tables.
20993
20994 (define_insn "*call_value_pop_0"
20995   [(set (match_operand 0 "" "")
20996         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20997               (match_operand:SI 2 "" "")))
20998    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20999                             (match_operand:SI 3 "immediate_operand" "")))]
21000   "!TARGET_64BIT"
21001 {
21002   if (SIBLING_CALL_P (insn))
21003     return "jmp\t%P1";
21004   else
21005     return "call\t%P1";
21006 }
21007   [(set_attr "type" "callv")])
21008
21009 (define_insn "*call_value_pop_1"
21010   [(set (match_operand 0 "" "")
21011         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21012               (match_operand:SI 2 "" "")))
21013    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21014                             (match_operand:SI 3 "immediate_operand" "i")))]
21015   "!TARGET_64BIT"
21016 {
21017   if (constant_call_address_operand (operands[1], Pmode))
21018     {
21019       if (SIBLING_CALL_P (insn))
21020         return "jmp\t%P1";
21021       else
21022         return "call\t%P1";
21023     }
21024   if (SIBLING_CALL_P (insn))
21025     return "jmp\t%A1";
21026   else
21027     return "call\t%A1";
21028 }
21029   [(set_attr "type" "callv")])
21030
21031 (define_insn "*call_value_0"
21032   [(set (match_operand 0 "" "")
21033         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21034               (match_operand:SI 2 "" "")))]
21035   "!TARGET_64BIT"
21036 {
21037   if (SIBLING_CALL_P (insn))
21038     return "jmp\t%P1";
21039   else
21040     return "call\t%P1";
21041 }
21042   [(set_attr "type" "callv")])
21043
21044 (define_insn "*call_value_0_rex64"
21045   [(set (match_operand 0 "" "")
21046         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21047               (match_operand:DI 2 "const_int_operand" "")))]
21048   "TARGET_64BIT"
21049 {
21050   if (SIBLING_CALL_P (insn))
21051     return "jmp\t%P1";
21052   else
21053     return "call\t%P1";
21054 }
21055   [(set_attr "type" "callv")])
21056
21057 (define_insn "*call_value_1"
21058   [(set (match_operand 0 "" "")
21059         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21060               (match_operand:SI 2 "" "")))]
21061   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21062 {
21063   if (constant_call_address_operand (operands[1], Pmode))
21064     return "call\t%P1";
21065   return "call\t%A1";
21066 }
21067   [(set_attr "type" "callv")])
21068
21069 (define_insn "*sibcall_value_1"
21070   [(set (match_operand 0 "" "")
21071         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21072               (match_operand:SI 2 "" "")))]
21073   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21074 {
21075   if (constant_call_address_operand (operands[1], Pmode))
21076     return "jmp\t%P1";
21077   return "jmp\t%A1";
21078 }
21079   [(set_attr "type" "callv")])
21080
21081 (define_insn "*call_value_1_rex64"
21082   [(set (match_operand 0 "" "")
21083         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21084               (match_operand:DI 2 "" "")))]
21085   "!SIBLING_CALL_P (insn) && TARGET_64BIT
21086    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21087 {
21088   if (constant_call_address_operand (operands[1], Pmode))
21089     return "call\t%P1";
21090   return "call\t%A1";
21091 }
21092   [(set_attr "type" "callv")])
21093
21094 (define_insn "*call_value_1_rex64_large"
21095   [(set (match_operand 0 "" "")
21096         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21097               (match_operand:DI 2 "" "")))]
21098   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21099   "call\t%A1"
21100   [(set_attr "type" "callv")])
21101
21102 (define_insn "*sibcall_value_1_rex64"
21103   [(set (match_operand 0 "" "")
21104         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21105               (match_operand:DI 2 "" "")))]
21106   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21107   "jmp\t%P1"
21108   [(set_attr "type" "callv")])
21109
21110 (define_insn "*sibcall_value_1_rex64_v"
21111   [(set (match_operand 0 "" "")
21112         (call (mem:QI (reg:DI R11_REG))
21113               (match_operand:DI 1 "" "")))]
21114   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21115   "jmp\t{*%%}r11"
21116   [(set_attr "type" "callv")])
21117 \f
21118 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21119 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21120 ;; caught for use by garbage collectors and the like.  Using an insn that
21121 ;; maps to SIGILL makes it more likely the program will rightfully die.
21122 ;; Keeping with tradition, "6" is in honor of #UD.
21123 (define_insn "trap"
21124   [(trap_if (const_int 1) (const_int 6))]
21125   ""
21126   { return ASM_SHORT "0x0b0f"; }
21127   [(set_attr "length" "2")])
21128
21129 (define_expand "sse_prologue_save"
21130   [(parallel [(set (match_operand:BLK 0 "" "")
21131                    (unspec:BLK [(reg:DI 21)
21132                                 (reg:DI 22)
21133                                 (reg:DI 23)
21134                                 (reg:DI 24)
21135                                 (reg:DI 25)
21136                                 (reg:DI 26)
21137                                 (reg:DI 27)
21138                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21139               (use (match_operand:DI 1 "register_operand" ""))
21140               (use (match_operand:DI 2 "immediate_operand" ""))
21141               (use (label_ref:DI (match_operand 3 "" "")))])]
21142   "TARGET_64BIT"
21143   "")
21144
21145 (define_insn "*sse_prologue_save_insn"
21146   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21147                           (match_operand:DI 4 "const_int_operand" "n")))
21148         (unspec:BLK [(reg:DI 21)
21149                      (reg:DI 22)
21150                      (reg:DI 23)
21151                      (reg:DI 24)
21152                      (reg:DI 25)
21153                      (reg:DI 26)
21154                      (reg:DI 27)
21155                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21156    (use (match_operand:DI 1 "register_operand" "r"))
21157    (use (match_operand:DI 2 "const_int_operand" "i"))
21158    (use (label_ref:DI (match_operand 3 "" "X")))]
21159   "TARGET_64BIT
21160    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21161    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21162   "*
21163 {
21164   int i;
21165   operands[0] = gen_rtx_MEM (Pmode,
21166                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21167   output_asm_insn (\"jmp\\t%A1\", operands);
21168   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21169     {
21170       operands[4] = adjust_address (operands[0], DImode, i*16);
21171       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21172       PUT_MODE (operands[4], TImode);
21173       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21174         output_asm_insn (\"rex\", operands);
21175       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21176     }
21177   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21178                              CODE_LABEL_NUMBER (operands[3]));
21179   return \"\";
21180 }
21181   "
21182   [(set_attr "type" "other")
21183    (set_attr "length_immediate" "0")
21184    (set_attr "length_address" "0")
21185    (set_attr "length" "135")
21186    (set_attr "memory" "store")
21187    (set_attr "modrm" "0")
21188    (set_attr "mode" "DI")])
21189
21190 (define_expand "prefetch"
21191   [(prefetch (match_operand 0 "address_operand" "")
21192              (match_operand:SI 1 "const_int_operand" "")
21193              (match_operand:SI 2 "const_int_operand" ""))]
21194   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21195 {
21196   int rw = INTVAL (operands[1]);
21197   int locality = INTVAL (operands[2]);
21198
21199   gcc_assert (rw == 0 || rw == 1);
21200   gcc_assert (locality >= 0 && locality <= 3);
21201   gcc_assert (GET_MODE (operands[0]) == Pmode
21202               || GET_MODE (operands[0]) == VOIDmode);
21203
21204   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21205      supported by SSE counterpart or the SSE prefetch is not available
21206      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21207      of locality.  */
21208   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21209     operands[2] = GEN_INT (3);
21210   else
21211     operands[1] = const0_rtx;
21212 })
21213
21214 (define_insn "*prefetch_sse"
21215   [(prefetch (match_operand:SI 0 "address_operand" "p")
21216              (const_int 0)
21217              (match_operand:SI 1 "const_int_operand" ""))]
21218   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21219 {
21220   static const char * const patterns[4] = {
21221    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21222   };
21223
21224   int locality = INTVAL (operands[1]);
21225   gcc_assert (locality >= 0 && locality <= 3);
21226
21227   return patterns[locality];
21228 }
21229   [(set_attr "type" "sse")
21230    (set_attr "memory" "none")])
21231
21232 (define_insn "*prefetch_sse_rex"
21233   [(prefetch (match_operand:DI 0 "address_operand" "p")
21234              (const_int 0)
21235              (match_operand:SI 1 "const_int_operand" ""))]
21236   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21237 {
21238   static const char * const patterns[4] = {
21239    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21240   };
21241
21242   int locality = INTVAL (operands[1]);
21243   gcc_assert (locality >= 0 && locality <= 3);
21244
21245   return patterns[locality];
21246 }
21247   [(set_attr "type" "sse")
21248    (set_attr "memory" "none")])
21249
21250 (define_insn "*prefetch_3dnow"
21251   [(prefetch (match_operand:SI 0 "address_operand" "p")
21252              (match_operand:SI 1 "const_int_operand" "n")
21253              (const_int 3))]
21254   "TARGET_3DNOW && !TARGET_64BIT"
21255 {
21256   if (INTVAL (operands[1]) == 0)
21257     return "prefetch\t%a0";
21258   else
21259     return "prefetchw\t%a0";
21260 }
21261   [(set_attr "type" "mmx")
21262    (set_attr "memory" "none")])
21263
21264 (define_insn "*prefetch_3dnow_rex"
21265   [(prefetch (match_operand:DI 0 "address_operand" "p")
21266              (match_operand:SI 1 "const_int_operand" "n")
21267              (const_int 3))]
21268   "TARGET_3DNOW && TARGET_64BIT"
21269 {
21270   if (INTVAL (operands[1]) == 0)
21271     return "prefetch\t%a0";
21272   else
21273     return "prefetchw\t%a0";
21274 }
21275   [(set_attr "type" "mmx")
21276    (set_attr "memory" "none")])
21277
21278 (define_expand "stack_protect_set"
21279   [(match_operand 0 "memory_operand" "")
21280    (match_operand 1 "memory_operand" "")]
21281   ""
21282 {
21283 #ifdef TARGET_THREAD_SSP_OFFSET
21284   if (TARGET_64BIT)
21285     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21286                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21287   else
21288     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21289                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21290 #else
21291   if (TARGET_64BIT)
21292     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21293   else
21294     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21295 #endif
21296   DONE;
21297 })
21298
21299 (define_insn "stack_protect_set_si"
21300   [(set (match_operand:SI 0 "memory_operand" "=m")
21301         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21302    (set (match_scratch:SI 2 "=&r") (const_int 0))
21303    (clobber (reg:CC FLAGS_REG))]
21304   ""
21305   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21306   [(set_attr "type" "multi")])
21307
21308 (define_insn "stack_protect_set_di"
21309   [(set (match_operand:DI 0 "memory_operand" "=m")
21310         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21311    (set (match_scratch:DI 2 "=&r") (const_int 0))
21312    (clobber (reg:CC FLAGS_REG))]
21313   "TARGET_64BIT"
21314   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21315   [(set_attr "type" "multi")])
21316
21317 (define_insn "stack_tls_protect_set_si"
21318   [(set (match_operand:SI 0 "memory_operand" "=m")
21319         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21320    (set (match_scratch:SI 2 "=&r") (const_int 0))
21321    (clobber (reg:CC FLAGS_REG))]
21322   ""
21323   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21324   [(set_attr "type" "multi")])
21325
21326 (define_insn "stack_tls_protect_set_di"
21327   [(set (match_operand:DI 0 "memory_operand" "=m")
21328         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21329    (set (match_scratch:DI 2 "=&r") (const_int 0))
21330    (clobber (reg:CC FLAGS_REG))]
21331   "TARGET_64BIT"
21332   {
21333      /* The kernel uses a different segment register for performance reasons; a
21334         system call would not have to trash the userspace segment register,
21335         which would be expensive */
21336      if (ix86_cmodel != CM_KERNEL)
21337         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21338      else
21339         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21340   }
21341   [(set_attr "type" "multi")])
21342
21343 (define_expand "stack_protect_test"
21344   [(match_operand 0 "memory_operand" "")
21345    (match_operand 1 "memory_operand" "")
21346    (match_operand 2 "" "")]
21347   ""
21348 {
21349   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21350   ix86_compare_op0 = operands[0];
21351   ix86_compare_op1 = operands[1];
21352   ix86_compare_emitted = flags;
21353
21354 #ifdef TARGET_THREAD_SSP_OFFSET
21355   if (TARGET_64BIT)
21356     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21357                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21358   else
21359     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21360                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21361 #else
21362   if (TARGET_64BIT)
21363     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21364   else
21365     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21366 #endif
21367   emit_jump_insn (gen_beq (operands[2]));
21368   DONE;
21369 })
21370
21371 (define_insn "stack_protect_test_si"
21372   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21373         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21374                      (match_operand:SI 2 "memory_operand" "m")]
21375                     UNSPEC_SP_TEST))
21376    (clobber (match_scratch:SI 3 "=&r"))]
21377   ""
21378   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21379   [(set_attr "type" "multi")])
21380
21381 (define_insn "stack_protect_test_di"
21382   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21383         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21384                      (match_operand:DI 2 "memory_operand" "m")]
21385                     UNSPEC_SP_TEST))
21386    (clobber (match_scratch:DI 3 "=&r"))]
21387   "TARGET_64BIT"
21388   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21389   [(set_attr "type" "multi")])
21390
21391 (define_insn "stack_tls_protect_test_si"
21392   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21393         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21394                      (match_operand:SI 2 "const_int_operand" "i")]
21395                     UNSPEC_SP_TLS_TEST))
21396    (clobber (match_scratch:SI 3 "=r"))]
21397   ""
21398   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21399   [(set_attr "type" "multi")])
21400
21401 (define_insn "stack_tls_protect_test_di"
21402   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21403         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21404                      (match_operand:DI 2 "const_int_operand" "i")]
21405                     UNSPEC_SP_TLS_TEST))
21406    (clobber (match_scratch:DI 3 "=r"))]
21407   "TARGET_64BIT"
21408   {
21409      /* The kernel uses a different segment register for performance reasons; a
21410         system call would not have to trash the userspace segment register,
21411         which would be expensive */
21412      if (ix86_cmodel != CM_KERNEL)
21413         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21414      else
21415         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21416   }
21417   [(set_attr "type" "multi")])
21418
21419 (define_mode_iterator CRC32MODE [QI HI SI])
21420 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21421 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21422
21423 (define_insn "sse4_2_crc32<mode>"
21424   [(set (match_operand:SI 0 "register_operand" "=r")
21425         (unspec:SI
21426           [(match_operand:SI 1 "register_operand" "0")
21427            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21428           UNSPEC_CRC32))]
21429   "TARGET_SSE4_2"
21430   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21431   [(set_attr "type" "sselog1")
21432    (set_attr "prefix_rep" "1")
21433    (set_attr "prefix_extra" "1")
21434    (set_attr "mode" "SI")])
21435
21436 (define_insn "sse4_2_crc32di"
21437   [(set (match_operand:DI 0 "register_operand" "=r")
21438         (unspec:DI
21439           [(match_operand:DI 1 "register_operand" "0")
21440            (match_operand:DI 2 "nonimmediate_operand" "rm")]
21441           UNSPEC_CRC32))]
21442   "TARGET_SSE4_2 && TARGET_64BIT"
21443   "crc32q\t{%2, %0|%0, %2}"
21444   [(set_attr "type" "sselog1")
21445    (set_attr "prefix_rep" "1")
21446    (set_attr "prefix_extra" "1")
21447    (set_attr "mode" "DI")])
21448
21449 (include "mmx.md")
21450 (include "sse.md")
21451 (include "sync.md")