OSDN Git Service

* config/i386/i386.md
[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    ; For AES support
191    (UNSPEC_AESENC               159)
192    (UNSPEC_AESENCLAST           160)
193    (UNSPEC_AESDEC               161)
194    (UNSPEC_AESDECLAST           162)
195    (UNSPEC_AESIMC               163)
196    (UNSPEC_AESKEYGENASSIST      164)
197
198    ; For PCLMUL support
199    (UNSPEC_PCLMUL               165)
200   ])
201
202 (define_constants
203   [(UNSPECV_BLOCKAGE            0)
204    (UNSPECV_STACK_PROBE         1)
205    (UNSPECV_EMMS                2)
206    (UNSPECV_LDMXCSR             3)
207    (UNSPECV_STMXCSR             4)
208    (UNSPECV_FEMMS               5)
209    (UNSPECV_CLFLUSH             6)
210    (UNSPECV_ALIGN               7)
211    (UNSPECV_MONITOR             8)
212    (UNSPECV_MWAIT               9)
213    (UNSPECV_CMPXCHG_1           10)
214    (UNSPECV_CMPXCHG_2           11)
215    (UNSPECV_XCHG                12)
216    (UNSPECV_LOCK                13)
217    (UNSPECV_PROLOGUE_USE        14)
218   ])
219
220 ;; Constants to represent pcomtrue/pcomfalse variants
221 (define_constants
222   [(PCOM_FALSE                  0)
223    (PCOM_TRUE                   1)
224    (COM_FALSE_S                 2)
225    (COM_FALSE_P                 3)
226    (COM_TRUE_S                  4)
227    (COM_TRUE_P                  5)
228   ])
229
230 ;; Registers by name.
231 (define_constants
232   [(AX_REG                       0)
233    (DX_REG                       1)
234    (CX_REG                       2)
235    (SI_REG                       4)
236    (DI_REG                       5)
237    (BP_REG                       6)
238    (SP_REG                       7)
239    (FLAGS_REG                   17)
240    (FPSR_REG                    18)
241    (FPCR_REG                    19)
242    (R10_REG                     39)
243    (R11_REG                     40)
244   ])
245
246 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
247 ;; from i386.c.
248
249 ;; In C guard expressions, put expressions which may be compile-time
250 ;; constants first.  This allows for better optimization.  For
251 ;; example, write "TARGET_64BIT && reload_completed", not
252 ;; "reload_completed && TARGET_64BIT".
253
254 \f
255 ;; Processor type.  This attribute must exactly match the processor_type
256 ;; enumeration in i386.h.
257 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
258                     nocona,core2,generic32,generic64,amdfam10"
259   (const (symbol_ref "ix86_tune")))
260
261 ;; A basic instruction type.  Refinements due to arguments to be
262 ;; provided in other attributes.
263 (define_attr "type"
264   "other,multi,
265    alu,alu1,negnot,imov,imovx,lea,
266    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
267    icmp,test,ibr,setcc,icmov,
268    push,pop,call,callv,leave,
269    str,bitmanip,
270    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
271    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
272    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
273    ssemuladd,sse4arg,
274    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
275   (const_string "other"))
276
277 ;; Main data type used by the insn
278 (define_attr "mode"
279   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
280   (const_string "unknown"))
281
282 ;; The CPU unit operations uses.
283 (define_attr "unit" "integer,i387,sse,mmx,unknown"
284   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
285            (const_string "i387")
286          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
287                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
288                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
289            (const_string "sse")
290          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
291            (const_string "mmx")
292          (eq_attr "type" "other")
293            (const_string "unknown")]
294          (const_string "integer")))
295
296 ;; The (bounding maximum) length of an instruction immediate.
297 (define_attr "length_immediate" ""
298   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
299                           bitmanip")
300            (const_int 0)
301          (eq_attr "unit" "i387,sse,mmx")
302            (const_int 0)
303          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
304                           imul,icmp,push,pop")
305            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
306          (eq_attr "type" "imov,test")
307            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
308          (eq_attr "type" "call")
309            (if_then_else (match_operand 0 "constant_call_address_operand" "")
310              (const_int 4)
311              (const_int 0))
312          (eq_attr "type" "callv")
313            (if_then_else (match_operand 1 "constant_call_address_operand" "")
314              (const_int 4)
315              (const_int 0))
316          ;; We don't know the size before shorten_branches.  Expect
317          ;; the instruction to fit for better scheduling.
318          (eq_attr "type" "ibr")
319            (const_int 1)
320          ]
321          (symbol_ref "/* Update immediate_length and other attributes! */
322                       gcc_unreachable (),1")))
323
324 ;; The (bounding maximum) length of an instruction address.
325 (define_attr "length_address" ""
326   (cond [(eq_attr "type" "str,other,multi,fxch")
327            (const_int 0)
328          (and (eq_attr "type" "call")
329               (match_operand 0 "constant_call_address_operand" ""))
330              (const_int 0)
331          (and (eq_attr "type" "callv")
332               (match_operand 1 "constant_call_address_operand" ""))
333              (const_int 0)
334          ]
335          (symbol_ref "ix86_attr_length_address_default (insn)")))
336
337 ;; Set when length prefix is used.
338 (define_attr "prefix_data16" ""
339   (if_then_else (ior (eq_attr "mode" "HI")
340                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
341     (const_int 1)
342     (const_int 0)))
343
344 ;; Set when string REP prefix is used.
345 (define_attr "prefix_rep" ""
346   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
347     (const_int 1)
348     (const_int 0)))
349
350 ;; Set when 0f opcode prefix is used.
351 (define_attr "prefix_0f" ""
352   (if_then_else
353     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
354          (eq_attr "unit" "sse,mmx"))
355     (const_int 1)
356     (const_int 0)))
357
358 ;; Set when REX opcode prefix is used.
359 (define_attr "prefix_rex" ""
360   (cond [(and (eq_attr "mode" "DI")
361               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
362            (const_int 1)
363          (and (eq_attr "mode" "QI")
364               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
365                   (const_int 0)))
366            (const_int 1)
367          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
368              (const_int 0))
369            (const_int 1)
370         ]
371         (const_int 0)))
372
373 ;; There are also additional prefixes in SSSE3.
374 (define_attr "prefix_extra" "" (const_int 0))
375
376 ;; Set when modrm byte is used.
377 (define_attr "modrm" ""
378   (cond [(eq_attr "type" "str,leave")
379            (const_int 0)
380          (eq_attr "unit" "i387")
381            (const_int 0)
382          (and (eq_attr "type" "incdec")
383               (ior (match_operand:SI 1 "register_operand" "")
384                    (match_operand:HI 1 "register_operand" "")))
385            (const_int 0)
386          (and (eq_attr "type" "push")
387               (not (match_operand 1 "memory_operand" "")))
388            (const_int 0)
389          (and (eq_attr "type" "pop")
390               (not (match_operand 0 "memory_operand" "")))
391            (const_int 0)
392          (and (eq_attr "type" "imov")
393               (ior (and (match_operand 0 "register_operand" "")
394                         (match_operand 1 "immediate_operand" ""))
395                    (ior (and (match_operand 0 "ax_reg_operand" "")
396                              (match_operand 1 "memory_displacement_only_operand" ""))
397                         (and (match_operand 0 "memory_displacement_only_operand" "")
398                              (match_operand 1 "ax_reg_operand" "")))))
399            (const_int 0)
400          (and (eq_attr "type" "call")
401               (match_operand 0 "constant_call_address_operand" ""))
402              (const_int 0)
403          (and (eq_attr "type" "callv")
404               (match_operand 1 "constant_call_address_operand" ""))
405              (const_int 0)
406          ]
407          (const_int 1)))
408
409 ;; The (bounding maximum) length of an instruction in bytes.
410 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
411 ;; Later we may want to split them and compute proper length as for
412 ;; other insns.
413 (define_attr "length" ""
414   (cond [(eq_attr "type" "other,multi,fistp,frndint")
415            (const_int 16)
416          (eq_attr "type" "fcmp")
417            (const_int 4)
418          (eq_attr "unit" "i387")
419            (plus (const_int 2)
420                  (plus (attr "prefix_data16")
421                        (attr "length_address")))]
422          (plus (plus (attr "modrm")
423                      (plus (attr "prefix_0f")
424                            (plus (attr "prefix_rex")
425                                  (plus (attr "prefix_extra")
426                                        (const_int 1)))))
427                (plus (attr "prefix_rep")
428                      (plus (attr "prefix_data16")
429                            (plus (attr "length_immediate")
430                                  (attr "length_address")))))))
431
432 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
433 ;; `store' if there is a simple memory reference therein, or `unknown'
434 ;; if the instruction is complex.
435
436 (define_attr "memory" "none,load,store,both,unknown"
437   (cond [(eq_attr "type" "other,multi,str")
438            (const_string "unknown")
439          (eq_attr "type" "lea,fcmov,fpspc")
440            (const_string "none")
441          (eq_attr "type" "fistp,leave")
442            (const_string "both")
443          (eq_attr "type" "frndint")
444            (const_string "load")
445          (eq_attr "type" "push")
446            (if_then_else (match_operand 1 "memory_operand" "")
447              (const_string "both")
448              (const_string "store"))
449          (eq_attr "type" "pop")
450            (if_then_else (match_operand 0 "memory_operand" "")
451              (const_string "both")
452              (const_string "load"))
453          (eq_attr "type" "setcc")
454            (if_then_else (match_operand 0 "memory_operand" "")
455              (const_string "store")
456              (const_string "none"))
457          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
458            (if_then_else (ior (match_operand 0 "memory_operand" "")
459                               (match_operand 1 "memory_operand" ""))
460              (const_string "load")
461              (const_string "none"))
462          (eq_attr "type" "ibr")
463            (if_then_else (match_operand 0 "memory_operand" "")
464              (const_string "load")
465              (const_string "none"))
466          (eq_attr "type" "call")
467            (if_then_else (match_operand 0 "constant_call_address_operand" "")
468              (const_string "none")
469              (const_string "load"))
470          (eq_attr "type" "callv")
471            (if_then_else (match_operand 1 "constant_call_address_operand" "")
472              (const_string "none")
473              (const_string "load"))
474          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
475               (match_operand 1 "memory_operand" ""))
476            (const_string "both")
477          (and (match_operand 0 "memory_operand" "")
478               (match_operand 1 "memory_operand" ""))
479            (const_string "both")
480          (match_operand 0 "memory_operand" "")
481            (const_string "store")
482          (match_operand 1 "memory_operand" "")
483            (const_string "load")
484          (and (eq_attr "type"
485                  "!alu1,negnot,ishift1,
486                    imov,imovx,icmp,test,bitmanip,
487                    fmov,fcmp,fsgn,
488                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
489                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
490               (match_operand 2 "memory_operand" ""))
491            (const_string "load")
492          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
493               (match_operand 3 "memory_operand" ""))
494            (const_string "load")
495         ]
496         (const_string "none")))
497
498 ;; Indicates if an instruction has both an immediate and a displacement.
499
500 (define_attr "imm_disp" "false,true,unknown"
501   (cond [(eq_attr "type" "other,multi")
502            (const_string "unknown")
503          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
504               (and (match_operand 0 "memory_displacement_operand" "")
505                    (match_operand 1 "immediate_operand" "")))
506            (const_string "true")
507          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
508               (and (match_operand 0 "memory_displacement_operand" "")
509                    (match_operand 2 "immediate_operand" "")))
510            (const_string "true")
511         ]
512         (const_string "false")))
513
514 ;; Indicates if an FP operation has an integer source.
515
516 (define_attr "fp_int_src" "false,true"
517   (const_string "false"))
518
519 ;; Defines rounding mode of an FP operation.
520
521 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
522   (const_string "any"))
523
524 ;; Describe a user's asm statement.
525 (define_asm_attributes
526   [(set_attr "length" "128")
527    (set_attr "type" "multi")])
528
529 ;; All integer comparison codes.
530 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
531
532 ;; All floating-point comparison codes.
533 (define_code_iterator fp_cond [unordered ordered
534                                uneq unge ungt unle unlt ltgt ])
535
536 (define_code_iterator plusminus [plus minus])
537
538 ;; Base name for define_insn and insn mnemonic.
539 (define_code_attr addsub [(plus "add") (minus "sub")])
540
541 ;; Mark commutative operators as such in constraints.
542 (define_code_attr comm [(plus "%") (minus "")])
543
544 ;; Mapping of signed max and min
545 (define_code_iterator smaxmin [smax smin])
546
547 ;; Mapping of unsigned max and min
548 (define_code_iterator umaxmin [umax umin])
549
550 ;; Base name for integer and FP insn mnemonic
551 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
552                                  (umax "maxu") (umin "minu")])
553 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
554
555 ;; Mapping of parallel logic operators
556 (define_code_iterator plogic [and ior xor])
557
558 ;; Base name for insn mnemonic.
559 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
560
561 ;; Mapping of abs neg operators
562 (define_code_iterator absneg [abs neg])
563
564 ;; Base name for x87 insn mnemonic.
565 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
566
567 ;; All single word integer modes.
568 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
569
570 ;; Instruction suffix for integer modes.
571 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
572
573 ;; Register class for integer modes.
574 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
575
576 ;; Immediate operand constraint for integer modes.
577 (define_mode_attr i [(QI "i") (HI "i") (SI "i") (DI "e")])
578
579 ;; General operand predicate for integer modes.
580 (define_mode_attr general_operand
581         [(QI "general_operand")
582          (HI "general_operand")
583          (SI "general_operand")
584          (DI "x86_64_general_operand")])
585
586 ;; SSE and x87 SFmode and DFmode floating point modes
587 (define_mode_iterator MODEF [SF DF])
588
589 ;; All x87 floating point modes
590 (define_mode_iterator X87MODEF [SF DF XF])
591
592 ;; All integer modes handled by x87 fisttp operator.
593 (define_mode_iterator X87MODEI [HI SI DI])
594
595 ;; All integer modes handled by integer x87 operators.
596 (define_mode_iterator X87MODEI12 [HI SI])
597
598 ;; All integer modes handled by SSE cvtts?2si* operators.
599 (define_mode_iterator SSEMODEI24 [SI DI])
600
601 ;; SSE asm suffix for floating point modes
602 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
603
604 ;; SSE vector mode corresponding to a scalar mode
605 (define_mode_attr ssevecmode
606   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
607
608 ;; Instruction suffix for REX 64bit operators.
609 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
610 \f
611 ;; Scheduling descriptions
612
613 (include "pentium.md")
614 (include "ppro.md")
615 (include "k6.md")
616 (include "athlon.md")
617 (include "geode.md")
618
619 \f
620 ;; Operand and operator predicates and constraints
621
622 (include "predicates.md")
623 (include "constraints.md")
624
625 \f
626 ;; Compare instructions.
627
628 ;; All compare insns have expanders that save the operands away without
629 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
630 ;; after the cmp) will actually emit the cmpM.
631
632 (define_expand "cmpti"
633   [(set (reg:CC FLAGS_REG)
634         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
635                     (match_operand:TI 1 "x86_64_general_operand" "")))]
636   "TARGET_64BIT"
637 {
638   if (MEM_P (operands[0]) && MEM_P (operands[1]))
639     operands[0] = force_reg (TImode, operands[0]);
640   ix86_compare_op0 = operands[0];
641   ix86_compare_op1 = operands[1];
642   DONE;
643 })
644
645 (define_expand "cmpdi"
646   [(set (reg:CC FLAGS_REG)
647         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
648                     (match_operand:DI 1 "x86_64_general_operand" "")))]
649   ""
650 {
651   if (MEM_P (operands[0]) && MEM_P (operands[1]))
652     operands[0] = force_reg (DImode, operands[0]);
653   ix86_compare_op0 = operands[0];
654   ix86_compare_op1 = operands[1];
655   DONE;
656 })
657
658 (define_expand "cmpsi"
659   [(set (reg:CC FLAGS_REG)
660         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
661                     (match_operand:SI 1 "general_operand" "")))]
662   ""
663 {
664   if (MEM_P (operands[0]) && MEM_P (operands[1]))
665     operands[0] = force_reg (SImode, operands[0]);
666   ix86_compare_op0 = operands[0];
667   ix86_compare_op1 = operands[1];
668   DONE;
669 })
670
671 (define_expand "cmphi"
672   [(set (reg:CC FLAGS_REG)
673         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
674                     (match_operand:HI 1 "general_operand" "")))]
675   ""
676 {
677   if (MEM_P (operands[0]) && MEM_P (operands[1]))
678     operands[0] = force_reg (HImode, operands[0]);
679   ix86_compare_op0 = operands[0];
680   ix86_compare_op1 = operands[1];
681   DONE;
682 })
683
684 (define_expand "cmpqi"
685   [(set (reg:CC FLAGS_REG)
686         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
687                     (match_operand:QI 1 "general_operand" "")))]
688   "TARGET_QIMODE_MATH"
689 {
690   if (MEM_P (operands[0]) && MEM_P (operands[1]))
691     operands[0] = force_reg (QImode, operands[0]);
692   ix86_compare_op0 = operands[0];
693   ix86_compare_op1 = operands[1];
694   DONE;
695 })
696
697 (define_insn "cmpdi_ccno_1_rex64"
698   [(set (reg FLAGS_REG)
699         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
700                  (match_operand:DI 1 "const0_operand" "n,n")))]
701   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
702   "@
703    test{q}\t%0, %0
704    cmp{q}\t{%1, %0|%0, %1}"
705   [(set_attr "type" "test,icmp")
706    (set_attr "length_immediate" "0,1")
707    (set_attr "mode" "DI")])
708
709 (define_insn "*cmpdi_minus_1_rex64"
710   [(set (reg FLAGS_REG)
711         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
712                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
713                  (const_int 0)))]
714   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
715   "cmp{q}\t{%1, %0|%0, %1}"
716   [(set_attr "type" "icmp")
717    (set_attr "mode" "DI")])
718
719 (define_expand "cmpdi_1_rex64"
720   [(set (reg:CC FLAGS_REG)
721         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
722                     (match_operand:DI 1 "general_operand" "")))]
723   "TARGET_64BIT"
724   "")
725
726 (define_insn "cmpdi_1_insn_rex64"
727   [(set (reg FLAGS_REG)
728         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
729                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
730   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
731   "cmp{q}\t{%1, %0|%0, %1}"
732   [(set_attr "type" "icmp")
733    (set_attr "mode" "DI")])
734
735
736 (define_insn "*cmpsi_ccno_1"
737   [(set (reg FLAGS_REG)
738         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
739                  (match_operand:SI 1 "const0_operand" "n,n")))]
740   "ix86_match_ccmode (insn, CCNOmode)"
741   "@
742    test{l}\t%0, %0
743    cmp{l}\t{%1, %0|%0, %1}"
744   [(set_attr "type" "test,icmp")
745    (set_attr "length_immediate" "0,1")
746    (set_attr "mode" "SI")])
747
748 (define_insn "*cmpsi_minus_1"
749   [(set (reg FLAGS_REG)
750         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
751                            (match_operand:SI 1 "general_operand" "ri,mr"))
752                  (const_int 0)))]
753   "ix86_match_ccmode (insn, CCGOCmode)"
754   "cmp{l}\t{%1, %0|%0, %1}"
755   [(set_attr "type" "icmp")
756    (set_attr "mode" "SI")])
757
758 (define_expand "cmpsi_1"
759   [(set (reg:CC FLAGS_REG)
760         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
761                     (match_operand:SI 1 "general_operand" "")))]
762   ""
763   "")
764
765 (define_insn "*cmpsi_1_insn"
766   [(set (reg FLAGS_REG)
767         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
768                  (match_operand:SI 1 "general_operand" "ri,mr")))]
769   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
770     && ix86_match_ccmode (insn, CCmode)"
771   "cmp{l}\t{%1, %0|%0, %1}"
772   [(set_attr "type" "icmp")
773    (set_attr "mode" "SI")])
774
775 (define_insn "*cmphi_ccno_1"
776   [(set (reg FLAGS_REG)
777         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
778                  (match_operand:HI 1 "const0_operand" "n,n")))]
779   "ix86_match_ccmode (insn, CCNOmode)"
780   "@
781    test{w}\t%0, %0
782    cmp{w}\t{%1, %0|%0, %1}"
783   [(set_attr "type" "test,icmp")
784    (set_attr "length_immediate" "0,1")
785    (set_attr "mode" "HI")])
786
787 (define_insn "*cmphi_minus_1"
788   [(set (reg FLAGS_REG)
789         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
790                            (match_operand:HI 1 "general_operand" "ri,mr"))
791                  (const_int 0)))]
792   "ix86_match_ccmode (insn, CCGOCmode)"
793   "cmp{w}\t{%1, %0|%0, %1}"
794   [(set_attr "type" "icmp")
795    (set_attr "mode" "HI")])
796
797 (define_insn "*cmphi_1"
798   [(set (reg FLAGS_REG)
799         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
800                  (match_operand:HI 1 "general_operand" "ri,mr")))]
801   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
802    && ix86_match_ccmode (insn, CCmode)"
803   "cmp{w}\t{%1, %0|%0, %1}"
804   [(set_attr "type" "icmp")
805    (set_attr "mode" "HI")])
806
807 (define_insn "*cmpqi_ccno_1"
808   [(set (reg FLAGS_REG)
809         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
810                  (match_operand:QI 1 "const0_operand" "n,n")))]
811   "ix86_match_ccmode (insn, CCNOmode)"
812   "@
813    test{b}\t%0, %0
814    cmp{b}\t{$0, %0|%0, 0}"
815   [(set_attr "type" "test,icmp")
816    (set_attr "length_immediate" "0,1")
817    (set_attr "mode" "QI")])
818
819 (define_insn "*cmpqi_1"
820   [(set (reg FLAGS_REG)
821         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
822                  (match_operand:QI 1 "general_operand" "qi,mq")))]
823   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
824     && ix86_match_ccmode (insn, CCmode)"
825   "cmp{b}\t{%1, %0|%0, %1}"
826   [(set_attr "type" "icmp")
827    (set_attr "mode" "QI")])
828
829 (define_insn "*cmpqi_minus_1"
830   [(set (reg FLAGS_REG)
831         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
832                            (match_operand:QI 1 "general_operand" "qi,mq"))
833                  (const_int 0)))]
834   "ix86_match_ccmode (insn, CCGOCmode)"
835   "cmp{b}\t{%1, %0|%0, %1}"
836   [(set_attr "type" "icmp")
837    (set_attr "mode" "QI")])
838
839 (define_insn "*cmpqi_ext_1"
840   [(set (reg FLAGS_REG)
841         (compare
842           (match_operand:QI 0 "general_operand" "Qm")
843           (subreg:QI
844             (zero_extract:SI
845               (match_operand 1 "ext_register_operand" "Q")
846               (const_int 8)
847               (const_int 8)) 0)))]
848   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
849   "cmp{b}\t{%h1, %0|%0, %h1}"
850   [(set_attr "type" "icmp")
851    (set_attr "mode" "QI")])
852
853 (define_insn "*cmpqi_ext_1_rex64"
854   [(set (reg FLAGS_REG)
855         (compare
856           (match_operand:QI 0 "register_operand" "Q")
857           (subreg:QI
858             (zero_extract:SI
859               (match_operand 1 "ext_register_operand" "Q")
860               (const_int 8)
861               (const_int 8)) 0)))]
862   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
863   "cmp{b}\t{%h1, %0|%0, %h1}"
864   [(set_attr "type" "icmp")
865    (set_attr "mode" "QI")])
866
867 (define_insn "*cmpqi_ext_2"
868   [(set (reg FLAGS_REG)
869         (compare
870           (subreg:QI
871             (zero_extract:SI
872               (match_operand 0 "ext_register_operand" "Q")
873               (const_int 8)
874               (const_int 8)) 0)
875           (match_operand:QI 1 "const0_operand" "n")))]
876   "ix86_match_ccmode (insn, CCNOmode)"
877   "test{b}\t%h0, %h0"
878   [(set_attr "type" "test")
879    (set_attr "length_immediate" "0")
880    (set_attr "mode" "QI")])
881
882 (define_expand "cmpqi_ext_3"
883   [(set (reg:CC FLAGS_REG)
884         (compare:CC
885           (subreg:QI
886             (zero_extract:SI
887               (match_operand 0 "ext_register_operand" "")
888               (const_int 8)
889               (const_int 8)) 0)
890           (match_operand:QI 1 "general_operand" "")))]
891   ""
892   "")
893
894 (define_insn "cmpqi_ext_3_insn"
895   [(set (reg FLAGS_REG)
896         (compare
897           (subreg:QI
898             (zero_extract:SI
899               (match_operand 0 "ext_register_operand" "Q")
900               (const_int 8)
901               (const_int 8)) 0)
902           (match_operand:QI 1 "general_operand" "Qmn")))]
903   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
904   "cmp{b}\t{%1, %h0|%h0, %1}"
905   [(set_attr "type" "icmp")
906    (set_attr "mode" "QI")])
907
908 (define_insn "cmpqi_ext_3_insn_rex64"
909   [(set (reg FLAGS_REG)
910         (compare
911           (subreg:QI
912             (zero_extract:SI
913               (match_operand 0 "ext_register_operand" "Q")
914               (const_int 8)
915               (const_int 8)) 0)
916           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
917   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
918   "cmp{b}\t{%1, %h0|%h0, %1}"
919   [(set_attr "type" "icmp")
920    (set_attr "mode" "QI")])
921
922 (define_insn "*cmpqi_ext_4"
923   [(set (reg FLAGS_REG)
924         (compare
925           (subreg:QI
926             (zero_extract:SI
927               (match_operand 0 "ext_register_operand" "Q")
928               (const_int 8)
929               (const_int 8)) 0)
930           (subreg:QI
931             (zero_extract:SI
932               (match_operand 1 "ext_register_operand" "Q")
933               (const_int 8)
934               (const_int 8)) 0)))]
935   "ix86_match_ccmode (insn, CCmode)"
936   "cmp{b}\t{%h1, %h0|%h0, %h1}"
937   [(set_attr "type" "icmp")
938    (set_attr "mode" "QI")])
939
940 ;; These implement float point compares.
941 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
942 ;; which would allow mix and match FP modes on the compares.  Which is what
943 ;; the old patterns did, but with many more of them.
944
945 (define_expand "cmpxf"
946   [(set (reg:CC FLAGS_REG)
947         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
948                     (match_operand:XF 1 "nonmemory_operand" "")))]
949   "TARGET_80387"
950 {
951   ix86_compare_op0 = operands[0];
952   ix86_compare_op1 = operands[1];
953   DONE;
954 })
955
956 (define_expand "cmp<mode>"
957   [(set (reg:CC FLAGS_REG)
958         (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
959                     (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
960   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
961 {
962   ix86_compare_op0 = operands[0];
963   ix86_compare_op1 = operands[1];
964   DONE;
965 })
966
967 ;; FP compares, step 1:
968 ;; Set the FP condition codes.
969 ;;
970 ;; CCFPmode     compare with exceptions
971 ;; CCFPUmode    compare with no exceptions
972
973 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
974 ;; used to manage the reg stack popping would not be preserved.
975
976 (define_insn "*cmpfp_0"
977   [(set (match_operand:HI 0 "register_operand" "=a")
978         (unspec:HI
979           [(compare:CCFP
980              (match_operand 1 "register_operand" "f")
981              (match_operand 2 "const0_operand" "X"))]
982         UNSPEC_FNSTSW))]
983   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
984    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
985   "* return output_fp_compare (insn, operands, 0, 0);"
986   [(set_attr "type" "multi")
987    (set_attr "unit" "i387")
988    (set (attr "mode")
989      (cond [(match_operand:SF 1 "" "")
990               (const_string "SF")
991             (match_operand:DF 1 "" "")
992               (const_string "DF")
993            ]
994            (const_string "XF")))])
995
996 (define_insn_and_split "*cmpfp_0_cc"
997   [(set (reg:CCFP FLAGS_REG)
998         (compare:CCFP
999           (match_operand 1 "register_operand" "f")
1000           (match_operand 2 "const0_operand" "X")))
1001    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1002   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1003    && TARGET_SAHF && !TARGET_CMOVE
1004    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1005   "#"
1006   "&& reload_completed"
1007   [(set (match_dup 0)
1008         (unspec:HI
1009           [(compare:CCFP (match_dup 1)(match_dup 2))]
1010         UNSPEC_FNSTSW))
1011    (set (reg:CC FLAGS_REG)
1012         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1013   ""
1014   [(set_attr "type" "multi")
1015    (set_attr "unit" "i387")
1016    (set (attr "mode")
1017      (cond [(match_operand:SF 1 "" "")
1018               (const_string "SF")
1019             (match_operand:DF 1 "" "")
1020               (const_string "DF")
1021            ]
1022            (const_string "XF")))])
1023
1024 (define_insn "*cmpfp_xf"
1025   [(set (match_operand:HI 0 "register_operand" "=a")
1026         (unspec:HI
1027           [(compare:CCFP
1028              (match_operand:XF 1 "register_operand" "f")
1029              (match_operand:XF 2 "register_operand" "f"))]
1030           UNSPEC_FNSTSW))]
1031   "TARGET_80387"
1032   "* return output_fp_compare (insn, operands, 0, 0);"
1033   [(set_attr "type" "multi")
1034    (set_attr "unit" "i387")
1035    (set_attr "mode" "XF")])
1036
1037 (define_insn_and_split "*cmpfp_xf_cc"
1038   [(set (reg:CCFP FLAGS_REG)
1039         (compare:CCFP
1040           (match_operand:XF 1 "register_operand" "f")
1041           (match_operand:XF 2 "register_operand" "f")))
1042    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1043   "TARGET_80387
1044    && TARGET_SAHF && !TARGET_CMOVE"
1045   "#"
1046   "&& reload_completed"
1047   [(set (match_dup 0)
1048         (unspec:HI
1049           [(compare:CCFP (match_dup 1)(match_dup 2))]
1050         UNSPEC_FNSTSW))
1051    (set (reg:CC FLAGS_REG)
1052         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1053   ""
1054   [(set_attr "type" "multi")
1055    (set_attr "unit" "i387")
1056    (set_attr "mode" "XF")])
1057
1058 (define_insn "*cmpfp_<mode>"
1059   [(set (match_operand:HI 0 "register_operand" "=a")
1060         (unspec:HI
1061           [(compare:CCFP
1062              (match_operand:MODEF 1 "register_operand" "f")
1063              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1064           UNSPEC_FNSTSW))]
1065   "TARGET_80387"
1066   "* return output_fp_compare (insn, operands, 0, 0);"
1067   [(set_attr "type" "multi")
1068    (set_attr "unit" "i387")
1069    (set_attr "mode" "<MODE>")])
1070
1071 (define_insn_and_split "*cmpfp_<mode>_cc"
1072   [(set (reg:CCFP FLAGS_REG)
1073         (compare:CCFP
1074           (match_operand:MODEF 1 "register_operand" "f")
1075           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1076    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1077   "TARGET_80387
1078    && TARGET_SAHF && !TARGET_CMOVE"
1079   "#"
1080   "&& reload_completed"
1081   [(set (match_dup 0)
1082         (unspec:HI
1083           [(compare:CCFP (match_dup 1)(match_dup 2))]
1084         UNSPEC_FNSTSW))
1085    (set (reg:CC FLAGS_REG)
1086         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1087   ""
1088   [(set_attr "type" "multi")
1089    (set_attr "unit" "i387")
1090    (set_attr "mode" "<MODE>")])
1091
1092 (define_insn "*cmpfp_u"
1093   [(set (match_operand:HI 0 "register_operand" "=a")
1094         (unspec:HI
1095           [(compare:CCFPU
1096              (match_operand 1 "register_operand" "f")
1097              (match_operand 2 "register_operand" "f"))]
1098           UNSPEC_FNSTSW))]
1099   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1100    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1101   "* return output_fp_compare (insn, operands, 0, 1);"
1102   [(set_attr "type" "multi")
1103    (set_attr "unit" "i387")
1104    (set (attr "mode")
1105      (cond [(match_operand:SF 1 "" "")
1106               (const_string "SF")
1107             (match_operand:DF 1 "" "")
1108               (const_string "DF")
1109            ]
1110            (const_string "XF")))])
1111
1112 (define_insn_and_split "*cmpfp_u_cc"
1113   [(set (reg:CCFPU FLAGS_REG)
1114         (compare:CCFPU
1115           (match_operand 1 "register_operand" "f")
1116           (match_operand 2 "register_operand" "f")))
1117    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1118   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1119    && TARGET_SAHF && !TARGET_CMOVE
1120    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1121   "#"
1122   "&& reload_completed"
1123   [(set (match_dup 0)
1124         (unspec:HI
1125           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1126         UNSPEC_FNSTSW))
1127    (set (reg:CC FLAGS_REG)
1128         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1129   ""
1130   [(set_attr "type" "multi")
1131    (set_attr "unit" "i387")
1132    (set (attr "mode")
1133      (cond [(match_operand:SF 1 "" "")
1134               (const_string "SF")
1135             (match_operand:DF 1 "" "")
1136               (const_string "DF")
1137            ]
1138            (const_string "XF")))])
1139
1140 (define_insn "*cmpfp_<mode>"
1141   [(set (match_operand:HI 0 "register_operand" "=a")
1142         (unspec:HI
1143           [(compare:CCFP
1144              (match_operand 1 "register_operand" "f")
1145              (match_operator 3 "float_operator"
1146                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1147           UNSPEC_FNSTSW))]
1148   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1149    && TARGET_USE_<MODE>MODE_FIOP
1150    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1151   "* return output_fp_compare (insn, operands, 0, 0);"
1152   [(set_attr "type" "multi")
1153    (set_attr "unit" "i387")
1154    (set_attr "fp_int_src" "true")
1155    (set_attr "mode" "<MODE>")])
1156
1157 (define_insn_and_split "*cmpfp_<mode>_cc"
1158   [(set (reg:CCFP FLAGS_REG)
1159         (compare:CCFP
1160           (match_operand 1 "register_operand" "f")
1161           (match_operator 3 "float_operator"
1162             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1163    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1164   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1165    && TARGET_SAHF && !TARGET_CMOVE
1166    && TARGET_USE_<MODE>MODE_FIOP
1167    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1168   "#"
1169   "&& reload_completed"
1170   [(set (match_dup 0)
1171         (unspec:HI
1172           [(compare:CCFP
1173              (match_dup 1)
1174              (match_op_dup 3 [(match_dup 2)]))]
1175         UNSPEC_FNSTSW))
1176    (set (reg:CC FLAGS_REG)
1177         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1178   ""
1179   [(set_attr "type" "multi")
1180    (set_attr "unit" "i387")
1181    (set_attr "fp_int_src" "true")
1182    (set_attr "mode" "<MODE>")])
1183
1184 ;; FP compares, step 2
1185 ;; Move the fpsw to ax.
1186
1187 (define_insn "x86_fnstsw_1"
1188   [(set (match_operand:HI 0 "register_operand" "=a")
1189         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1190   "TARGET_80387"
1191   "fnstsw\t%0"
1192   [(set_attr "length" "2")
1193    (set_attr "mode" "SI")
1194    (set_attr "unit" "i387")])
1195
1196 ;; FP compares, step 3
1197 ;; Get ax into flags, general case.
1198
1199 (define_insn "x86_sahf_1"
1200   [(set (reg:CC FLAGS_REG)
1201         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1202                    UNSPEC_SAHF))]
1203   "TARGET_SAHF"
1204 {
1205 #ifdef HAVE_AS_IX86_SAHF
1206   return "sahf";
1207 #else
1208   return ".byte\t0x9e";
1209 #endif
1210 }
1211   [(set_attr "length" "1")
1212    (set_attr "athlon_decode" "vector")
1213    (set_attr "amdfam10_decode" "direct")
1214    (set_attr "mode" "SI")])
1215
1216 ;; Pentium Pro can do steps 1 through 3 in one go.
1217 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1218 (define_insn "*cmpfp_i_mixed"
1219   [(set (reg:CCFP FLAGS_REG)
1220         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1221                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1222   "TARGET_MIX_SSE_I387
1223    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1224    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1225   "* return output_fp_compare (insn, operands, 1, 0);"
1226   [(set_attr "type" "fcmp,ssecomi")
1227    (set (attr "mode")
1228      (if_then_else (match_operand:SF 1 "" "")
1229         (const_string "SF")
1230         (const_string "DF")))
1231    (set_attr "athlon_decode" "vector")
1232    (set_attr "amdfam10_decode" "direct")])
1233
1234 (define_insn "*cmpfp_i_sse"
1235   [(set (reg:CCFP FLAGS_REG)
1236         (compare:CCFP (match_operand 0 "register_operand" "x")
1237                       (match_operand 1 "nonimmediate_operand" "xm")))]
1238   "TARGET_SSE_MATH
1239    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1240    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1241   "* return output_fp_compare (insn, operands, 1, 0);"
1242   [(set_attr "type" "ssecomi")
1243    (set (attr "mode")
1244      (if_then_else (match_operand:SF 1 "" "")
1245         (const_string "SF")
1246         (const_string "DF")))
1247    (set_attr "athlon_decode" "vector")
1248    (set_attr "amdfam10_decode" "direct")])
1249
1250 (define_insn "*cmpfp_i_i387"
1251   [(set (reg:CCFP FLAGS_REG)
1252         (compare:CCFP (match_operand 0 "register_operand" "f")
1253                       (match_operand 1 "register_operand" "f")))]
1254   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1255    && TARGET_CMOVE
1256    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1257    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1258   "* return output_fp_compare (insn, operands, 1, 0);"
1259   [(set_attr "type" "fcmp")
1260    (set (attr "mode")
1261      (cond [(match_operand:SF 1 "" "")
1262               (const_string "SF")
1263             (match_operand:DF 1 "" "")
1264               (const_string "DF")
1265            ]
1266            (const_string "XF")))
1267    (set_attr "athlon_decode" "vector")
1268    (set_attr "amdfam10_decode" "direct")])
1269
1270 (define_insn "*cmpfp_iu_mixed"
1271   [(set (reg:CCFPU FLAGS_REG)
1272         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1273                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1274   "TARGET_MIX_SSE_I387
1275    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1276    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1277   "* return output_fp_compare (insn, operands, 1, 1);"
1278   [(set_attr "type" "fcmp,ssecomi")
1279    (set (attr "mode")
1280      (if_then_else (match_operand:SF 1 "" "")
1281         (const_string "SF")
1282         (const_string "DF")))
1283    (set_attr "athlon_decode" "vector")
1284    (set_attr "amdfam10_decode" "direct")])
1285
1286 (define_insn "*cmpfp_iu_sse"
1287   [(set (reg:CCFPU FLAGS_REG)
1288         (compare:CCFPU (match_operand 0 "register_operand" "x")
1289                        (match_operand 1 "nonimmediate_operand" "xm")))]
1290   "TARGET_SSE_MATH
1291    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1292    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1293   "* return output_fp_compare (insn, operands, 1, 1);"
1294   [(set_attr "type" "ssecomi")
1295    (set (attr "mode")
1296      (if_then_else (match_operand:SF 1 "" "")
1297         (const_string "SF")
1298         (const_string "DF")))
1299    (set_attr "athlon_decode" "vector")
1300    (set_attr "amdfam10_decode" "direct")])
1301
1302 (define_insn "*cmpfp_iu_387"
1303   [(set (reg:CCFPU FLAGS_REG)
1304         (compare:CCFPU (match_operand 0 "register_operand" "f")
1305                        (match_operand 1 "register_operand" "f")))]
1306   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1307    && TARGET_CMOVE
1308    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1309    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1310   "* return output_fp_compare (insn, operands, 1, 1);"
1311   [(set_attr "type" "fcmp")
1312    (set (attr "mode")
1313      (cond [(match_operand:SF 1 "" "")
1314               (const_string "SF")
1315             (match_operand:DF 1 "" "")
1316               (const_string "DF")
1317            ]
1318            (const_string "XF")))
1319    (set_attr "athlon_decode" "vector")
1320    (set_attr "amdfam10_decode" "direct")])
1321 \f
1322 ;; Move instructions.
1323
1324 ;; General case of fullword move.
1325
1326 (define_expand "movsi"
1327   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1328         (match_operand:SI 1 "general_operand" ""))]
1329   ""
1330   "ix86_expand_move (SImode, operands); DONE;")
1331
1332 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1333 ;; general_operand.
1334 ;;
1335 ;; %%% We don't use a post-inc memory reference because x86 is not a
1336 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1337 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1338 ;; targets without our curiosities, and it is just as easy to represent
1339 ;; this differently.
1340
1341 (define_insn "*pushsi2"
1342   [(set (match_operand:SI 0 "push_operand" "=<")
1343         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1344   "!TARGET_64BIT"
1345   "push{l}\t%1"
1346   [(set_attr "type" "push")
1347    (set_attr "mode" "SI")])
1348
1349 ;; For 64BIT abi we always round up to 8 bytes.
1350 (define_insn "*pushsi2_rex64"
1351   [(set (match_operand:SI 0 "push_operand" "=X")
1352         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1353   "TARGET_64BIT"
1354   "push{q}\t%q1"
1355   [(set_attr "type" "push")
1356    (set_attr "mode" "SI")])
1357
1358 (define_insn "*pushsi2_prologue"
1359   [(set (match_operand:SI 0 "push_operand" "=<")
1360         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1361    (clobber (mem:BLK (scratch)))]
1362   "!TARGET_64BIT"
1363   "push{l}\t%1"
1364   [(set_attr "type" "push")
1365    (set_attr "mode" "SI")])
1366
1367 (define_insn "*popsi1_epilogue"
1368   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1369         (mem:SI (reg:SI SP_REG)))
1370    (set (reg:SI SP_REG)
1371         (plus:SI (reg:SI SP_REG) (const_int 4)))
1372    (clobber (mem:BLK (scratch)))]
1373   "!TARGET_64BIT"
1374   "pop{l}\t%0"
1375   [(set_attr "type" "pop")
1376    (set_attr "mode" "SI")])
1377
1378 (define_insn "popsi1"
1379   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1380         (mem:SI (reg:SI SP_REG)))
1381    (set (reg:SI SP_REG)
1382         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1383   "!TARGET_64BIT"
1384   "pop{l}\t%0"
1385   [(set_attr "type" "pop")
1386    (set_attr "mode" "SI")])
1387
1388 (define_insn "*movsi_xor"
1389   [(set (match_operand:SI 0 "register_operand" "=r")
1390         (match_operand:SI 1 "const0_operand" "i"))
1391    (clobber (reg:CC FLAGS_REG))]
1392   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1393   "xor{l}\t%0, %0"
1394   [(set_attr "type" "alu1")
1395    (set_attr "mode" "SI")
1396    (set_attr "length_immediate" "0")])
1397
1398 (define_insn "*movsi_or"
1399   [(set (match_operand:SI 0 "register_operand" "=r")
1400         (match_operand:SI 1 "immediate_operand" "i"))
1401    (clobber (reg:CC FLAGS_REG))]
1402   "reload_completed
1403    && operands[1] == constm1_rtx
1404    && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1405 {
1406   operands[1] = constm1_rtx;
1407   return "or{l}\t{%1, %0|%0, %1}";
1408 }
1409   [(set_attr "type" "alu1")
1410    (set_attr "mode" "SI")
1411    (set_attr "length_immediate" "1")])
1412
1413 (define_insn "*movsi_1"
1414   [(set (match_operand:SI 0 "nonimmediate_operand"
1415                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1416         (match_operand:SI 1 "general_operand"
1417                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1418   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1419 {
1420   switch (get_attr_type (insn))
1421     {
1422     case TYPE_SSELOG1:
1423       if (get_attr_mode (insn) == MODE_TI)
1424         return "pxor\t%0, %0";
1425       return "xorps\t%0, %0";
1426
1427     case TYPE_SSEMOV:
1428       switch (get_attr_mode (insn))
1429         {
1430         case MODE_TI:
1431           return "movdqa\t{%1, %0|%0, %1}";
1432         case MODE_V4SF:
1433           return "movaps\t{%1, %0|%0, %1}";
1434         case MODE_SI:
1435           return "movd\t{%1, %0|%0, %1}";
1436         case MODE_SF:
1437           return "movss\t{%1, %0|%0, %1}";
1438         default:
1439           gcc_unreachable ();
1440         }
1441
1442     case TYPE_MMXADD:
1443       return "pxor\t%0, %0";
1444
1445     case TYPE_MMXMOV:
1446       if (get_attr_mode (insn) == MODE_DI)
1447         return "movq\t{%1, %0|%0, %1}";
1448       return "movd\t{%1, %0|%0, %1}";
1449
1450     case TYPE_LEA:
1451       return "lea{l}\t{%1, %0|%0, %1}";
1452
1453     default:
1454       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1455       return "mov{l}\t{%1, %0|%0, %1}";
1456     }
1457 }
1458   [(set (attr "type")
1459      (cond [(eq_attr "alternative" "2")
1460               (const_string "mmxadd")
1461             (eq_attr "alternative" "3,4,5")
1462               (const_string "mmxmov")
1463             (eq_attr "alternative" "6")
1464               (const_string "sselog1")
1465             (eq_attr "alternative" "7,8,9,10,11")
1466               (const_string "ssemov")
1467             (match_operand:DI 1 "pic_32bit_operand" "")
1468               (const_string "lea")
1469            ]
1470            (const_string "imov")))
1471    (set (attr "mode")
1472      (cond [(eq_attr "alternative" "2,3")
1473               (const_string "DI")
1474             (eq_attr "alternative" "6,7")
1475               (if_then_else
1476                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1477                 (const_string "V4SF")
1478                 (const_string "TI"))
1479             (and (eq_attr "alternative" "8,9,10,11")
1480                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1481               (const_string "SF")
1482            ]
1483            (const_string "SI")))])
1484
1485 ;; Stores and loads of ax to arbitrary constant address.
1486 ;; We fake an second form of instruction to force reload to load address
1487 ;; into register when rax is not available
1488 (define_insn "*movabssi_1_rex64"
1489   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1490         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1491   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1492   "@
1493    movabs{l}\t{%1, %P0|%P0, %1}
1494    mov{l}\t{%1, %a0|%a0, %1}"
1495   [(set_attr "type" "imov")
1496    (set_attr "modrm" "0,*")
1497    (set_attr "length_address" "8,0")
1498    (set_attr "length_immediate" "0,*")
1499    (set_attr "memory" "store")
1500    (set_attr "mode" "SI")])
1501
1502 (define_insn "*movabssi_2_rex64"
1503   [(set (match_operand:SI 0 "register_operand" "=a,r")
1504         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1505   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1506   "@
1507    movabs{l}\t{%P1, %0|%0, %P1}
1508    mov{l}\t{%a1, %0|%0, %a1}"
1509   [(set_attr "type" "imov")
1510    (set_attr "modrm" "0,*")
1511    (set_attr "length_address" "8,0")
1512    (set_attr "length_immediate" "0")
1513    (set_attr "memory" "load")
1514    (set_attr "mode" "SI")])
1515
1516 (define_insn "*swapsi"
1517   [(set (match_operand:SI 0 "register_operand" "+r")
1518         (match_operand:SI 1 "register_operand" "+r"))
1519    (set (match_dup 1)
1520         (match_dup 0))]
1521   ""
1522   "xchg{l}\t%1, %0"
1523   [(set_attr "type" "imov")
1524    (set_attr "mode" "SI")
1525    (set_attr "pent_pair" "np")
1526    (set_attr "athlon_decode" "vector")
1527    (set_attr "amdfam10_decode" "double")])
1528
1529 (define_expand "movhi"
1530   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1531         (match_operand:HI 1 "general_operand" ""))]
1532   ""
1533   "ix86_expand_move (HImode, operands); DONE;")
1534
1535 (define_insn "*pushhi2"
1536   [(set (match_operand:HI 0 "push_operand" "=X")
1537         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1538   "!TARGET_64BIT"
1539   "push{l}\t%k1"
1540   [(set_attr "type" "push")
1541    (set_attr "mode" "SI")])
1542
1543 ;; For 64BIT abi we always round up to 8 bytes.
1544 (define_insn "*pushhi2_rex64"
1545   [(set (match_operand:HI 0 "push_operand" "=X")
1546         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1547   "TARGET_64BIT"
1548   "push{q}\t%q1"
1549   [(set_attr "type" "push")
1550    (set_attr "mode" "DI")])
1551
1552 (define_insn "*movhi_1"
1553   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1554         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1555   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1556 {
1557   switch (get_attr_type (insn))
1558     {
1559     case TYPE_IMOVX:
1560       /* movzwl is faster than movw on p2 due to partial word stalls,
1561          though not as fast as an aligned movl.  */
1562       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1563     default:
1564       if (get_attr_mode (insn) == MODE_SI)
1565         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1566       else
1567         return "mov{w}\t{%1, %0|%0, %1}";
1568     }
1569 }
1570   [(set (attr "type")
1571      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1572               (const_string "imov")
1573             (and (eq_attr "alternative" "0")
1574                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1575                           (const_int 0))
1576                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1577                           (const_int 0))))
1578               (const_string "imov")
1579             (and (eq_attr "alternative" "1,2")
1580                  (match_operand:HI 1 "aligned_operand" ""))
1581               (const_string "imov")
1582             (and (ne (symbol_ref "TARGET_MOVX")
1583                      (const_int 0))
1584                  (eq_attr "alternative" "0,2"))
1585               (const_string "imovx")
1586            ]
1587            (const_string "imov")))
1588     (set (attr "mode")
1589       (cond [(eq_attr "type" "imovx")
1590                (const_string "SI")
1591              (and (eq_attr "alternative" "1,2")
1592                   (match_operand:HI 1 "aligned_operand" ""))
1593                (const_string "SI")
1594              (and (eq_attr "alternative" "0")
1595                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1596                            (const_int 0))
1597                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1598                            (const_int 0))))
1599                (const_string "SI")
1600             ]
1601             (const_string "HI")))])
1602
1603 ;; Stores and loads of ax to arbitrary constant address.
1604 ;; We fake an second form of instruction to force reload to load address
1605 ;; into register when rax is not available
1606 (define_insn "*movabshi_1_rex64"
1607   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1608         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1609   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1610   "@
1611    movabs{w}\t{%1, %P0|%P0, %1}
1612    mov{w}\t{%1, %a0|%a0, %1}"
1613   [(set_attr "type" "imov")
1614    (set_attr "modrm" "0,*")
1615    (set_attr "length_address" "8,0")
1616    (set_attr "length_immediate" "0,*")
1617    (set_attr "memory" "store")
1618    (set_attr "mode" "HI")])
1619
1620 (define_insn "*movabshi_2_rex64"
1621   [(set (match_operand:HI 0 "register_operand" "=a,r")
1622         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1623   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1624   "@
1625    movabs{w}\t{%P1, %0|%0, %P1}
1626    mov{w}\t{%a1, %0|%0, %a1}"
1627   [(set_attr "type" "imov")
1628    (set_attr "modrm" "0,*")
1629    (set_attr "length_address" "8,0")
1630    (set_attr "length_immediate" "0")
1631    (set_attr "memory" "load")
1632    (set_attr "mode" "HI")])
1633
1634 (define_insn "*swaphi_1"
1635   [(set (match_operand:HI 0 "register_operand" "+r")
1636         (match_operand:HI 1 "register_operand" "+r"))
1637    (set (match_dup 1)
1638         (match_dup 0))]
1639   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1640   "xchg{l}\t%k1, %k0"
1641   [(set_attr "type" "imov")
1642    (set_attr "mode" "SI")
1643    (set_attr "pent_pair" "np")
1644    (set_attr "athlon_decode" "vector")
1645    (set_attr "amdfam10_decode" "double")])
1646
1647 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1648 (define_insn "*swaphi_2"
1649   [(set (match_operand:HI 0 "register_operand" "+r")
1650         (match_operand:HI 1 "register_operand" "+r"))
1651    (set (match_dup 1)
1652         (match_dup 0))]
1653   "TARGET_PARTIAL_REG_STALL"
1654   "xchg{w}\t%1, %0"
1655   [(set_attr "type" "imov")
1656    (set_attr "mode" "HI")
1657    (set_attr "pent_pair" "np")
1658    (set_attr "athlon_decode" "vector")])
1659
1660 (define_expand "movstricthi"
1661   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1662         (match_operand:HI 1 "general_operand" ""))]
1663   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1664 {
1665   /* Don't generate memory->memory moves, go through a register */
1666   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1667     operands[1] = force_reg (HImode, operands[1]);
1668 })
1669
1670 (define_insn "*movstricthi_1"
1671   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1672         (match_operand:HI 1 "general_operand" "rn,m"))]
1673   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1674    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1675   "mov{w}\t{%1, %0|%0, %1}"
1676   [(set_attr "type" "imov")
1677    (set_attr "mode" "HI")])
1678
1679 (define_insn "*movstricthi_xor"
1680   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1681         (match_operand:HI 1 "const0_operand" "i"))
1682    (clobber (reg:CC FLAGS_REG))]
1683   "reload_completed
1684    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1685   "xor{w}\t%0, %0"
1686   [(set_attr "type" "alu1")
1687    (set_attr "mode" "HI")
1688    (set_attr "length_immediate" "0")])
1689
1690 (define_expand "movqi"
1691   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1692         (match_operand:QI 1 "general_operand" ""))]
1693   ""
1694   "ix86_expand_move (QImode, operands); DONE;")
1695
1696 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1697 ;; "push a byte".  But actually we use pushl, which has the effect
1698 ;; of rounding the amount pushed up to a word.
1699
1700 (define_insn "*pushqi2"
1701   [(set (match_operand:QI 0 "push_operand" "=X")
1702         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1703   "!TARGET_64BIT"
1704   "push{l}\t%k1"
1705   [(set_attr "type" "push")
1706    (set_attr "mode" "SI")])
1707
1708 ;; For 64BIT abi we always round up to 8 bytes.
1709 (define_insn "*pushqi2_rex64"
1710   [(set (match_operand:QI 0 "push_operand" "=X")
1711         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1712   "TARGET_64BIT"
1713   "push{q}\t%q1"
1714   [(set_attr "type" "push")
1715    (set_attr "mode" "DI")])
1716
1717 ;; Situation is quite tricky about when to choose full sized (SImode) move
1718 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1719 ;; partial register dependency machines (such as AMD Athlon), where QImode
1720 ;; moves issue extra dependency and for partial register stalls machines
1721 ;; that don't use QImode patterns (and QImode move cause stall on the next
1722 ;; instruction).
1723 ;;
1724 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1725 ;; register stall machines with, where we use QImode instructions, since
1726 ;; partial register stall can be caused there.  Then we use movzx.
1727 (define_insn "*movqi_1"
1728   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1729         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1730   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1731 {
1732   switch (get_attr_type (insn))
1733     {
1734     case TYPE_IMOVX:
1735       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1736       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1737     default:
1738       if (get_attr_mode (insn) == MODE_SI)
1739         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1740       else
1741         return "mov{b}\t{%1, %0|%0, %1}";
1742     }
1743 }
1744   [(set (attr "type")
1745      (cond [(and (eq_attr "alternative" "5")
1746                  (not (match_operand:QI 1 "aligned_operand" "")))
1747               (const_string "imovx")
1748             (ne (symbol_ref "optimize_size") (const_int 0))
1749               (const_string "imov")
1750             (and (eq_attr "alternative" "3")
1751                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1752                           (const_int 0))
1753                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1754                           (const_int 0))))
1755               (const_string "imov")
1756             (eq_attr "alternative" "3,5")
1757               (const_string "imovx")
1758             (and (ne (symbol_ref "TARGET_MOVX")
1759                      (const_int 0))
1760                  (eq_attr "alternative" "2"))
1761               (const_string "imovx")
1762            ]
1763            (const_string "imov")))
1764    (set (attr "mode")
1765       (cond [(eq_attr "alternative" "3,4,5")
1766                (const_string "SI")
1767              (eq_attr "alternative" "6")
1768                (const_string "QI")
1769              (eq_attr "type" "imovx")
1770                (const_string "SI")
1771              (and (eq_attr "type" "imov")
1772                   (and (eq_attr "alternative" "0,1")
1773                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1774                                 (const_int 0))
1775                             (and (eq (symbol_ref "optimize_size")
1776                                      (const_int 0))
1777                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1778                                      (const_int 0))))))
1779                (const_string "SI")
1780              ;; Avoid partial register stalls when not using QImode arithmetic
1781              (and (eq_attr "type" "imov")
1782                   (and (eq_attr "alternative" "0,1")
1783                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1784                                 (const_int 0))
1785                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1786                                 (const_int 0)))))
1787                (const_string "SI")
1788            ]
1789            (const_string "QI")))])
1790
1791 (define_expand "reload_outqi"
1792   [(parallel [(match_operand:QI 0 "" "=m")
1793               (match_operand:QI 1 "register_operand" "r")
1794               (match_operand:QI 2 "register_operand" "=&q")])]
1795   ""
1796 {
1797   rtx op0, op1, op2;
1798   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1799
1800   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1801   if (! q_regs_operand (op1, QImode))
1802     {
1803       emit_insn (gen_movqi (op2, op1));
1804       op1 = op2;
1805     }
1806   emit_insn (gen_movqi (op0, op1));
1807   DONE;
1808 })
1809
1810 (define_insn "*swapqi_1"
1811   [(set (match_operand:QI 0 "register_operand" "+r")
1812         (match_operand:QI 1 "register_operand" "+r"))
1813    (set (match_dup 1)
1814         (match_dup 0))]
1815   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1816   "xchg{l}\t%k1, %k0"
1817   [(set_attr "type" "imov")
1818    (set_attr "mode" "SI")
1819    (set_attr "pent_pair" "np")
1820    (set_attr "athlon_decode" "vector")
1821    (set_attr "amdfam10_decode" "vector")])
1822
1823 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1824 (define_insn "*swapqi_2"
1825   [(set (match_operand:QI 0 "register_operand" "+q")
1826         (match_operand:QI 1 "register_operand" "+q"))
1827    (set (match_dup 1)
1828         (match_dup 0))]
1829   "TARGET_PARTIAL_REG_STALL"
1830   "xchg{b}\t%1, %0"
1831   [(set_attr "type" "imov")
1832    (set_attr "mode" "QI")
1833    (set_attr "pent_pair" "np")
1834    (set_attr "athlon_decode" "vector")])
1835
1836 (define_expand "movstrictqi"
1837   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1838         (match_operand:QI 1 "general_operand" ""))]
1839   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1840 {
1841   /* Don't generate memory->memory moves, go through a register.  */
1842   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1843     operands[1] = force_reg (QImode, operands[1]);
1844 })
1845
1846 (define_insn "*movstrictqi_1"
1847   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1848         (match_operand:QI 1 "general_operand" "*qn,m"))]
1849   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1850    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1851   "mov{b}\t{%1, %0|%0, %1}"
1852   [(set_attr "type" "imov")
1853    (set_attr "mode" "QI")])
1854
1855 (define_insn "*movstrictqi_xor"
1856   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1857         (match_operand:QI 1 "const0_operand" "i"))
1858    (clobber (reg:CC FLAGS_REG))]
1859   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1860   "xor{b}\t%0, %0"
1861   [(set_attr "type" "alu1")
1862    (set_attr "mode" "QI")
1863    (set_attr "length_immediate" "0")])
1864
1865 (define_insn "*movsi_extv_1"
1866   [(set (match_operand:SI 0 "register_operand" "=R")
1867         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1868                          (const_int 8)
1869                          (const_int 8)))]
1870   ""
1871   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1872   [(set_attr "type" "imovx")
1873    (set_attr "mode" "SI")])
1874
1875 (define_insn "*movhi_extv_1"
1876   [(set (match_operand:HI 0 "register_operand" "=R")
1877         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1878                          (const_int 8)
1879                          (const_int 8)))]
1880   ""
1881   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1882   [(set_attr "type" "imovx")
1883    (set_attr "mode" "SI")])
1884
1885 (define_insn "*movqi_extv_1"
1886   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1887         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1888                          (const_int 8)
1889                          (const_int 8)))]
1890   "!TARGET_64BIT"
1891 {
1892   switch (get_attr_type (insn))
1893     {
1894     case TYPE_IMOVX:
1895       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1896     default:
1897       return "mov{b}\t{%h1, %0|%0, %h1}";
1898     }
1899 }
1900   [(set (attr "type")
1901      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1902                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1903                              (ne (symbol_ref "TARGET_MOVX")
1904                                  (const_int 0))))
1905         (const_string "imovx")
1906         (const_string "imov")))
1907    (set (attr "mode")
1908      (if_then_else (eq_attr "type" "imovx")
1909         (const_string "SI")
1910         (const_string "QI")))])
1911
1912 (define_insn "*movqi_extv_1_rex64"
1913   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1914         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1915                          (const_int 8)
1916                          (const_int 8)))]
1917   "TARGET_64BIT"
1918 {
1919   switch (get_attr_type (insn))
1920     {
1921     case TYPE_IMOVX:
1922       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1923     default:
1924       return "mov{b}\t{%h1, %0|%0, %h1}";
1925     }
1926 }
1927   [(set (attr "type")
1928      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1929                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1930                              (ne (symbol_ref "TARGET_MOVX")
1931                                  (const_int 0))))
1932         (const_string "imovx")
1933         (const_string "imov")))
1934    (set (attr "mode")
1935      (if_then_else (eq_attr "type" "imovx")
1936         (const_string "SI")
1937         (const_string "QI")))])
1938
1939 ;; Stores and loads of ax to arbitrary constant address.
1940 ;; We fake an second form of instruction to force reload to load address
1941 ;; into register when rax is not available
1942 (define_insn "*movabsqi_1_rex64"
1943   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1944         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1945   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1946   "@
1947    movabs{b}\t{%1, %P0|%P0, %1}
1948    mov{b}\t{%1, %a0|%a0, %1}"
1949   [(set_attr "type" "imov")
1950    (set_attr "modrm" "0,*")
1951    (set_attr "length_address" "8,0")
1952    (set_attr "length_immediate" "0,*")
1953    (set_attr "memory" "store")
1954    (set_attr "mode" "QI")])
1955
1956 (define_insn "*movabsqi_2_rex64"
1957   [(set (match_operand:QI 0 "register_operand" "=a,r")
1958         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1959   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1960   "@
1961    movabs{b}\t{%P1, %0|%0, %P1}
1962    mov{b}\t{%a1, %0|%0, %a1}"
1963   [(set_attr "type" "imov")
1964    (set_attr "modrm" "0,*")
1965    (set_attr "length_address" "8,0")
1966    (set_attr "length_immediate" "0")
1967    (set_attr "memory" "load")
1968    (set_attr "mode" "QI")])
1969
1970 (define_insn "*movdi_extzv_1"
1971   [(set (match_operand:DI 0 "register_operand" "=R")
1972         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1973                          (const_int 8)
1974                          (const_int 8)))]
1975   "TARGET_64BIT"
1976   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1977   [(set_attr "type" "imovx")
1978    (set_attr "mode" "DI")])
1979
1980 (define_insn "*movsi_extzv_1"
1981   [(set (match_operand:SI 0 "register_operand" "=R")
1982         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1983                          (const_int 8)
1984                          (const_int 8)))]
1985   ""
1986   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1987   [(set_attr "type" "imovx")
1988    (set_attr "mode" "SI")])
1989
1990 (define_insn "*movqi_extzv_2"
1991   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1992         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1993                                     (const_int 8)
1994                                     (const_int 8)) 0))]
1995   "!TARGET_64BIT"
1996 {
1997   switch (get_attr_type (insn))
1998     {
1999     case TYPE_IMOVX:
2000       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2001     default:
2002       return "mov{b}\t{%h1, %0|%0, %h1}";
2003     }
2004 }
2005   [(set (attr "type")
2006      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2007                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2008                              (ne (symbol_ref "TARGET_MOVX")
2009                                  (const_int 0))))
2010         (const_string "imovx")
2011         (const_string "imov")))
2012    (set (attr "mode")
2013      (if_then_else (eq_attr "type" "imovx")
2014         (const_string "SI")
2015         (const_string "QI")))])
2016
2017 (define_insn "*movqi_extzv_2_rex64"
2018   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2019         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2020                                     (const_int 8)
2021                                     (const_int 8)) 0))]
2022   "TARGET_64BIT"
2023 {
2024   switch (get_attr_type (insn))
2025     {
2026     case TYPE_IMOVX:
2027       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2028     default:
2029       return "mov{b}\t{%h1, %0|%0, %h1}";
2030     }
2031 }
2032   [(set (attr "type")
2033      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2034                         (ne (symbol_ref "TARGET_MOVX")
2035                             (const_int 0)))
2036         (const_string "imovx")
2037         (const_string "imov")))
2038    (set (attr "mode")
2039      (if_then_else (eq_attr "type" "imovx")
2040         (const_string "SI")
2041         (const_string "QI")))])
2042
2043 (define_insn "movsi_insv_1"
2044   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2045                          (const_int 8)
2046                          (const_int 8))
2047         (match_operand:SI 1 "general_operand" "Qmn"))]
2048   "!TARGET_64BIT"
2049   "mov{b}\t{%b1, %h0|%h0, %b1}"
2050   [(set_attr "type" "imov")
2051    (set_attr "mode" "QI")])
2052
2053 (define_insn "*movsi_insv_1_rex64"
2054   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2055                          (const_int 8)
2056                          (const_int 8))
2057         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2058   "TARGET_64BIT"
2059   "mov{b}\t{%b1, %h0|%h0, %b1}"
2060   [(set_attr "type" "imov")
2061    (set_attr "mode" "QI")])
2062
2063 (define_insn "movdi_insv_1_rex64"
2064   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2065                          (const_int 8)
2066                          (const_int 8))
2067         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2068   "TARGET_64BIT"
2069   "mov{b}\t{%b1, %h0|%h0, %b1}"
2070   [(set_attr "type" "imov")
2071    (set_attr "mode" "QI")])
2072
2073 (define_insn "*movqi_insv_2"
2074   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2075                          (const_int 8)
2076                          (const_int 8))
2077         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2078                      (const_int 8)))]
2079   ""
2080   "mov{b}\t{%h1, %h0|%h0, %h1}"
2081   [(set_attr "type" "imov")
2082    (set_attr "mode" "QI")])
2083
2084 (define_expand "movdi"
2085   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2086         (match_operand:DI 1 "general_operand" ""))]
2087   ""
2088   "ix86_expand_move (DImode, operands); DONE;")
2089
2090 (define_insn "*pushdi"
2091   [(set (match_operand:DI 0 "push_operand" "=<")
2092         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2093   "!TARGET_64BIT"
2094   "#")
2095
2096 (define_insn "*pushdi2_rex64"
2097   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2098         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2099   "TARGET_64BIT"
2100   "@
2101    push{q}\t%1
2102    #"
2103   [(set_attr "type" "push,multi")
2104    (set_attr "mode" "DI")])
2105
2106 ;; Convert impossible pushes of immediate to existing instructions.
2107 ;; First try to get scratch register and go through it.  In case this
2108 ;; fails, push sign extended lower part first and then overwrite
2109 ;; upper part by 32bit move.
2110 (define_peephole2
2111   [(match_scratch:DI 2 "r")
2112    (set (match_operand:DI 0 "push_operand" "")
2113         (match_operand:DI 1 "immediate_operand" ""))]
2114   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2115    && !x86_64_immediate_operand (operands[1], DImode)"
2116   [(set (match_dup 2) (match_dup 1))
2117    (set (match_dup 0) (match_dup 2))]
2118   "")
2119
2120 ;; We need to define this as both peepholer and splitter for case
2121 ;; peephole2 pass is not run.
2122 ;; "&& 1" is needed to keep it from matching the previous pattern.
2123 (define_peephole2
2124   [(set (match_operand:DI 0 "push_operand" "")
2125         (match_operand:DI 1 "immediate_operand" ""))]
2126   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2127    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2128   [(set (match_dup 0) (match_dup 1))
2129    (set (match_dup 2) (match_dup 3))]
2130   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2131    operands[1] = gen_lowpart (DImode, operands[2]);
2132    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2133                                                     GEN_INT (4)));
2134   ")
2135
2136 (define_split
2137   [(set (match_operand:DI 0 "push_operand" "")
2138         (match_operand:DI 1 "immediate_operand" ""))]
2139   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2140                     ? epilogue_completed : reload_completed)
2141    && !symbolic_operand (operands[1], DImode)
2142    && !x86_64_immediate_operand (operands[1], DImode)"
2143   [(set (match_dup 0) (match_dup 1))
2144    (set (match_dup 2) (match_dup 3))]
2145   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2146    operands[1] = gen_lowpart (DImode, operands[2]);
2147    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2148                                                     GEN_INT (4)));
2149   ")
2150
2151 (define_insn "*pushdi2_prologue_rex64"
2152   [(set (match_operand:DI 0 "push_operand" "=<")
2153         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2154    (clobber (mem:BLK (scratch)))]
2155   "TARGET_64BIT"
2156   "push{q}\t%1"
2157   [(set_attr "type" "push")
2158    (set_attr "mode" "DI")])
2159
2160 (define_insn "*popdi1_epilogue_rex64"
2161   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2162         (mem:DI (reg:DI SP_REG)))
2163    (set (reg:DI SP_REG)
2164         (plus:DI (reg:DI SP_REG) (const_int 8)))
2165    (clobber (mem:BLK (scratch)))]
2166   "TARGET_64BIT"
2167   "pop{q}\t%0"
2168   [(set_attr "type" "pop")
2169    (set_attr "mode" "DI")])
2170
2171 (define_insn "popdi1"
2172   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2173         (mem:DI (reg:DI SP_REG)))
2174    (set (reg:DI SP_REG)
2175         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2176   "TARGET_64BIT"
2177   "pop{q}\t%0"
2178   [(set_attr "type" "pop")
2179    (set_attr "mode" "DI")])
2180
2181 (define_insn "*movdi_xor_rex64"
2182   [(set (match_operand:DI 0 "register_operand" "=r")
2183         (match_operand:DI 1 "const0_operand" "i"))
2184    (clobber (reg:CC FLAGS_REG))]
2185   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2186    && reload_completed"
2187   "xor{l}\t%k0, %k0";
2188   [(set_attr "type" "alu1")
2189    (set_attr "mode" "SI")
2190    (set_attr "length_immediate" "0")])
2191
2192 (define_insn "*movdi_or_rex64"
2193   [(set (match_operand:DI 0 "register_operand" "=r")
2194         (match_operand:DI 1 "const_int_operand" "i"))
2195    (clobber (reg:CC FLAGS_REG))]
2196   "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2197    && reload_completed
2198    && operands[1] == constm1_rtx"
2199 {
2200   operands[1] = constm1_rtx;
2201   return "or{q}\t{%1, %0|%0, %1}";
2202 }
2203   [(set_attr "type" "alu1")
2204    (set_attr "mode" "DI")
2205    (set_attr "length_immediate" "1")])
2206
2207 (define_insn "*movdi_2"
2208   [(set (match_operand:DI 0 "nonimmediate_operand"
2209                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2210         (match_operand:DI 1 "general_operand"
2211                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2212   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2213   "@
2214    #
2215    #
2216    pxor\t%0, %0
2217    movq\t{%1, %0|%0, %1}
2218    movq\t{%1, %0|%0, %1}
2219    pxor\t%0, %0
2220    movq\t{%1, %0|%0, %1}
2221    movdqa\t{%1, %0|%0, %1}
2222    movq\t{%1, %0|%0, %1}
2223    xorps\t%0, %0
2224    movlps\t{%1, %0|%0, %1}
2225    movaps\t{%1, %0|%0, %1}
2226    movlps\t{%1, %0|%0, %1}"
2227   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2228    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2229
2230 (define_split
2231   [(set (match_operand:DI 0 "push_operand" "")
2232         (match_operand:DI 1 "general_operand" ""))]
2233   "!TARGET_64BIT && reload_completed
2234    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2235   [(const_int 0)]
2236   "ix86_split_long_move (operands); DONE;")
2237
2238 ;; %%% This multiword shite has got to go.
2239 (define_split
2240   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2241         (match_operand:DI 1 "general_operand" ""))]
2242   "!TARGET_64BIT && reload_completed
2243    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2244    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2245   [(const_int 0)]
2246   "ix86_split_long_move (operands); DONE;")
2247
2248 (define_insn "*movdi_1_rex64"
2249   [(set (match_operand:DI 0 "nonimmediate_operand"
2250           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2251         (match_operand:DI 1 "general_operand"
2252           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2253   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2254 {
2255   switch (get_attr_type (insn))
2256     {
2257     case TYPE_SSECVT:
2258       if (SSE_REG_P (operands[0]))
2259         return "movq2dq\t{%1, %0|%0, %1}";
2260       else
2261         return "movdq2q\t{%1, %0|%0, %1}";
2262
2263     case TYPE_SSEMOV:
2264       if (get_attr_mode (insn) == MODE_TI)
2265         return "movdqa\t{%1, %0|%0, %1}";
2266       /* FALLTHRU */
2267
2268     case TYPE_MMXMOV:
2269       /* Moves from and into integer register is done using movd
2270          opcode with REX prefix.  */
2271       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2272         return "movd\t{%1, %0|%0, %1}";
2273       return "movq\t{%1, %0|%0, %1}";
2274
2275     case TYPE_SSELOG1:
2276     case TYPE_MMXADD:
2277       return "pxor\t%0, %0";
2278
2279     case TYPE_MULTI:
2280       return "#";
2281
2282     case TYPE_LEA:
2283       return "lea{q}\t{%a1, %0|%0, %a1}";
2284
2285     default:
2286       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2287       if (get_attr_mode (insn) == MODE_SI)
2288         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2289       else if (which_alternative == 2)
2290         return "movabs{q}\t{%1, %0|%0, %1}";
2291       else
2292         return "mov{q}\t{%1, %0|%0, %1}";
2293     }
2294 }
2295   [(set (attr "type")
2296      (cond [(eq_attr "alternative" "5")
2297               (const_string "mmxadd")
2298             (eq_attr "alternative" "6,7,8,9,10")
2299               (const_string "mmxmov")
2300             (eq_attr "alternative" "11")
2301               (const_string "sselog1")
2302             (eq_attr "alternative" "12,13,14,15,16")
2303               (const_string "ssemov")
2304             (eq_attr "alternative" "17,18")
2305               (const_string "ssecvt")
2306             (eq_attr "alternative" "4")
2307               (const_string "multi")
2308             (match_operand:DI 1 "pic_32bit_operand" "")
2309               (const_string "lea")
2310            ]
2311            (const_string "imov")))
2312    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2313    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2314    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2315
2316 ;; Stores and loads of ax to arbitrary constant address.
2317 ;; We fake an second form of instruction to force reload to load address
2318 ;; into register when rax is not available
2319 (define_insn "*movabsdi_1_rex64"
2320   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2321         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2322   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2323   "@
2324    movabs{q}\t{%1, %P0|%P0, %1}
2325    mov{q}\t{%1, %a0|%a0, %1}"
2326   [(set_attr "type" "imov")
2327    (set_attr "modrm" "0,*")
2328    (set_attr "length_address" "8,0")
2329    (set_attr "length_immediate" "0,*")
2330    (set_attr "memory" "store")
2331    (set_attr "mode" "DI")])
2332
2333 (define_insn "*movabsdi_2_rex64"
2334   [(set (match_operand:DI 0 "register_operand" "=a,r")
2335         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2336   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2337   "@
2338    movabs{q}\t{%P1, %0|%0, %P1}
2339    mov{q}\t{%a1, %0|%0, %a1}"
2340   [(set_attr "type" "imov")
2341    (set_attr "modrm" "0,*")
2342    (set_attr "length_address" "8,0")
2343    (set_attr "length_immediate" "0")
2344    (set_attr "memory" "load")
2345    (set_attr "mode" "DI")])
2346
2347 ;; Convert impossible stores of immediate to existing instructions.
2348 ;; First try to get scratch register and go through it.  In case this
2349 ;; fails, move by 32bit parts.
2350 (define_peephole2
2351   [(match_scratch:DI 2 "r")
2352    (set (match_operand:DI 0 "memory_operand" "")
2353         (match_operand:DI 1 "immediate_operand" ""))]
2354   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2355    && !x86_64_immediate_operand (operands[1], DImode)"
2356   [(set (match_dup 2) (match_dup 1))
2357    (set (match_dup 0) (match_dup 2))]
2358   "")
2359
2360 ;; We need to define this as both peepholer and splitter for case
2361 ;; peephole2 pass is not run.
2362 ;; "&& 1" is needed to keep it from matching the previous pattern.
2363 (define_peephole2
2364   [(set (match_operand:DI 0 "memory_operand" "")
2365         (match_operand:DI 1 "immediate_operand" ""))]
2366   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2367    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2368   [(set (match_dup 2) (match_dup 3))
2369    (set (match_dup 4) (match_dup 5))]
2370   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2371
2372 (define_split
2373   [(set (match_operand:DI 0 "memory_operand" "")
2374         (match_operand:DI 1 "immediate_operand" ""))]
2375   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2376                     ? epilogue_completed : reload_completed)
2377    && !symbolic_operand (operands[1], DImode)
2378    && !x86_64_immediate_operand (operands[1], DImode)"
2379   [(set (match_dup 2) (match_dup 3))
2380    (set (match_dup 4) (match_dup 5))]
2381   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2382
2383 (define_insn "*swapdi_rex64"
2384   [(set (match_operand:DI 0 "register_operand" "+r")
2385         (match_operand:DI 1 "register_operand" "+r"))
2386    (set (match_dup 1)
2387         (match_dup 0))]
2388   "TARGET_64BIT"
2389   "xchg{q}\t%1, %0"
2390   [(set_attr "type" "imov")
2391    (set_attr "mode" "DI")
2392    (set_attr "pent_pair" "np")
2393    (set_attr "athlon_decode" "vector")
2394    (set_attr "amdfam10_decode" "double")])
2395
2396 (define_expand "movti"
2397   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2398         (match_operand:TI 1 "nonimmediate_operand" ""))]
2399   "TARGET_SSE || TARGET_64BIT"
2400 {
2401   if (TARGET_64BIT)
2402     ix86_expand_move (TImode, operands);
2403   else if (push_operand (operands[0], TImode))
2404     ix86_expand_push (TImode, operands[1]);
2405   else
2406     ix86_expand_vector_move (TImode, operands);
2407   DONE;
2408 })
2409
2410 (define_insn "*movti_internal"
2411   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2412         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2413   "TARGET_SSE && !TARGET_64BIT
2414    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2415 {
2416   switch (which_alternative)
2417     {
2418     case 0:
2419       if (get_attr_mode (insn) == MODE_V4SF)
2420         return "xorps\t%0, %0";
2421       else
2422         return "pxor\t%0, %0";
2423     case 1:
2424     case 2:
2425       /* TDmode values are passed as TImode on the stack.  Moving them
2426          to stack may result in unaligned memory access.  */
2427       if (misaligned_operand (operands[0], TImode)
2428           || misaligned_operand (operands[1], TImode))
2429         { 
2430           if (get_attr_mode (insn) == MODE_V4SF)
2431             return "movups\t{%1, %0|%0, %1}";
2432          else
2433            return "movdqu\t{%1, %0|%0, %1}";
2434         }
2435       else
2436         { 
2437           if (get_attr_mode (insn) == MODE_V4SF)
2438             return "movaps\t{%1, %0|%0, %1}";
2439          else
2440            return "movdqa\t{%1, %0|%0, %1}";
2441         }
2442     default:
2443       gcc_unreachable ();
2444     }
2445 }
2446   [(set_attr "type" "sselog1,ssemov,ssemov")
2447    (set (attr "mode")
2448         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2449                     (ne (symbol_ref "optimize_size") (const_int 0)))
2450                  (const_string "V4SF")
2451                (and (eq_attr "alternative" "2")
2452                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2453                         (const_int 0)))
2454                  (const_string "V4SF")]
2455               (const_string "TI")))])
2456
2457 (define_insn "*movti_rex64"
2458   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2459         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2460   "TARGET_64BIT
2461    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2462 {
2463   switch (which_alternative)
2464     {
2465     case 0:
2466     case 1:
2467       return "#";
2468     case 2:
2469       if (get_attr_mode (insn) == MODE_V4SF)
2470         return "xorps\t%0, %0";
2471       else
2472         return "pxor\t%0, %0";
2473     case 3:
2474     case 4:
2475       /* TDmode values are passed as TImode on the stack.  Moving them
2476          to stack may result in unaligned memory access.  */
2477       if (misaligned_operand (operands[0], TImode)
2478           || misaligned_operand (operands[1], TImode))
2479         { 
2480           if (get_attr_mode (insn) == MODE_V4SF)
2481             return "movups\t{%1, %0|%0, %1}";
2482          else
2483            return "movdqu\t{%1, %0|%0, %1}";
2484         }
2485       else
2486         { 
2487           if (get_attr_mode (insn) == MODE_V4SF)
2488             return "movaps\t{%1, %0|%0, %1}";
2489          else
2490            return "movdqa\t{%1, %0|%0, %1}";
2491         }
2492     default:
2493       gcc_unreachable ();
2494     }
2495 }
2496   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2497    (set (attr "mode")
2498         (cond [(eq_attr "alternative" "2,3")
2499                  (if_then_else
2500                    (ne (symbol_ref "optimize_size")
2501                        (const_int 0))
2502                    (const_string "V4SF")
2503                    (const_string "TI"))
2504                (eq_attr "alternative" "4")
2505                  (if_then_else
2506                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2507                             (const_int 0))
2508                         (ne (symbol_ref "optimize_size")
2509                             (const_int 0)))
2510                    (const_string "V4SF")
2511                    (const_string "TI"))]
2512                (const_string "DI")))])
2513
2514 (define_split
2515   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2516         (match_operand:TI 1 "general_operand" ""))]
2517   "reload_completed && !SSE_REG_P (operands[0])
2518    && !SSE_REG_P (operands[1])"
2519   [(const_int 0)]
2520   "ix86_split_long_move (operands); DONE;")
2521
2522 ;; This expands to what emit_move_complex would generate if we didn't
2523 ;; have a movti pattern.  Having this avoids problems with reload on
2524 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2525 ;; to have around all the time.
2526 (define_expand "movcdi"
2527   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2528         (match_operand:CDI 1 "general_operand" ""))]
2529   ""
2530 {
2531   if (push_operand (operands[0], CDImode))
2532     emit_move_complex_push (CDImode, operands[0], operands[1]);
2533   else
2534     emit_move_complex_parts (operands[0], operands[1]);
2535   DONE;
2536 })
2537
2538 (define_expand "movsf"
2539   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2540         (match_operand:SF 1 "general_operand" ""))]
2541   ""
2542   "ix86_expand_move (SFmode, operands); DONE;")
2543
2544 (define_insn "*pushsf"
2545   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2546         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2547   "!TARGET_64BIT"
2548 {
2549   /* Anything else should be already split before reg-stack.  */
2550   gcc_assert (which_alternative == 1);
2551   return "push{l}\t%1";
2552 }
2553   [(set_attr "type" "multi,push,multi")
2554    (set_attr "unit" "i387,*,*")
2555    (set_attr "mode" "SF,SI,SF")])
2556
2557 (define_insn "*pushsf_rex64"
2558   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2559         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2560   "TARGET_64BIT"
2561 {
2562   /* Anything else should be already split before reg-stack.  */
2563   gcc_assert (which_alternative == 1);
2564   return "push{q}\t%q1";
2565 }
2566   [(set_attr "type" "multi,push,multi")
2567    (set_attr "unit" "i387,*,*")
2568    (set_attr "mode" "SF,DI,SF")])
2569
2570 (define_split
2571   [(set (match_operand:SF 0 "push_operand" "")
2572         (match_operand:SF 1 "memory_operand" ""))]
2573   "reload_completed
2574    && MEM_P (operands[1])
2575    && (operands[2] = find_constant_src (insn))"
2576   [(set (match_dup 0)
2577         (match_dup 2))])
2578
2579
2580 ;; %%% Kill this when call knows how to work this out.
2581 (define_split
2582   [(set (match_operand:SF 0 "push_operand" "")
2583         (match_operand:SF 1 "any_fp_register_operand" ""))]
2584   "!TARGET_64BIT"
2585   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2586    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2587
2588 (define_split
2589   [(set (match_operand:SF 0 "push_operand" "")
2590         (match_operand:SF 1 "any_fp_register_operand" ""))]
2591   "TARGET_64BIT"
2592   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2593    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2594
2595 (define_insn "*movsf_1"
2596   [(set (match_operand:SF 0 "nonimmediate_operand"
2597           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2598         (match_operand:SF 1 "general_operand"
2599           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2600   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2601    && (reload_in_progress || reload_completed
2602        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2603        || (!TARGET_SSE_MATH && optimize_size
2604            && standard_80387_constant_p (operands[1]))
2605        || GET_CODE (operands[1]) != CONST_DOUBLE
2606        || memory_operand (operands[0], SFmode))"
2607 {
2608   switch (which_alternative)
2609     {
2610     case 0:
2611     case 1:
2612       return output_387_reg_move (insn, operands);
2613
2614     case 2:
2615       return standard_80387_constant_opcode (operands[1]);
2616
2617     case 3:
2618     case 4:
2619       return "mov{l}\t{%1, %0|%0, %1}";
2620     case 5:
2621       if (get_attr_mode (insn) == MODE_TI)
2622         return "pxor\t%0, %0";
2623       else
2624         return "xorps\t%0, %0";
2625     case 6:
2626       if (get_attr_mode (insn) == MODE_V4SF)
2627         return "movaps\t{%1, %0|%0, %1}";
2628       else
2629         return "movss\t{%1, %0|%0, %1}";
2630     case 7: case 8:
2631       return "movss\t{%1, %0|%0, %1}";
2632
2633     case 9: case 10:
2634     case 12: case 13: case 14: case 15:
2635       return "movd\t{%1, %0|%0, %1}";
2636
2637     case 11:
2638       return "movq\t{%1, %0|%0, %1}";
2639
2640     default:
2641       gcc_unreachable ();
2642     }
2643 }
2644   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2645    (set (attr "mode")
2646         (cond [(eq_attr "alternative" "3,4,9,10")
2647                  (const_string "SI")
2648                (eq_attr "alternative" "5")
2649                  (if_then_else
2650                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2651                                  (const_int 0))
2652                              (ne (symbol_ref "TARGET_SSE2")
2653                                  (const_int 0)))
2654                         (eq (symbol_ref "optimize_size")
2655                             (const_int 0)))
2656                    (const_string "TI")
2657                    (const_string "V4SF"))
2658                /* For architectures resolving dependencies on
2659                   whole SSE registers use APS move to break dependency
2660                   chains, otherwise use short move to avoid extra work.
2661
2662                   Do the same for architectures resolving dependencies on
2663                   the parts.  While in DF mode it is better to always handle
2664                   just register parts, the SF mode is different due to lack
2665                   of instructions to load just part of the register.  It is
2666                   better to maintain the whole registers in single format
2667                   to avoid problems on using packed logical operations.  */
2668                (eq_attr "alternative" "6")
2669                  (if_then_else
2670                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2671                             (const_int 0))
2672                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2673                             (const_int 0)))
2674                    (const_string "V4SF")
2675                    (const_string "SF"))
2676                (eq_attr "alternative" "11")
2677                  (const_string "DI")]
2678                (const_string "SF")))])
2679
2680 (define_insn "*swapsf"
2681   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2682         (match_operand:SF 1 "fp_register_operand" "+f"))
2683    (set (match_dup 1)
2684         (match_dup 0))]
2685   "reload_completed || TARGET_80387"
2686 {
2687   if (STACK_TOP_P (operands[0]))
2688     return "fxch\t%1";
2689   else
2690     return "fxch\t%0";
2691 }
2692   [(set_attr "type" "fxch")
2693    (set_attr "mode" "SF")])
2694
2695 (define_expand "movdf"
2696   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2697         (match_operand:DF 1 "general_operand" ""))]
2698   ""
2699   "ix86_expand_move (DFmode, operands); DONE;")
2700
2701 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2702 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2703 ;; On the average, pushdf using integers can be still shorter.  Allow this
2704 ;; pattern for optimize_size too.
2705
2706 (define_insn "*pushdf_nointeger"
2707   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2708         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2709   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2710 {
2711   /* This insn should be already split before reg-stack.  */
2712   gcc_unreachable ();
2713 }
2714   [(set_attr "type" "multi")
2715    (set_attr "unit" "i387,*,*,*")
2716    (set_attr "mode" "DF,SI,SI,DF")])
2717
2718 (define_insn "*pushdf_integer"
2719   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2720         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2721   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2722 {
2723   /* This insn should be already split before reg-stack.  */
2724   gcc_unreachable ();
2725 }
2726   [(set_attr "type" "multi")
2727    (set_attr "unit" "i387,*,*")
2728    (set_attr "mode" "DF,SI,DF")])
2729
2730 ;; %%% Kill this when call knows how to work this out.
2731 (define_split
2732   [(set (match_operand:DF 0 "push_operand" "")
2733         (match_operand:DF 1 "any_fp_register_operand" ""))]
2734   "!TARGET_64BIT && reload_completed"
2735   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2736    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2737   "")
2738
2739 (define_split
2740   [(set (match_operand:DF 0 "push_operand" "")
2741         (match_operand:DF 1 "any_fp_register_operand" ""))]
2742   "TARGET_64BIT && reload_completed"
2743   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2744    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2745   "")
2746
2747 (define_split
2748   [(set (match_operand:DF 0 "push_operand" "")
2749         (match_operand:DF 1 "general_operand" ""))]
2750   "reload_completed"
2751   [(const_int 0)]
2752   "ix86_split_long_move (operands); DONE;")
2753
2754 ;; Moving is usually shorter when only FP registers are used. This separate
2755 ;; movdf pattern avoids the use of integer registers for FP operations
2756 ;; when optimizing for size.
2757
2758 (define_insn "*movdf_nointeger"
2759   [(set (match_operand:DF 0 "nonimmediate_operand"
2760                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2761         (match_operand:DF 1 "general_operand"
2762                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
2763   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2764    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2765    && (reload_in_progress || reload_completed
2766        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2767        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2768            && !memory_operand (operands[0], DFmode)
2769            && standard_80387_constant_p (operands[1]))
2770        || GET_CODE (operands[1]) != CONST_DOUBLE
2771        || ((optimize_size
2772             || !TARGET_MEMORY_MISMATCH_STALL
2773             || reload_in_progress || reload_completed)
2774            && memory_operand (operands[0], DFmode)))"
2775 {
2776   switch (which_alternative)
2777     {
2778     case 0:
2779     case 1:
2780       return output_387_reg_move (insn, operands);
2781
2782     case 2:
2783       return standard_80387_constant_opcode (operands[1]);
2784
2785     case 3:
2786     case 4:
2787       return "#";
2788     case 5:
2789       switch (get_attr_mode (insn))
2790         {
2791         case MODE_V4SF:
2792           return "xorps\t%0, %0";
2793         case MODE_V2DF:
2794           return "xorpd\t%0, %0";
2795         case MODE_TI:
2796           return "pxor\t%0, %0";
2797         default:
2798           gcc_unreachable ();
2799         }
2800     case 6:
2801     case 7:
2802     case 8:
2803       switch (get_attr_mode (insn))
2804         {
2805         case MODE_V4SF:
2806           return "movaps\t{%1, %0|%0, %1}";
2807         case MODE_V2DF:
2808           return "movapd\t{%1, %0|%0, %1}";
2809         case MODE_TI:
2810           return "movdqa\t{%1, %0|%0, %1}";
2811         case MODE_DI:
2812           return "movq\t{%1, %0|%0, %1}";
2813         case MODE_DF:
2814           return "movsd\t{%1, %0|%0, %1}";
2815         case MODE_V1DF:
2816           return "movlpd\t{%1, %0|%0, %1}";
2817         case MODE_V2SF:
2818           return "movlps\t{%1, %0|%0, %1}";
2819         default:
2820           gcc_unreachable ();
2821         }
2822
2823     default:
2824       gcc_unreachable ();
2825     }
2826 }
2827   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2828    (set (attr "mode")
2829         (cond [(eq_attr "alternative" "0,1,2")
2830                  (const_string "DF")
2831                (eq_attr "alternative" "3,4")
2832                  (const_string "SI")
2833
2834                /* For SSE1, we have many fewer alternatives.  */
2835                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2836                  (cond [(eq_attr "alternative" "5,6")
2837                           (const_string "V4SF")
2838                        ]
2839                    (const_string "V2SF"))
2840
2841                /* xorps is one byte shorter.  */
2842                (eq_attr "alternative" "5")
2843                  (cond [(ne (symbol_ref "optimize_size")
2844                             (const_int 0))
2845                           (const_string "V4SF")
2846                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2847                             (const_int 0))
2848                           (const_string "TI")
2849                        ]
2850                        (const_string "V2DF"))
2851
2852                /* For architectures resolving dependencies on
2853                   whole SSE registers use APD move to break dependency
2854                   chains, otherwise use short move to avoid extra work.
2855
2856                   movaps encodes one byte shorter.  */
2857                (eq_attr "alternative" "6")
2858                  (cond
2859                    [(ne (symbol_ref "optimize_size")
2860                         (const_int 0))
2861                       (const_string "V4SF")
2862                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2863                         (const_int 0))
2864                       (const_string "V2DF")
2865                    ]
2866                    (const_string "DF"))
2867                /* For architectures resolving dependencies on register
2868                   parts we may avoid extra work to zero out upper part
2869                   of register.  */
2870                (eq_attr "alternative" "7")
2871                  (if_then_else
2872                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2873                        (const_int 0))
2874                    (const_string "V1DF")
2875                    (const_string "DF"))
2876               ]
2877               (const_string "DF")))])
2878
2879 (define_insn "*movdf_integer_rex64"
2880   [(set (match_operand:DF 0 "nonimmediate_operand"
2881                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2882         (match_operand:DF 1 "general_operand"
2883                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2884   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2885    && (reload_in_progress || reload_completed
2886        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2887        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2888            && standard_80387_constant_p (operands[1]))
2889        || GET_CODE (operands[1]) != CONST_DOUBLE
2890        || memory_operand (operands[0], DFmode))"
2891 {
2892   switch (which_alternative)
2893     {
2894     case 0:
2895     case 1:
2896       return output_387_reg_move (insn, operands);
2897
2898     case 2:
2899       return standard_80387_constant_opcode (operands[1]);
2900
2901     case 3:
2902     case 4:
2903       return "#";
2904
2905     case 5:
2906       switch (get_attr_mode (insn))
2907         {
2908         case MODE_V4SF:
2909           return "xorps\t%0, %0";
2910         case MODE_V2DF:
2911           return "xorpd\t%0, %0";
2912         case MODE_TI:
2913           return "pxor\t%0, %0";
2914         default:
2915           gcc_unreachable ();
2916         }
2917     case 6:
2918     case 7:
2919     case 8:
2920       switch (get_attr_mode (insn))
2921         {
2922         case MODE_V4SF:
2923           return "movaps\t{%1, %0|%0, %1}";
2924         case MODE_V2DF:
2925           return "movapd\t{%1, %0|%0, %1}";
2926         case MODE_TI:
2927           return "movdqa\t{%1, %0|%0, %1}";
2928         case MODE_DI:
2929           return "movq\t{%1, %0|%0, %1}";
2930         case MODE_DF:
2931           return "movsd\t{%1, %0|%0, %1}";
2932         case MODE_V1DF:
2933           return "movlpd\t{%1, %0|%0, %1}";
2934         case MODE_V2SF:
2935           return "movlps\t{%1, %0|%0, %1}";
2936         default:
2937           gcc_unreachable ();
2938         }
2939
2940     case 9:
2941     case 10:
2942       return "movd\t{%1, %0|%0, %1}";
2943
2944     default:
2945       gcc_unreachable();
2946     }
2947 }
2948   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2949    (set (attr "mode")
2950         (cond [(eq_attr "alternative" "0,1,2")
2951                  (const_string "DF")
2952                (eq_attr "alternative" "3,4,9,10")
2953                  (const_string "DI")
2954
2955                /* For SSE1, we have many fewer alternatives.  */
2956                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2957                  (cond [(eq_attr "alternative" "5,6")
2958                           (const_string "V4SF")
2959                        ]
2960                    (const_string "V2SF"))
2961
2962                /* xorps is one byte shorter.  */
2963                (eq_attr "alternative" "5")
2964                  (cond [(ne (symbol_ref "optimize_size")
2965                             (const_int 0))
2966                           (const_string "V4SF")
2967                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2968                             (const_int 0))
2969                           (const_string "TI")
2970                        ]
2971                        (const_string "V2DF"))
2972
2973                /* For architectures resolving dependencies on
2974                   whole SSE registers use APD move to break dependency
2975                   chains, otherwise use short move to avoid extra work.
2976
2977                   movaps encodes one byte shorter.  */
2978                (eq_attr "alternative" "6")
2979                  (cond
2980                    [(ne (symbol_ref "optimize_size")
2981                         (const_int 0))
2982                       (const_string "V4SF")
2983                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2984                         (const_int 0))
2985                       (const_string "V2DF")
2986                    ]
2987                    (const_string "DF"))
2988                /* For architectures resolving dependencies on register
2989                   parts we may avoid extra work to zero out upper part
2990                   of register.  */
2991                (eq_attr "alternative" "7")
2992                  (if_then_else
2993                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2994                        (const_int 0))
2995                    (const_string "V1DF")
2996                    (const_string "DF"))
2997               ]
2998               (const_string "DF")))])
2999
3000 (define_insn "*movdf_integer"
3001   [(set (match_operand:DF 0 "nonimmediate_operand"
3002                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3003         (match_operand:DF 1 "general_operand"
3004                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3005   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3006    && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
3007    && (reload_in_progress || reload_completed
3008        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3009        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
3010            && standard_80387_constant_p (operands[1]))
3011        || GET_CODE (operands[1]) != CONST_DOUBLE
3012        || memory_operand (operands[0], DFmode))"
3013 {
3014   switch (which_alternative)
3015     {
3016     case 0:
3017     case 1:
3018       return output_387_reg_move (insn, operands);
3019
3020     case 2:
3021       return standard_80387_constant_opcode (operands[1]);
3022
3023     case 3:
3024     case 4:
3025       return "#";
3026
3027     case 5:
3028       switch (get_attr_mode (insn))
3029         {
3030         case MODE_V4SF:
3031           return "xorps\t%0, %0";
3032         case MODE_V2DF:
3033           return "xorpd\t%0, %0";
3034         case MODE_TI:
3035           return "pxor\t%0, %0";
3036         default:
3037           gcc_unreachable ();
3038         }
3039     case 6:
3040     case 7:
3041     case 8:
3042       switch (get_attr_mode (insn))
3043         {
3044         case MODE_V4SF:
3045           return "movaps\t{%1, %0|%0, %1}";
3046         case MODE_V2DF:
3047           return "movapd\t{%1, %0|%0, %1}";
3048         case MODE_TI:
3049           return "movdqa\t{%1, %0|%0, %1}";
3050         case MODE_DI:
3051           return "movq\t{%1, %0|%0, %1}";
3052         case MODE_DF:
3053           return "movsd\t{%1, %0|%0, %1}";
3054         case MODE_V1DF:
3055           return "movlpd\t{%1, %0|%0, %1}";
3056         case MODE_V2SF:
3057           return "movlps\t{%1, %0|%0, %1}";
3058         default:
3059           gcc_unreachable ();
3060         }
3061
3062     default:
3063       gcc_unreachable();
3064     }
3065 }
3066   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3067    (set (attr "mode")
3068         (cond [(eq_attr "alternative" "0,1,2")
3069                  (const_string "DF")
3070                (eq_attr "alternative" "3,4")
3071                  (const_string "SI")
3072
3073                /* For SSE1, we have many fewer alternatives.  */
3074                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3075                  (cond [(eq_attr "alternative" "5,6")
3076                           (const_string "V4SF")
3077                        ]
3078                    (const_string "V2SF"))
3079
3080                /* xorps is one byte shorter.  */
3081                (eq_attr "alternative" "5")
3082                  (cond [(ne (symbol_ref "optimize_size")
3083                             (const_int 0))
3084                           (const_string "V4SF")
3085                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3086                             (const_int 0))
3087                           (const_string "TI")
3088                        ]
3089                        (const_string "V2DF"))
3090
3091                /* For architectures resolving dependencies on
3092                   whole SSE registers use APD move to break dependency
3093                   chains, otherwise use short move to avoid extra work.
3094
3095                   movaps encodes one byte shorter.  */
3096                (eq_attr "alternative" "6")
3097                  (cond
3098                    [(ne (symbol_ref "optimize_size")
3099                         (const_int 0))
3100                       (const_string "V4SF")
3101                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3102                         (const_int 0))
3103                       (const_string "V2DF")
3104                    ]
3105                    (const_string "DF"))
3106                /* For architectures resolving dependencies on register
3107                   parts we may avoid extra work to zero out upper part
3108                   of register.  */
3109                (eq_attr "alternative" "7")
3110                  (if_then_else
3111                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3112                        (const_int 0))
3113                    (const_string "V1DF")
3114                    (const_string "DF"))
3115               ]
3116               (const_string "DF")))])
3117
3118 (define_split
3119   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3120         (match_operand:DF 1 "general_operand" ""))]
3121   "reload_completed
3122    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3123    && ! (ANY_FP_REG_P (operands[0]) ||
3124          (GET_CODE (operands[0]) == SUBREG
3125           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3126    && ! (ANY_FP_REG_P (operands[1]) ||
3127          (GET_CODE (operands[1]) == SUBREG
3128           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3129   [(const_int 0)]
3130   "ix86_split_long_move (operands); DONE;")
3131
3132 (define_insn "*swapdf"
3133   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3134         (match_operand:DF 1 "fp_register_operand" "+f"))
3135    (set (match_dup 1)
3136         (match_dup 0))]
3137   "reload_completed || TARGET_80387"
3138 {
3139   if (STACK_TOP_P (operands[0]))
3140     return "fxch\t%1";
3141   else
3142     return "fxch\t%0";
3143 }
3144   [(set_attr "type" "fxch")
3145    (set_attr "mode" "DF")])
3146
3147 (define_expand "movxf"
3148   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3149         (match_operand:XF 1 "general_operand" ""))]
3150   ""
3151   "ix86_expand_move (XFmode, operands); DONE;")
3152
3153 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3154 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3155 ;; Pushing using integer instructions is longer except for constants
3156 ;; and direct memory references.
3157 ;; (assuming that any given constant is pushed only once, but this ought to be
3158 ;;  handled elsewhere).
3159
3160 (define_insn "*pushxf_nointeger"
3161   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3162         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3163   "optimize_size"
3164 {
3165   /* This insn should be already split before reg-stack.  */
3166   gcc_unreachable ();
3167 }
3168   [(set_attr "type" "multi")
3169    (set_attr "unit" "i387,*,*")
3170    (set_attr "mode" "XF,SI,SI")])
3171
3172 (define_insn "*pushxf_integer"
3173   [(set (match_operand:XF 0 "push_operand" "=<,<")
3174         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3175   "!optimize_size"
3176 {
3177   /* This insn should be already split before reg-stack.  */
3178   gcc_unreachable ();
3179 }
3180   [(set_attr "type" "multi")
3181    (set_attr "unit" "i387,*")
3182    (set_attr "mode" "XF,SI")])
3183
3184 (define_split
3185   [(set (match_operand 0 "push_operand" "")
3186         (match_operand 1 "general_operand" ""))]
3187   "reload_completed
3188    && (GET_MODE (operands[0]) == XFmode
3189        || GET_MODE (operands[0]) == DFmode)
3190    && !ANY_FP_REG_P (operands[1])"
3191   [(const_int 0)]
3192   "ix86_split_long_move (operands); DONE;")
3193
3194 (define_split
3195   [(set (match_operand:XF 0 "push_operand" "")
3196         (match_operand:XF 1 "any_fp_register_operand" ""))]
3197   "!TARGET_64BIT"
3198   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3199    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
3200   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3201
3202 (define_split
3203   [(set (match_operand:XF 0 "push_operand" "")
3204         (match_operand:XF 1 "any_fp_register_operand" ""))]
3205   "TARGET_64BIT"
3206   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3207    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
3208   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3209
3210 ;; Do not use integer registers when optimizing for size
3211 (define_insn "*movxf_nointeger"
3212   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3213         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3214   "optimize_size
3215    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3216    && (reload_in_progress || reload_completed
3217        || (optimize_size && standard_80387_constant_p (operands[1]))
3218        || GET_CODE (operands[1]) != CONST_DOUBLE
3219        || memory_operand (operands[0], XFmode))"
3220 {
3221   switch (which_alternative)
3222     {
3223     case 0:
3224     case 1:
3225       return output_387_reg_move (insn, operands);
3226
3227     case 2:
3228       return standard_80387_constant_opcode (operands[1]);
3229
3230     case 3: case 4:
3231       return "#";
3232     default:
3233       gcc_unreachable ();
3234     }
3235 }
3236   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3237    (set_attr "mode" "XF,XF,XF,SI,SI")])
3238
3239 (define_insn "*movxf_integer"
3240   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3241         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3242   "!optimize_size
3243    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3244    && (reload_in_progress || reload_completed
3245        || (optimize_size && standard_80387_constant_p (operands[1]))
3246        || GET_CODE (operands[1]) != CONST_DOUBLE
3247        || memory_operand (operands[0], XFmode))"
3248 {
3249   switch (which_alternative)
3250     {
3251     case 0:
3252     case 1:
3253       return output_387_reg_move (insn, operands);
3254
3255     case 2:
3256       return standard_80387_constant_opcode (operands[1]);
3257
3258     case 3: case 4:
3259       return "#";
3260
3261     default:
3262       gcc_unreachable ();
3263     }
3264 }
3265   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3266    (set_attr "mode" "XF,XF,XF,SI,SI")])
3267
3268 (define_expand "movtf"
3269   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3270         (match_operand:TF 1 "nonimmediate_operand" ""))]
3271   "TARGET_64BIT"
3272 {
3273   ix86_expand_move (TFmode, operands);
3274   DONE;
3275 })
3276
3277 (define_insn "*movtf_internal"
3278   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3279         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3280   "TARGET_64BIT
3281    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3282 {
3283   switch (which_alternative)
3284     {
3285     case 0:
3286     case 1:
3287       if (get_attr_mode (insn) == MODE_V4SF)
3288         return "movaps\t{%1, %0|%0, %1}";
3289       else
3290         return "movdqa\t{%1, %0|%0, %1}";
3291     case 2:
3292       if (get_attr_mode (insn) == MODE_V4SF)
3293         return "xorps\t%0, %0";
3294       else
3295         return "pxor\t%0, %0";
3296     case 3:
3297     case 4:
3298         return "#";
3299     default:
3300       gcc_unreachable ();
3301     }
3302 }
3303   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3304    (set (attr "mode")
3305         (cond [(eq_attr "alternative" "0,2")
3306                  (if_then_else
3307                    (ne (symbol_ref "optimize_size")
3308                        (const_int 0))
3309                    (const_string "V4SF")
3310                    (const_string "TI"))
3311                (eq_attr "alternative" "1")
3312                  (if_then_else
3313                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3314                             (const_int 0))
3315                         (ne (symbol_ref "optimize_size")
3316                             (const_int 0)))
3317                    (const_string "V4SF")
3318                    (const_string "TI"))]
3319                (const_string "DI")))])
3320
3321 (define_split
3322   [(set (match_operand 0 "nonimmediate_operand" "")
3323         (match_operand 1 "general_operand" ""))]
3324   "reload_completed
3325    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3326    && GET_MODE (operands[0]) == XFmode
3327    && ! (ANY_FP_REG_P (operands[0]) ||
3328          (GET_CODE (operands[0]) == SUBREG
3329           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3330    && ! (ANY_FP_REG_P (operands[1]) ||
3331          (GET_CODE (operands[1]) == SUBREG
3332           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3333   [(const_int 0)]
3334   "ix86_split_long_move (operands); DONE;")
3335
3336 (define_split
3337   [(set (match_operand 0 "register_operand" "")
3338         (match_operand 1 "memory_operand" ""))]
3339   "reload_completed
3340    && MEM_P (operands[1])
3341    && (GET_MODE (operands[0]) == TFmode
3342        || GET_MODE (operands[0]) == XFmode
3343        || GET_MODE (operands[0]) == SFmode
3344        || GET_MODE (operands[0]) == DFmode)
3345    && (operands[2] = find_constant_src (insn))"
3346   [(set (match_dup 0) (match_dup 2))]
3347 {
3348   rtx c = operands[2];
3349   rtx r = operands[0];
3350
3351   if (GET_CODE (r) == SUBREG)
3352     r = SUBREG_REG (r);
3353
3354   if (SSE_REG_P (r))
3355     {
3356       if (!standard_sse_constant_p (c))
3357         FAIL;
3358     }
3359   else if (FP_REG_P (r))
3360     {
3361       if (!standard_80387_constant_p (c))
3362         FAIL;
3363     }
3364   else if (MMX_REG_P (r))
3365     FAIL;
3366 })
3367
3368 (define_split
3369   [(set (match_operand 0 "register_operand" "")
3370         (float_extend (match_operand 1 "memory_operand" "")))]
3371   "reload_completed
3372    && MEM_P (operands[1])
3373    && (GET_MODE (operands[0]) == TFmode
3374        || GET_MODE (operands[0]) == XFmode
3375        || GET_MODE (operands[0]) == SFmode
3376        || GET_MODE (operands[0]) == DFmode)
3377    && (operands[2] = find_constant_src (insn))"
3378   [(set (match_dup 0) (match_dup 2))]
3379 {
3380   rtx c = operands[2];
3381   rtx r = operands[0];
3382
3383   if (GET_CODE (r) == SUBREG)
3384     r = SUBREG_REG (r);
3385
3386   if (SSE_REG_P (r))
3387     {
3388       if (!standard_sse_constant_p (c))
3389         FAIL;
3390     }
3391   else if (FP_REG_P (r))
3392     {
3393       if (!standard_80387_constant_p (c))
3394         FAIL;
3395     }
3396   else if (MMX_REG_P (r))
3397     FAIL;
3398 })
3399
3400 (define_insn "swapxf"
3401   [(set (match_operand:XF 0 "register_operand" "+f")
3402         (match_operand:XF 1 "register_operand" "+f"))
3403    (set (match_dup 1)
3404         (match_dup 0))]
3405   "TARGET_80387"
3406 {
3407   if (STACK_TOP_P (operands[0]))
3408     return "fxch\t%1";
3409   else
3410     return "fxch\t%0";
3411 }
3412   [(set_attr "type" "fxch")
3413    (set_attr "mode" "XF")])
3414
3415 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3416 (define_split
3417   [(set (match_operand:X87MODEF 0 "register_operand" "")
3418         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3419   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3420    && (standard_80387_constant_p (operands[1]) == 8
3421        || standard_80387_constant_p (operands[1]) == 9)"
3422   [(set (match_dup 0)(match_dup 1))
3423    (set (match_dup 0)
3424         (neg:X87MODEF (match_dup 0)))]
3425 {
3426   REAL_VALUE_TYPE r;
3427
3428   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3429   if (real_isnegzero (&r))
3430     operands[1] = CONST0_RTX (<MODE>mode);
3431   else
3432     operands[1] = CONST1_RTX (<MODE>mode);
3433 })
3434
3435 (define_split
3436   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3437         (match_operand:TF 1 "general_operand" ""))]
3438   "reload_completed
3439    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3440   [(const_int 0)]
3441   "ix86_split_long_move (operands); DONE;")
3442 \f
3443 ;; Zero extension instructions
3444
3445 (define_expand "zero_extendhisi2"
3446   [(set (match_operand:SI 0 "register_operand" "")
3447      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3448   ""
3449 {
3450   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3451     {
3452       operands[1] = force_reg (HImode, operands[1]);
3453       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3454       DONE;
3455     }
3456 })
3457
3458 (define_insn "zero_extendhisi2_and"
3459   [(set (match_operand:SI 0 "register_operand" "=r")
3460      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3461    (clobber (reg:CC FLAGS_REG))]
3462   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3463   "#"
3464   [(set_attr "type" "alu1")
3465    (set_attr "mode" "SI")])
3466
3467 (define_split
3468   [(set (match_operand:SI 0 "register_operand" "")
3469         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3470    (clobber (reg:CC FLAGS_REG))]
3471   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3472   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3473               (clobber (reg:CC FLAGS_REG))])]
3474   "")
3475
3476 (define_insn "*zero_extendhisi2_movzwl"
3477   [(set (match_operand:SI 0 "register_operand" "=r")
3478      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3479   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3480   "movz{wl|x}\t{%1, %0|%0, %1}"
3481   [(set_attr "type" "imovx")
3482    (set_attr "mode" "SI")])
3483
3484 (define_expand "zero_extendqihi2"
3485   [(parallel
3486     [(set (match_operand:HI 0 "register_operand" "")
3487        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3488      (clobber (reg:CC FLAGS_REG))])]
3489   ""
3490   "")
3491
3492 (define_insn "*zero_extendqihi2_and"
3493   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3494      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3495    (clobber (reg:CC FLAGS_REG))]
3496   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3497   "#"
3498   [(set_attr "type" "alu1")
3499    (set_attr "mode" "HI")])
3500
3501 (define_insn "*zero_extendqihi2_movzbw_and"
3502   [(set (match_operand:HI 0 "register_operand" "=r,r")
3503      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3504    (clobber (reg:CC FLAGS_REG))]
3505   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3506   "#"
3507   [(set_attr "type" "imovx,alu1")
3508    (set_attr "mode" "HI")])
3509
3510 ; zero extend to SImode here to avoid partial register stalls
3511 (define_insn "*zero_extendqihi2_movzbl"
3512   [(set (match_operand:HI 0 "register_operand" "=r")
3513      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3514   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3515   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3516   [(set_attr "type" "imovx")
3517    (set_attr "mode" "SI")])
3518
3519 ;; For the movzbw case strip only the clobber
3520 (define_split
3521   [(set (match_operand:HI 0 "register_operand" "")
3522         (zero_extend:HI (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_operand:HI 0 "register_operand" "")
3528         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
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:HI 0 "register_operand" "")
3534         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3535    (clobber (reg:CC FLAGS_REG))]
3536   "reload_completed
3537    && ANY_QI_REG_P (operands[0])
3538    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3539    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3540   [(set (match_dup 0) (const_int 0))
3541    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3542   "operands[2] = gen_lowpart (QImode, operands[0]);")
3543
3544 ;; Rest is handled by single and.
3545 (define_split
3546   [(set (match_operand:HI 0 "register_operand" "")
3547         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3548    (clobber (reg:CC FLAGS_REG))]
3549   "reload_completed
3550    && true_regnum (operands[0]) == true_regnum (operands[1])"
3551   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3552               (clobber (reg:CC FLAGS_REG))])]
3553   "")
3554
3555 (define_expand "zero_extendqisi2"
3556   [(parallel
3557     [(set (match_operand:SI 0 "register_operand" "")
3558        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3559      (clobber (reg:CC FLAGS_REG))])]
3560   ""
3561   "")
3562
3563 (define_insn "*zero_extendqisi2_and"
3564   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3565      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3566    (clobber (reg:CC FLAGS_REG))]
3567   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3568   "#"
3569   [(set_attr "type" "alu1")
3570    (set_attr "mode" "SI")])
3571
3572 (define_insn "*zero_extendqisi2_movzbw_and"
3573   [(set (match_operand:SI 0 "register_operand" "=r,r")
3574      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3575    (clobber (reg:CC FLAGS_REG))]
3576   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3577   "#"
3578   [(set_attr "type" "imovx,alu1")
3579    (set_attr "mode" "SI")])
3580
3581 (define_insn "*zero_extendqisi2_movzbw"
3582   [(set (match_operand:SI 0 "register_operand" "=r")
3583      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3584   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3585   "movz{bl|x}\t{%1, %0|%0, %1}"
3586   [(set_attr "type" "imovx")
3587    (set_attr "mode" "SI")])
3588
3589 ;; For the movzbl case strip only the clobber
3590 (define_split
3591   [(set (match_operand:SI 0 "register_operand" "")
3592         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3593    (clobber (reg:CC FLAGS_REG))]
3594   "reload_completed
3595    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3596    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3597   [(set (match_dup 0)
3598         (zero_extend:SI (match_dup 1)))])
3599
3600 ;; When source and destination does not overlap, clear destination
3601 ;; first and then do the movb
3602 (define_split
3603   [(set (match_operand:SI 0 "register_operand" "")
3604         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3605    (clobber (reg:CC FLAGS_REG))]
3606   "reload_completed
3607    && ANY_QI_REG_P (operands[0])
3608    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3609    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3610    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3611   [(set (match_dup 0) (const_int 0))
3612    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3613   "operands[2] = gen_lowpart (QImode, operands[0]);")
3614
3615 ;; Rest is handled by single and.
3616 (define_split
3617   [(set (match_operand:SI 0 "register_operand" "")
3618         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3619    (clobber (reg:CC FLAGS_REG))]
3620   "reload_completed
3621    && true_regnum (operands[0]) == true_regnum (operands[1])"
3622   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3623               (clobber (reg:CC FLAGS_REG))])]
3624   "")
3625
3626 ;; %%% Kill me once multi-word ops are sane.
3627 (define_expand "zero_extendsidi2"
3628   [(set (match_operand:DI 0 "register_operand" "")
3629      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3630   ""
3631 {
3632   if (!TARGET_64BIT)
3633     {
3634       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3635       DONE;
3636     }
3637 })
3638
3639 (define_insn "zero_extendsidi2_32"
3640   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3641         (zero_extend:DI
3642          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3643    (clobber (reg:CC FLAGS_REG))]
3644   "!TARGET_64BIT"
3645   "@
3646    #
3647    #
3648    #
3649    movd\t{%1, %0|%0, %1}
3650    movd\t{%1, %0|%0, %1}
3651    movd\t{%1, %0|%0, %1}
3652    movd\t{%1, %0|%0, %1}"
3653   [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3654    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3655
3656 (define_insn "zero_extendsidi2_rex64"
3657   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3658      (zero_extend:DI
3659        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3660   "TARGET_64BIT"
3661   "@
3662    mov\t{%k1, %k0|%k0, %k1}
3663    #
3664    movd\t{%1, %0|%0, %1}
3665    movd\t{%1, %0|%0, %1}
3666    movd\t{%1, %0|%0, %1}
3667    movd\t{%1, %0|%0, %1}"
3668   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3669    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3670
3671 (define_split
3672   [(set (match_operand:DI 0 "memory_operand" "")
3673      (zero_extend:DI (match_dup 0)))]
3674   "TARGET_64BIT"
3675   [(set (match_dup 4) (const_int 0))]
3676   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3677
3678 (define_split
3679   [(set (match_operand:DI 0 "register_operand" "")
3680         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3681    (clobber (reg:CC FLAGS_REG))]
3682   "!TARGET_64BIT && reload_completed
3683    && true_regnum (operands[0]) == true_regnum (operands[1])"
3684   [(set (match_dup 4) (const_int 0))]
3685   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3686
3687 (define_split
3688   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3689         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3690    (clobber (reg:CC FLAGS_REG))]
3691   "!TARGET_64BIT && reload_completed
3692    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3693   [(set (match_dup 3) (match_dup 1))
3694    (set (match_dup 4) (const_int 0))]
3695   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3696
3697 (define_insn "zero_extendhidi2"
3698   [(set (match_operand:DI 0 "register_operand" "=r")
3699      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3700   "TARGET_64BIT"
3701   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3702   [(set_attr "type" "imovx")
3703    (set_attr "mode" "DI")])
3704
3705 (define_insn "zero_extendqidi2"
3706   [(set (match_operand:DI 0 "register_operand" "=r")
3707      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3708   "TARGET_64BIT"
3709   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3710   [(set_attr "type" "imovx")
3711    (set_attr "mode" "DI")])
3712 \f
3713 ;; Sign extension instructions
3714
3715 (define_expand "extendsidi2"
3716   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3717                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3718               (clobber (reg:CC FLAGS_REG))
3719               (clobber (match_scratch:SI 2 ""))])]
3720   ""
3721 {
3722   if (TARGET_64BIT)
3723     {
3724       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3725       DONE;
3726     }
3727 })
3728
3729 (define_insn "*extendsidi2_1"
3730   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3731         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3732    (clobber (reg:CC FLAGS_REG))
3733    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3734   "!TARGET_64BIT"
3735   "#")
3736
3737 (define_insn "extendsidi2_rex64"
3738   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3739         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3740   "TARGET_64BIT"
3741   "@
3742    {cltq|cdqe}
3743    movs{lq|x}\t{%1,%0|%0, %1}"
3744   [(set_attr "type" "imovx")
3745    (set_attr "mode" "DI")
3746    (set_attr "prefix_0f" "0")
3747    (set_attr "modrm" "0,1")])
3748
3749 (define_insn "extendhidi2"
3750   [(set (match_operand:DI 0 "register_operand" "=r")
3751         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3752   "TARGET_64BIT"
3753   "movs{wq|x}\t{%1,%0|%0, %1}"
3754   [(set_attr "type" "imovx")
3755    (set_attr "mode" "DI")])
3756
3757 (define_insn "extendqidi2"
3758   [(set (match_operand:DI 0 "register_operand" "=r")
3759         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3760   "TARGET_64BIT"
3761   "movs{bq|x}\t{%1,%0|%0, %1}"
3762    [(set_attr "type" "imovx")
3763     (set_attr "mode" "DI")])
3764
3765 ;; Extend to memory case when source register does die.
3766 (define_split
3767   [(set (match_operand:DI 0 "memory_operand" "")
3768         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3769    (clobber (reg:CC FLAGS_REG))
3770    (clobber (match_operand:SI 2 "register_operand" ""))]
3771   "(reload_completed
3772     && dead_or_set_p (insn, operands[1])
3773     && !reg_mentioned_p (operands[1], operands[0]))"
3774   [(set (match_dup 3) (match_dup 1))
3775    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3776               (clobber (reg:CC FLAGS_REG))])
3777    (set (match_dup 4) (match_dup 1))]
3778   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3779
3780 ;; Extend to memory case when source register does not die.
3781 (define_split
3782   [(set (match_operand:DI 0 "memory_operand" "")
3783         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3784    (clobber (reg:CC FLAGS_REG))
3785    (clobber (match_operand:SI 2 "register_operand" ""))]
3786   "reload_completed"
3787   [(const_int 0)]
3788 {
3789   split_di (&operands[0], 1, &operands[3], &operands[4]);
3790
3791   emit_move_insn (operands[3], operands[1]);
3792
3793   /* Generate a cltd if possible and doing so it profitable.  */
3794   if ((optimize_size || TARGET_USE_CLTD)
3795       && true_regnum (operands[1]) == AX_REG
3796       && true_regnum (operands[2]) == DX_REG)
3797     {
3798       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3799     }
3800   else
3801     {
3802       emit_move_insn (operands[2], operands[1]);
3803       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3804     }
3805   emit_move_insn (operands[4], operands[2]);
3806   DONE;
3807 })
3808
3809 ;; Extend to register case.  Optimize case where source and destination
3810 ;; registers match and cases where we can use cltd.
3811 (define_split
3812   [(set (match_operand:DI 0 "register_operand" "")
3813         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3814    (clobber (reg:CC FLAGS_REG))
3815    (clobber (match_scratch:SI 2 ""))]
3816   "reload_completed"
3817   [(const_int 0)]
3818 {
3819   split_di (&operands[0], 1, &operands[3], &operands[4]);
3820
3821   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3822     emit_move_insn (operands[3], operands[1]);
3823
3824   /* Generate a cltd if possible and doing so it profitable.  */
3825   if ((optimize_size || TARGET_USE_CLTD)
3826       && true_regnum (operands[3]) == AX_REG)
3827     {
3828       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3829       DONE;
3830     }
3831
3832   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3833     emit_move_insn (operands[4], operands[1]);
3834
3835   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3836   DONE;
3837 })
3838
3839 (define_insn "extendhisi2"
3840   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3841         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3842   ""
3843 {
3844   switch (get_attr_prefix_0f (insn))
3845     {
3846     case 0:
3847       return "{cwtl|cwde}";
3848     default:
3849       return "movs{wl|x}\t{%1,%0|%0, %1}";
3850     }
3851 }
3852   [(set_attr "type" "imovx")
3853    (set_attr "mode" "SI")
3854    (set (attr "prefix_0f")
3855      ;; movsx is short decodable while cwtl is vector decoded.
3856      (if_then_else (and (eq_attr "cpu" "!k6")
3857                         (eq_attr "alternative" "0"))
3858         (const_string "0")
3859         (const_string "1")))
3860    (set (attr "modrm")
3861      (if_then_else (eq_attr "prefix_0f" "0")
3862         (const_string "0")
3863         (const_string "1")))])
3864
3865 (define_insn "*extendhisi2_zext"
3866   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3867         (zero_extend:DI
3868           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3869   "TARGET_64BIT"
3870 {
3871   switch (get_attr_prefix_0f (insn))
3872     {
3873     case 0:
3874       return "{cwtl|cwde}";
3875     default:
3876       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3877     }
3878 }
3879   [(set_attr "type" "imovx")
3880    (set_attr "mode" "SI")
3881    (set (attr "prefix_0f")
3882      ;; movsx is short decodable while cwtl is vector decoded.
3883      (if_then_else (and (eq_attr "cpu" "!k6")
3884                         (eq_attr "alternative" "0"))
3885         (const_string "0")
3886         (const_string "1")))
3887    (set (attr "modrm")
3888      (if_then_else (eq_attr "prefix_0f" "0")
3889         (const_string "0")
3890         (const_string "1")))])
3891
3892 (define_insn "extendqihi2"
3893   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3894         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3895   ""
3896 {
3897   switch (get_attr_prefix_0f (insn))
3898     {
3899     case 0:
3900       return "{cbtw|cbw}";
3901     default:
3902       return "movs{bw|x}\t{%1,%0|%0, %1}";
3903     }
3904 }
3905   [(set_attr "type" "imovx")
3906    (set_attr "mode" "HI")
3907    (set (attr "prefix_0f")
3908      ;; movsx is short decodable while cwtl is vector decoded.
3909      (if_then_else (and (eq_attr "cpu" "!k6")
3910                         (eq_attr "alternative" "0"))
3911         (const_string "0")
3912         (const_string "1")))
3913    (set (attr "modrm")
3914      (if_then_else (eq_attr "prefix_0f" "0")
3915         (const_string "0")
3916         (const_string "1")))])
3917
3918 (define_insn "extendqisi2"
3919   [(set (match_operand:SI 0 "register_operand" "=r")
3920         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3921   ""
3922   "movs{bl|x}\t{%1,%0|%0, %1}"
3923    [(set_attr "type" "imovx")
3924     (set_attr "mode" "SI")])
3925
3926 (define_insn "*extendqisi2_zext"
3927   [(set (match_operand:DI 0 "register_operand" "=r")
3928         (zero_extend:DI
3929           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3930   "TARGET_64BIT"
3931   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3932    [(set_attr "type" "imovx")
3933     (set_attr "mode" "SI")])
3934 \f
3935 ;; Conversions between float and double.
3936
3937 ;; These are all no-ops in the model used for the 80387.  So just
3938 ;; emit moves.
3939
3940 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3941 (define_insn "*dummy_extendsfdf2"
3942   [(set (match_operand:DF 0 "push_operand" "=<")
3943         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3944   "0"
3945   "#")
3946
3947 (define_split
3948   [(set (match_operand:DF 0 "push_operand" "")
3949         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3950   "!TARGET_64BIT"
3951   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3952    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3953
3954 (define_split
3955   [(set (match_operand:DF 0 "push_operand" "")
3956         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3957   "TARGET_64BIT"
3958   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3959    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3960
3961 (define_insn "*dummy_extendsfxf2"
3962   [(set (match_operand:XF 0 "push_operand" "=<")
3963         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3964   "0"
3965   "#")
3966
3967 (define_split
3968   [(set (match_operand:XF 0 "push_operand" "")
3969         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3970   ""
3971   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3972    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3973   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3974
3975 (define_split
3976   [(set (match_operand:XF 0 "push_operand" "")
3977         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3978   "TARGET_64BIT"
3979   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3980    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3981   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3982
3983 (define_split
3984   [(set (match_operand:XF 0 "push_operand" "")
3985         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3986   ""
3987   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3988    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3989   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3990
3991 (define_split
3992   [(set (match_operand:XF 0 "push_operand" "")
3993         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3994   "TARGET_64BIT"
3995   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3996    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3997   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3998
3999 (define_expand "extendsfdf2"
4000   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4001         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4002   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4003 {
4004   /* ??? Needed for compress_float_constant since all fp constants
4005      are LEGITIMATE_CONSTANT_P.  */
4006   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4007     {
4008       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4009           && standard_80387_constant_p (operands[1]) > 0)
4010         {
4011           operands[1] = simplify_const_unary_operation
4012             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4013           emit_move_insn_1 (operands[0], operands[1]);
4014           DONE;
4015         }
4016       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4017     }
4018 })
4019
4020 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4021    cvtss2sd:
4022       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4023       cvtps2pd xmm2,xmm1
4024    We do the conversion post reload to avoid producing of 128bit spills
4025    that might lead to ICE on 32bit target.  The sequence unlikely combine
4026    anyway.  */
4027 (define_split
4028   [(set (match_operand:DF 0 "register_operand" "")
4029         (float_extend:DF
4030           (match_operand:SF 1 "nonimmediate_operand" "")))]
4031   "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4032    && reload_completed && SSE_REG_P (operands[0])"
4033    [(set (match_dup 2)
4034          (float_extend:V2DF
4035            (vec_select:V2SF
4036              (match_dup 3)
4037              (parallel [(const_int 0) (const_int 1)]))))]
4038 {
4039   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4040   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4041   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4042      Try to avoid move when unpacking can be done in source.  */
4043   if (REG_P (operands[1]))
4044     {
4045       /* If it is unsafe to overwrite upper half of source, we need
4046          to move to destination and unpack there.  */
4047       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4048            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4049           && true_regnum (operands[0]) != true_regnum (operands[1]))
4050         {
4051           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4052           emit_move_insn (tmp, operands[1]);
4053         }
4054       else
4055         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4056       emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4057     }
4058   else
4059     emit_insn (gen_vec_setv4sf_0 (operands[3],
4060                                   CONST0_RTX (V4SFmode), operands[1]));
4061 })
4062
4063 (define_insn "*extendsfdf2_mixed"
4064   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4065         (float_extend:DF
4066           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4067   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4068 {
4069   switch (which_alternative)
4070     {
4071     case 0:
4072     case 1:
4073       return output_387_reg_move (insn, operands);
4074
4075     case 2:
4076       return "cvtss2sd\t{%1, %0|%0, %1}";
4077
4078     default:
4079       gcc_unreachable ();
4080     }
4081 }
4082   [(set_attr "type" "fmov,fmov,ssecvt")
4083    (set_attr "mode" "SF,XF,DF")])
4084
4085 (define_insn "*extendsfdf2_sse"
4086   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4087         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4088   "TARGET_SSE2 && TARGET_SSE_MATH"
4089   "cvtss2sd\t{%1, %0|%0, %1}"
4090   [(set_attr "type" "ssecvt")
4091    (set_attr "mode" "DF")])
4092
4093 (define_insn "*extendsfdf2_i387"
4094   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4095         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4096   "TARGET_80387"
4097   "* return output_387_reg_move (insn, operands);"
4098   [(set_attr "type" "fmov")
4099    (set_attr "mode" "SF,XF")])
4100
4101 (define_expand "extend<mode>xf2"
4102   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4103         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4104   "TARGET_80387"
4105 {
4106   /* ??? Needed for compress_float_constant since all fp constants
4107      are LEGITIMATE_CONSTANT_P.  */
4108   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4109     {
4110       if (standard_80387_constant_p (operands[1]) > 0)
4111         {
4112           operands[1] = simplify_const_unary_operation
4113             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4114           emit_move_insn_1 (operands[0], operands[1]);
4115           DONE;
4116         }
4117       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4118     }
4119 })
4120
4121 (define_insn "*extend<mode>xf2_i387"
4122   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4123         (float_extend:XF
4124           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4125   "TARGET_80387"
4126   "* return output_387_reg_move (insn, operands);"
4127   [(set_attr "type" "fmov")
4128    (set_attr "mode" "<MODE>,XF")])
4129
4130 ;; %%% This seems bad bad news.
4131 ;; This cannot output into an f-reg because there is no way to be sure
4132 ;; of truncating in that case.  Otherwise this is just like a simple move
4133 ;; insn.  So we pretend we can output to a reg in order to get better
4134 ;; register preferencing, but we really use a stack slot.
4135
4136 ;; Conversion from DFmode to SFmode.
4137
4138 (define_expand "truncdfsf2"
4139   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4140         (float_truncate:SF
4141           (match_operand:DF 1 "nonimmediate_operand" "")))]
4142   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4143 {
4144   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4145     ;
4146   else if (flag_unsafe_math_optimizations)
4147     ;
4148   else
4149     {
4150       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4151       rtx temp = assign_386_stack_local (SFmode, slot);
4152       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4153       DONE;
4154     }
4155 })
4156
4157 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4158    cvtsd2ss:
4159       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4160       cvtpd2ps xmm2,xmm1
4161    We do the conversion post reload to avoid producing of 128bit spills
4162    that might lead to ICE on 32bit target.  The sequence unlikely combine
4163    anyway.  */
4164 (define_split
4165   [(set (match_operand:SF 0 "register_operand" "")
4166         (float_truncate:SF
4167           (match_operand:DF 1 "nonimmediate_operand" "")))]
4168   "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4169    && reload_completed && SSE_REG_P (operands[0])"
4170    [(set (match_dup 2)
4171          (vec_concat:V4SF
4172            (float_truncate:V2SF
4173              (match_dup 4))
4174            (match_dup 3)))]
4175 {
4176   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4177   operands[3] = CONST0_RTX (V2SFmode);
4178   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4179   /* Use movsd for loading from memory, unpcklpd for registers.
4180      Try to avoid move when unpacking can be done in source, or SSE3
4181      movddup is available.  */
4182   if (REG_P (operands[1]))
4183     {
4184       if (!TARGET_SSE3
4185           && true_regnum (operands[0]) != true_regnum (operands[1])
4186           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4187               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4188         {
4189           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4190           emit_move_insn (tmp, operands[1]);
4191           operands[1] = tmp;
4192         }
4193       else if (!TARGET_SSE3)
4194         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4195       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4196     }
4197   else
4198     emit_insn (gen_sse2_loadlpd (operands[4],
4199                                  CONST0_RTX (V2DFmode), operands[1]));
4200 })
4201
4202 (define_expand "truncdfsf2_with_temp"
4203   [(parallel [(set (match_operand:SF 0 "" "")
4204                    (float_truncate:SF (match_operand:DF 1 "" "")))
4205               (clobber (match_operand:SF 2 "" ""))])]
4206   "")
4207
4208 (define_insn "*truncdfsf_fast_mixed"
4209   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4210         (float_truncate:SF
4211           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4212   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4213 {
4214   switch (which_alternative)
4215     {
4216     case 0:
4217       return output_387_reg_move (insn, operands);
4218     case 1:
4219       return "cvtsd2ss\t{%1, %0|%0, %1}";
4220     default:
4221       gcc_unreachable ();
4222     }
4223 }
4224   [(set_attr "type" "fmov,ssecvt")
4225    (set_attr "mode" "SF")])
4226
4227 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4228 ;; because nothing we do here is unsafe.
4229 (define_insn "*truncdfsf_fast_sse"
4230   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4231         (float_truncate:SF
4232           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4233   "TARGET_SSE2 && TARGET_SSE_MATH"
4234   "cvtsd2ss\t{%1, %0|%0, %1}"
4235   [(set_attr "type" "ssecvt")
4236    (set_attr "mode" "SF")])
4237
4238 (define_insn "*truncdfsf_fast_i387"
4239   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4240         (float_truncate:SF
4241           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4242   "TARGET_80387 && flag_unsafe_math_optimizations"
4243   "* return output_387_reg_move (insn, operands);"
4244   [(set_attr "type" "fmov")
4245    (set_attr "mode" "SF")])
4246
4247 (define_insn "*truncdfsf_mixed"
4248   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y2")
4249         (float_truncate:SF
4250           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Y2m")))
4251    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
4252   "TARGET_MIX_SSE_I387"
4253 {
4254   switch (which_alternative)
4255     {
4256     case 0:
4257       return output_387_reg_move (insn, operands);
4258
4259     case 1:
4260       return "#";
4261     case 2:
4262       return "cvtsd2ss\t{%1, %0|%0, %1}";
4263     default:
4264       gcc_unreachable ();
4265     }
4266 }
4267   [(set_attr "type" "fmov,multi,ssecvt")
4268    (set_attr "unit" "*,i387,*")
4269    (set_attr "mode" "SF")])
4270
4271 (define_insn "*truncdfsf_i387"
4272   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4273         (float_truncate:SF
4274           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4275    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4276   "TARGET_80387"
4277 {
4278   switch (which_alternative)
4279     {
4280     case 0:
4281       return output_387_reg_move (insn, operands);
4282
4283     case 1:
4284       return "#";
4285     default:
4286       gcc_unreachable ();
4287     }
4288 }
4289   [(set_attr "type" "fmov,multi")
4290    (set_attr "unit" "*,i387")
4291    (set_attr "mode" "SF")])
4292
4293 (define_insn "*truncdfsf2_i387_1"
4294   [(set (match_operand:SF 0 "memory_operand" "=m")
4295         (float_truncate:SF
4296           (match_operand:DF 1 "register_operand" "f")))]
4297   "TARGET_80387
4298    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4299    && !TARGET_MIX_SSE_I387"
4300   "* return output_387_reg_move (insn, operands);"
4301   [(set_attr "type" "fmov")
4302    (set_attr "mode" "SF")])
4303
4304 (define_split
4305   [(set (match_operand:SF 0 "register_operand" "")
4306         (float_truncate:SF
4307          (match_operand:DF 1 "fp_register_operand" "")))
4308    (clobber (match_operand 2 "" ""))]
4309   "reload_completed"
4310   [(set (match_dup 2) (match_dup 1))
4311    (set (match_dup 0) (match_dup 2))]
4312 {
4313   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4314 })
4315
4316 ;; Conversion from XFmode to {SF,DF}mode
4317
4318 (define_expand "truncxf<mode>2"
4319   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4320                    (float_truncate:MODEF
4321                      (match_operand:XF 1 "register_operand" "")))
4322               (clobber (match_dup 2))])]
4323   "TARGET_80387"
4324 {
4325   if (flag_unsafe_math_optimizations)
4326     {
4327       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4328       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4329       if (reg != operands[0])
4330         emit_move_insn (operands[0], reg);
4331       DONE;
4332     }
4333   else
4334     {
4335       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4336       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4337     }
4338 })
4339
4340 (define_insn "*truncxfsf2_mixed"
4341   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4342         (float_truncate:SF
4343           (match_operand:XF 1 "register_operand" "f,f")))
4344    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4345   "TARGET_80387"
4346 {
4347   gcc_assert (!which_alternative);
4348   return output_387_reg_move (insn, operands);
4349 }
4350   [(set_attr "type" "fmov,multi")
4351    (set_attr "unit" "*,i387")
4352    (set_attr "mode" "SF")])
4353
4354 (define_insn "*truncxfdf2_mixed"
4355   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4356         (float_truncate:DF
4357           (match_operand:XF 1 "register_operand" "f,f")))
4358    (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4359   "TARGET_80387"
4360 {
4361   gcc_assert (!which_alternative);
4362   return output_387_reg_move (insn, operands);
4363 }
4364   [(set_attr "type" "fmov,multi")
4365    (set_attr "unit" "*,i387")
4366    (set_attr "mode" "DF")])
4367
4368 (define_insn "truncxf<mode>2_i387_noop"
4369   [(set (match_operand:MODEF 0 "register_operand" "=f")
4370         (float_truncate:MODEF
4371           (match_operand:XF 1 "register_operand" "f")))]
4372   "TARGET_80387 && flag_unsafe_math_optimizations"
4373   "* return output_387_reg_move (insn, operands);"
4374   [(set_attr "type" "fmov")
4375    (set_attr "mode" "<MODE>")])
4376
4377 (define_insn "*truncxf<mode>2_i387"
4378   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4379         (float_truncate:MODEF
4380           (match_operand:XF 1 "register_operand" "f")))]
4381   "TARGET_80387"
4382   "* return output_387_reg_move (insn, operands);"
4383   [(set_attr "type" "fmov")
4384    (set_attr "mode" "<MODE>")])
4385
4386 (define_split
4387   [(set (match_operand:MODEF 0 "register_operand" "")
4388         (float_truncate:MODEF
4389           (match_operand:XF 1 "register_operand" "")))
4390    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4391   "TARGET_80387 && reload_completed"
4392   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4393    (set (match_dup 0) (match_dup 2))]
4394   "")
4395
4396 (define_split
4397   [(set (match_operand:MODEF 0 "memory_operand" "")
4398         (float_truncate:MODEF
4399           (match_operand:XF 1 "register_operand" "")))
4400    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4401   "TARGET_80387"
4402   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4403   "")
4404 \f
4405 ;; Signed conversion to DImode.
4406
4407 (define_expand "fix_truncxfdi2"
4408   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4409                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4410               (clobber (reg:CC FLAGS_REG))])]
4411   "TARGET_80387"
4412 {
4413   if (TARGET_FISTTP)
4414    {
4415      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4416      DONE;
4417    }
4418 })
4419
4420 (define_expand "fix_trunc<mode>di2"
4421   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4422                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4423               (clobber (reg:CC FLAGS_REG))])]
4424   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4425 {
4426   if (TARGET_FISTTP
4427       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4428    {
4429      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4430      DONE;
4431    }
4432   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4433    {
4434      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4435      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4436      if (out != operands[0])
4437         emit_move_insn (operands[0], out);
4438      DONE;
4439    }
4440 })
4441
4442 ;; Signed conversion to SImode.
4443
4444 (define_expand "fix_truncxfsi2"
4445   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4446                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4447               (clobber (reg:CC FLAGS_REG))])]
4448   "TARGET_80387"
4449 {
4450   if (TARGET_FISTTP)
4451    {
4452      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4453      DONE;
4454    }
4455 })
4456
4457 (define_expand "fix_trunc<mode>si2"
4458   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4459                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4460               (clobber (reg:CC FLAGS_REG))])]
4461   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4462 {
4463   if (TARGET_FISTTP
4464       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4465    {
4466      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4467      DONE;
4468    }
4469   if (SSE_FLOAT_MODE_P (<MODE>mode))
4470    {
4471      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4472      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4473      if (out != operands[0])
4474         emit_move_insn (operands[0], out);
4475      DONE;
4476    }
4477 })
4478
4479 ;; Signed conversion to HImode.
4480
4481 (define_expand "fix_trunc<mode>hi2"
4482   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4483                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4484               (clobber (reg:CC FLAGS_REG))])]
4485   "TARGET_80387
4486    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4487 {
4488   if (TARGET_FISTTP)
4489    {
4490      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4491      DONE;
4492    }
4493 })
4494
4495 ;; Unsigned conversion to SImode.
4496
4497 (define_expand "fixuns_trunc<mode>si2"
4498   [(parallel
4499     [(set (match_operand:SI 0 "register_operand" "")
4500           (unsigned_fix:SI
4501             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4502      (use (match_dup 2))
4503      (clobber (match_scratch:<ssevecmode> 3 ""))
4504      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4505   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4506 {
4507   enum machine_mode mode = <MODE>mode;
4508   enum machine_mode vecmode = <ssevecmode>mode;
4509   REAL_VALUE_TYPE TWO31r;
4510   rtx two31;
4511
4512   real_ldexp (&TWO31r, &dconst1, 31);
4513   two31 = const_double_from_real_value (TWO31r, mode);
4514   two31 = ix86_build_const_vector (mode, true, two31);
4515   operands[2] = force_reg (vecmode, two31);
4516 })
4517
4518 (define_insn_and_split "*fixuns_trunc<mode>_1"
4519   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4520         (unsigned_fix:SI
4521           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4522    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4523    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4524    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4525   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4526   "#"
4527   "&& reload_completed"
4528   [(const_int 0)]
4529 {
4530   ix86_split_convert_uns_si_sse (operands);
4531   DONE;
4532 })
4533
4534 ;; Unsigned conversion to HImode.
4535 ;; Without these patterns, we'll try the unsigned SI conversion which
4536 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4537
4538 (define_expand "fixuns_trunc<mode>hi2"
4539   [(set (match_dup 2)
4540         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4541    (set (match_operand:HI 0 "nonimmediate_operand" "")
4542         (subreg:HI (match_dup 2) 0))]
4543   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4544   "operands[2] = gen_reg_rtx (SImode);")
4545
4546 ;; When SSE is available, it is always faster to use it!
4547 (define_insn "fix_trunc<mode>di_sse"
4548   [(set (match_operand:DI 0 "register_operand" "=r,r")
4549         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4550   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4551    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4552   "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4553   [(set_attr "type" "sseicvt")
4554    (set_attr "mode" "<MODE>")
4555    (set_attr "athlon_decode" "double,vector")
4556    (set_attr "amdfam10_decode" "double,double")])
4557
4558 (define_insn "fix_trunc<mode>si_sse"
4559   [(set (match_operand:SI 0 "register_operand" "=r,r")
4560         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4561   "SSE_FLOAT_MODE_P (<MODE>mode)
4562    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4563   "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4564   [(set_attr "type" "sseicvt")
4565    (set_attr "mode" "<MODE>")
4566    (set_attr "athlon_decode" "double,vector")
4567    (set_attr "amdfam10_decode" "double,double")])
4568
4569 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4570 (define_peephole2
4571   [(set (match_operand:MODEF 0 "register_operand" "")
4572         (match_operand:MODEF 1 "memory_operand" ""))
4573    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4574         (fix:SSEMODEI24 (match_dup 0)))]
4575   "TARGET_SHORTEN_X87_SSE
4576    && peep2_reg_dead_p (2, operands[0])"
4577   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4578   "")
4579
4580 ;; Avoid vector decoded forms of the instruction.
4581 (define_peephole2
4582   [(match_scratch:DF 2 "Y2")
4583    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4584         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4585   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4586   [(set (match_dup 2) (match_dup 1))
4587    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4588   "")
4589
4590 (define_peephole2
4591   [(match_scratch:SF 2 "x")
4592    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4593         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4594   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4595   [(set (match_dup 2) (match_dup 1))
4596    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4597   "")
4598
4599 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4600   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4601         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4602   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4603    && TARGET_FISTTP
4604    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4605          && (TARGET_64BIT || <MODE>mode != DImode))
4606         && TARGET_SSE_MATH)
4607    && !(reload_completed || reload_in_progress)"
4608   "#"
4609   "&& 1"
4610   [(const_int 0)]
4611 {
4612   if (memory_operand (operands[0], VOIDmode))
4613     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4614   else
4615     {
4616       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4617       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4618                                                             operands[1],
4619                                                             operands[2]));
4620     }
4621   DONE;
4622 }
4623   [(set_attr "type" "fisttp")
4624    (set_attr "mode" "<MODE>")])
4625
4626 (define_insn "fix_trunc<mode>_i387_fisttp"
4627   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4628         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4629    (clobber (match_scratch:XF 2 "=&1f"))]
4630   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4631    && TARGET_FISTTP
4632    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4633          && (TARGET_64BIT || <MODE>mode != DImode))
4634         && TARGET_SSE_MATH)"
4635   "* return output_fix_trunc (insn, operands, 1);"
4636   [(set_attr "type" "fisttp")
4637    (set_attr "mode" "<MODE>")])
4638
4639 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4640   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4641         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4642    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4643    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4644   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4645    && TARGET_FISTTP
4646    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4647         && (TARGET_64BIT || <MODE>mode != DImode))
4648         && TARGET_SSE_MATH)"
4649   "#"
4650   [(set_attr "type" "fisttp")
4651    (set_attr "mode" "<MODE>")])
4652
4653 (define_split
4654   [(set (match_operand:X87MODEI 0 "register_operand" "")
4655         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4656    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4657    (clobber (match_scratch 3 ""))]
4658   "reload_completed"
4659   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4660               (clobber (match_dup 3))])
4661    (set (match_dup 0) (match_dup 2))]
4662   "")
4663
4664 (define_split
4665   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4666         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4667    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4668    (clobber (match_scratch 3 ""))]
4669   "reload_completed"
4670   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4671               (clobber (match_dup 3))])]
4672   "")
4673
4674 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4675 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4676 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4677 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4678 ;; function in i386.c.
4679 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4680   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4681         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4682    (clobber (reg:CC FLAGS_REG))]
4683   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4684    && !TARGET_FISTTP
4685    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4686          && (TARGET_64BIT || <MODE>mode != DImode))
4687    && !(reload_completed || reload_in_progress)"
4688   "#"
4689   "&& 1"
4690   [(const_int 0)]
4691 {
4692   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4693
4694   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4695   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4696   if (memory_operand (operands[0], VOIDmode))
4697     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4698                                          operands[2], operands[3]));
4699   else
4700     {
4701       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4702       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4703                                                      operands[2], operands[3],
4704                                                      operands[4]));
4705     }
4706   DONE;
4707 }
4708   [(set_attr "type" "fistp")
4709    (set_attr "i387_cw" "trunc")
4710    (set_attr "mode" "<MODE>")])
4711
4712 (define_insn "fix_truncdi_i387"
4713   [(set (match_operand:DI 0 "memory_operand" "=m")
4714         (fix:DI (match_operand 1 "register_operand" "f")))
4715    (use (match_operand:HI 2 "memory_operand" "m"))
4716    (use (match_operand:HI 3 "memory_operand" "m"))
4717    (clobber (match_scratch:XF 4 "=&1f"))]
4718   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4719    && !TARGET_FISTTP
4720    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4721   "* return output_fix_trunc (insn, operands, 0);"
4722   [(set_attr "type" "fistp")
4723    (set_attr "i387_cw" "trunc")
4724    (set_attr "mode" "DI")])
4725
4726 (define_insn "fix_truncdi_i387_with_temp"
4727   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4728         (fix:DI (match_operand 1 "register_operand" "f,f")))
4729    (use (match_operand:HI 2 "memory_operand" "m,m"))
4730    (use (match_operand:HI 3 "memory_operand" "m,m"))
4731    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4732    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4733   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4734    && !TARGET_FISTTP
4735    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4736   "#"
4737   [(set_attr "type" "fistp")
4738    (set_attr "i387_cw" "trunc")
4739    (set_attr "mode" "DI")])
4740
4741 (define_split
4742   [(set (match_operand:DI 0 "register_operand" "")
4743         (fix:DI (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:DI 4 "memory_operand" ""))
4747    (clobber (match_scratch 5 ""))]
4748   "reload_completed"
4749   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4750               (use (match_dup 2))
4751               (use (match_dup 3))
4752               (clobber (match_dup 5))])
4753    (set (match_dup 0) (match_dup 4))]
4754   "")
4755
4756 (define_split
4757   [(set (match_operand:DI 0 "memory_operand" "")
4758         (fix:DI (match_operand 1 "register_operand" "")))
4759    (use (match_operand:HI 2 "memory_operand" ""))
4760    (use (match_operand:HI 3 "memory_operand" ""))
4761    (clobber (match_operand:DI 4 "memory_operand" ""))
4762    (clobber (match_scratch 5 ""))]
4763   "reload_completed"
4764   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4765               (use (match_dup 2))
4766               (use (match_dup 3))
4767               (clobber (match_dup 5))])]
4768   "")
4769
4770 (define_insn "fix_trunc<mode>_i387"
4771   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4772         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4773    (use (match_operand:HI 2 "memory_operand" "m"))
4774    (use (match_operand:HI 3 "memory_operand" "m"))]
4775   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4776    && !TARGET_FISTTP
4777    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4778   "* return output_fix_trunc (insn, operands, 0);"
4779   [(set_attr "type" "fistp")
4780    (set_attr "i387_cw" "trunc")
4781    (set_attr "mode" "<MODE>")])
4782
4783 (define_insn "fix_trunc<mode>_i387_with_temp"
4784   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4785         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4786    (use (match_operand:HI 2 "memory_operand" "m,m"))
4787    (use (match_operand:HI 3 "memory_operand" "m,m"))
4788    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4789   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4790    && !TARGET_FISTTP
4791    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4792   "#"
4793   [(set_attr "type" "fistp")
4794    (set_attr "i387_cw" "trunc")
4795    (set_attr "mode" "<MODE>")])
4796
4797 (define_split
4798   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4799         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4800    (use (match_operand:HI 2 "memory_operand" ""))
4801    (use (match_operand:HI 3 "memory_operand" ""))
4802    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4803   "reload_completed"
4804   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4805               (use (match_dup 2))
4806               (use (match_dup 3))])
4807    (set (match_dup 0) (match_dup 4))]
4808   "")
4809
4810 (define_split
4811   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4812         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4813    (use (match_operand:HI 2 "memory_operand" ""))
4814    (use (match_operand:HI 3 "memory_operand" ""))
4815    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4816   "reload_completed"
4817   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4818               (use (match_dup 2))
4819               (use (match_dup 3))])]
4820   "")
4821
4822 (define_insn "x86_fnstcw_1"
4823   [(set (match_operand:HI 0 "memory_operand" "=m")
4824         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4825   "TARGET_80387"
4826   "fnstcw\t%0"
4827   [(set_attr "length" "2")
4828    (set_attr "mode" "HI")
4829    (set_attr "unit" "i387")])
4830
4831 (define_insn "x86_fldcw_1"
4832   [(set (reg:HI FPCR_REG)
4833         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4834   "TARGET_80387"
4835   "fldcw\t%0"
4836   [(set_attr "length" "2")
4837    (set_attr "mode" "HI")
4838    (set_attr "unit" "i387")
4839    (set_attr "athlon_decode" "vector")
4840    (set_attr "amdfam10_decode" "vector")])
4841 \f
4842 ;; Conversion between fixed point and floating point.
4843
4844 ;; Even though we only accept memory inputs, the backend _really_
4845 ;; wants to be able to do this between registers.
4846
4847 (define_expand "floathi<mode>2"
4848   [(set (match_operand:X87MODEF 0 "register_operand" "")
4849         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4850   "TARGET_80387
4851    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4852        || TARGET_MIX_SSE_I387)"
4853   "")
4854
4855 ;; Pre-reload splitter to add memory clobber to the pattern.
4856 (define_insn_and_split "*floathi<mode>2_1"
4857   [(set (match_operand:X87MODEF 0 "register_operand" "")
4858         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4859   "TARGET_80387
4860    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4861        || TARGET_MIX_SSE_I387)
4862    && !(reload_completed || reload_in_progress)"
4863   "#"
4864   "&& 1"
4865   [(parallel [(set (match_dup 0)
4866               (float:X87MODEF (match_dup 1)))
4867    (clobber (match_dup 2))])]
4868   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4869
4870 (define_insn "*floathi<mode>2_i387_with_temp"
4871   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4872         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4873   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4874   "TARGET_80387
4875    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4876        || TARGET_MIX_SSE_I387)"
4877   "#"
4878   [(set_attr "type" "fmov,multi")
4879    (set_attr "mode" "<MODE>")
4880    (set_attr "unit" "*,i387")
4881    (set_attr "fp_int_src" "true")])
4882
4883 (define_insn "*floathi<mode>2_i387"
4884   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4885         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4886   "TARGET_80387
4887    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4888        || TARGET_MIX_SSE_I387)"
4889   "fild%z1\t%1"
4890   [(set_attr "type" "fmov")
4891    (set_attr "mode" "<MODE>")
4892    (set_attr "fp_int_src" "true")])
4893
4894 (define_split
4895   [(set (match_operand:X87MODEF 0 "register_operand" "")
4896         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4897    (clobber (match_operand:HI 2 "memory_operand" ""))]
4898   "TARGET_80387
4899    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4900        || TARGET_MIX_SSE_I387)
4901    && reload_completed"
4902   [(set (match_dup 2) (match_dup 1))
4903    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4904   "")
4905
4906 (define_split
4907   [(set (match_operand:X87MODEF 0 "register_operand" "")
4908         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4909    (clobber (match_operand:HI 2 "memory_operand" ""))]
4910    "TARGET_80387
4911     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4912         || TARGET_MIX_SSE_I387)
4913     && reload_completed"
4914   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
4915   "")
4916
4917 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4918   [(set (match_operand:X87MODEF 0 "register_operand" "")
4919         (float:X87MODEF
4920           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4921   "TARGET_80387
4922    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4923        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4924   "")
4925
4926 ;; Pre-reload splitter to add memory clobber to the pattern.
4927 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4928   [(set (match_operand:X87MODEF 0 "register_operand" "")
4929         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4930   "((TARGET_80387
4931      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4932            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4933          || TARGET_MIX_SSE_I387))
4934     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4935         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4936         && ((<SSEMODEI24:MODE>mode == SImode
4937              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4938              && flag_trapping_math)
4939             || !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size))))
4940    && !(reload_completed || reload_in_progress)"
4941   "#"
4942   "&& 1"
4943   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4944               (clobber (match_dup 2))])]
4945 {
4946   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4947
4948   /* Avoid store forwarding (partial memory) stall penalty
4949      by passing DImode value through XMM registers.  */
4950   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT 
4951       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES 
4952       && !optimize_size)
4953     {
4954       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4955                                                             operands[1],
4956                                                             operands[2]));
4957       DONE;
4958     }
4959 })
4960
4961 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4962   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4963         (float:MODEF
4964           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4965    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4966   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4967    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4968   "#"
4969   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4970    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4971    (set_attr "unit" "*,i387,*,*,*")
4972    (set_attr "athlon_decode" "*,*,double,direct,double")
4973    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4974    (set_attr "fp_int_src" "true")])
4975
4976 (define_insn "*floatsi<mode>2_vector_mixed"
4977   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4978         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4979   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4980    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4981   "@
4982    fild%z1\t%1
4983    #"
4984   [(set_attr "type" "fmov,sseicvt")
4985    (set_attr "mode" "<MODE>,<ssevecmode>")
4986    (set_attr "unit" "i387,*")
4987    (set_attr "athlon_decode" "*,direct")
4988    (set_attr "amdfam10_decode" "*,double")
4989    (set_attr "fp_int_src" "true")])
4990
4991 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
4992   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4993         (float:MODEF
4994           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
4995   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
4996   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4997    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4998   "#"
4999   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5000    (set_attr "mode" "<MODEF:MODE>")
5001    (set_attr "unit" "*,i387,*,*")
5002    (set_attr "athlon_decode" "*,*,double,direct")
5003    (set_attr "amdfam10_decode" "*,*,vector,double")
5004    (set_attr "fp_int_src" "true")])
5005
5006 (define_split
5007   [(set (match_operand:MODEF 0 "register_operand" "")
5008         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5009    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5010   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5011    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5012    && TARGET_INTER_UNIT_CONVERSIONS
5013    && reload_completed
5014    && (SSE_REG_P (operands[0])
5015        || (GET_CODE (operands[0]) == SUBREG
5016            && SSE_REG_P (operands[0])))"
5017   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5018   "")
5019
5020 (define_split
5021   [(set (match_operand:MODEF 0 "register_operand" "")
5022         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5023    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5024   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5025    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5026    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5027    && reload_completed
5028    && (SSE_REG_P (operands[0])
5029        || (GET_CODE (operands[0]) == SUBREG
5030            && SSE_REG_P (operands[0])))"
5031   [(set (match_dup 2) (match_dup 1))
5032    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5033   "")
5034
5035 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5036   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5037         (float:MODEF
5038           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5039   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5040    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5041    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5042   "@
5043    fild%z1\t%1
5044    cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}
5045    cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5046   [(set_attr "type" "fmov,sseicvt,sseicvt")
5047    (set_attr "mode" "<MODEF:MODE>")
5048    (set_attr "unit" "i387,*,*")
5049    (set_attr "athlon_decode" "*,double,direct")
5050    (set_attr "amdfam10_decode" "*,vector,double")
5051    (set_attr "fp_int_src" "true")])
5052
5053 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5054   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5055         (float:MODEF
5056           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5057   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5058    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5059    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5060   "@
5061    fild%z1\t%1
5062    cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5063   [(set_attr "type" "fmov,sseicvt")
5064    (set_attr "mode" "<MODEF:MODE>")
5065    (set_attr "athlon_decode" "*,direct")
5066    (set_attr "amdfam10_decode" "*,double")
5067    (set_attr "fp_int_src" "true")])
5068
5069 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5070   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5071         (float:MODEF
5072           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5073    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5074   "TARGET_SSE2 && TARGET_SSE_MATH
5075    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5076   "#"
5077   [(set_attr "type" "sseicvt")
5078    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5079    (set_attr "athlon_decode" "double,direct,double")
5080    (set_attr "amdfam10_decode" "vector,double,double")
5081    (set_attr "fp_int_src" "true")])
5082
5083 (define_insn "*floatsi<mode>2_vector_sse"
5084   [(set (match_operand:MODEF 0 "register_operand" "=x")
5085         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5086   "TARGET_SSE2 && TARGET_SSE_MATH
5087    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5088   "#"
5089   [(set_attr "type" "sseicvt")
5090    (set_attr "mode" "<MODE>")
5091    (set_attr "athlon_decode" "direct")
5092    (set_attr "amdfam10_decode" "double")
5093    (set_attr "fp_int_src" "true")])
5094
5095 (define_split
5096   [(set (match_operand:MODEF 0 "register_operand" "")
5097         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5098    (clobber (match_operand:SI 2 "memory_operand" ""))]
5099   "TARGET_SSE2 && TARGET_SSE_MATH
5100    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5101    && reload_completed
5102    && (SSE_REG_P (operands[0])
5103        || (GET_CODE (operands[0]) == SUBREG
5104            && SSE_REG_P (operands[0])))"
5105   [(const_int 0)]
5106 {
5107   rtx op1 = operands[1];
5108
5109   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5110                                      <MODE>mode, 0);
5111   if (GET_CODE (op1) == SUBREG)
5112     op1 = SUBREG_REG (op1);
5113
5114   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5115     {
5116       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5117       emit_insn (gen_sse2_loadld (operands[4],
5118                                   CONST0_RTX (V4SImode), operands[1]));
5119     }
5120   /* We can ignore possible trapping value in the
5121      high part of SSE register for non-trapping math. */
5122   else if (SSE_REG_P (op1) && !flag_trapping_math)
5123     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5124   else
5125     {
5126       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5127       emit_move_insn (operands[2], operands[1]);
5128       emit_insn (gen_sse2_loadld (operands[4],
5129                                   CONST0_RTX (V4SImode), operands[2]));
5130     }
5131   emit_insn
5132     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5133   DONE;
5134 })
5135
5136 (define_split
5137   [(set (match_operand:MODEF 0 "register_operand" "")
5138         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5139    (clobber (match_operand:SI 2 "memory_operand" ""))]
5140   "TARGET_SSE2 && TARGET_SSE_MATH
5141    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5142    && reload_completed
5143    && (SSE_REG_P (operands[0])
5144        || (GET_CODE (operands[0]) == SUBREG
5145            && SSE_REG_P (operands[0])))"
5146   [(const_int 0)]
5147 {
5148   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5149                                      <MODE>mode, 0);
5150   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5151
5152   emit_insn (gen_sse2_loadld (operands[4],
5153                               CONST0_RTX (V4SImode), operands[1]));
5154   emit_insn
5155     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5156   DONE;
5157 })
5158
5159 (define_split
5160   [(set (match_operand:MODEF 0 "register_operand" "")
5161         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5162   "TARGET_SSE2 && TARGET_SSE_MATH
5163    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5164    && reload_completed
5165    && (SSE_REG_P (operands[0])
5166        || (GET_CODE (operands[0]) == SUBREG
5167            && SSE_REG_P (operands[0])))"
5168   [(const_int 0)]
5169 {
5170   rtx op1 = operands[1];
5171
5172   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5173                                      <MODE>mode, 0);
5174   if (GET_CODE (op1) == SUBREG)
5175     op1 = SUBREG_REG (op1);
5176
5177   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5178     {
5179       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5180       emit_insn (gen_sse2_loadld (operands[4],
5181                                   CONST0_RTX (V4SImode), operands[1]));
5182     }
5183   /* We can ignore possible trapping value in the
5184      high part of SSE register for non-trapping math. */
5185   else if (SSE_REG_P (op1) && !flag_trapping_math)
5186     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5187   else
5188     gcc_unreachable ();
5189 })
5190
5191 (define_split
5192   [(set (match_operand:MODEF 0 "register_operand" "")
5193         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5194   "TARGET_SSE2 && TARGET_SSE_MATH
5195    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5196    && reload_completed
5197    && (SSE_REG_P (operands[0])
5198        || (GET_CODE (operands[0]) == SUBREG
5199            && SSE_REG_P (operands[0])))"
5200   [(const_int 0)]
5201 {
5202   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5203                                      <MODE>mode, 0);
5204   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5205
5206   emit_insn (gen_sse2_loadld (operands[4],
5207                               CONST0_RTX (V4SImode), operands[1]));
5208   emit_insn
5209     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5210   DONE;
5211 })
5212
5213 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5214   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5215         (float:MODEF
5216           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5217   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5218   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5219    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5220   "#"
5221   [(set_attr "type" "sseicvt")
5222    (set_attr "mode" "<MODEF:MODE>")
5223    (set_attr "athlon_decode" "double,direct")
5224    (set_attr "amdfam10_decode" "vector,double")
5225    (set_attr "fp_int_src" "true")])
5226
5227 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5228   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5229         (float:MODEF
5230           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5231   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5232    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5233    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5234   "cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5235   [(set_attr "type" "sseicvt")
5236    (set_attr "mode" "<MODEF:MODE>")
5237    (set_attr "athlon_decode" "double,direct")
5238    (set_attr "amdfam10_decode" "vector,double")
5239    (set_attr "fp_int_src" "true")])
5240
5241 (define_split
5242   [(set (match_operand:MODEF 0 "register_operand" "")
5243         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5244    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5245   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5246    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5247    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5248    && reload_completed
5249    && (SSE_REG_P (operands[0])
5250        || (GET_CODE (operands[0]) == SUBREG
5251            && SSE_REG_P (operands[0])))"
5252   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5253   "")
5254
5255 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5256   [(set (match_operand:MODEF 0 "register_operand" "=x")
5257         (float:MODEF
5258           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5259   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5260    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5261    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5262   "cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5263   [(set_attr "type" "sseicvt")
5264    (set_attr "mode" "<MODEF:MODE>")
5265    (set_attr "athlon_decode" "direct")
5266    (set_attr "amdfam10_decode" "double")
5267    (set_attr "fp_int_src" "true")])
5268
5269 (define_split
5270   [(set (match_operand:MODEF 0 "register_operand" "")
5271         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5272    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5273   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5274    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5275    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5276    && reload_completed
5277    && (SSE_REG_P (operands[0])
5278        || (GET_CODE (operands[0]) == SUBREG
5279            && SSE_REG_P (operands[0])))"
5280   [(set (match_dup 2) (match_dup 1))
5281    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5282   "")
5283
5284 (define_split
5285   [(set (match_operand:MODEF 0 "register_operand" "")
5286         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5287    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5288   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5289    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5290    && reload_completed
5291    && (SSE_REG_P (operands[0])
5292        || (GET_CODE (operands[0]) == SUBREG
5293            && SSE_REG_P (operands[0])))"
5294   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5295   "")
5296
5297 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5298   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5299         (float:X87MODEF
5300           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5301   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5302   "TARGET_80387"
5303   "@
5304    fild%z1\t%1
5305    #"
5306   [(set_attr "type" "fmov,multi")
5307    (set_attr "mode" "<X87MODEF:MODE>")
5308    (set_attr "unit" "*,i387")
5309    (set_attr "fp_int_src" "true")])
5310
5311 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5312   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5313         (float:X87MODEF
5314           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5315   "TARGET_80387"
5316   "fild%z1\t%1"
5317   [(set_attr "type" "fmov")
5318    (set_attr "mode" "<X87MODEF:MODE>")
5319    (set_attr "fp_int_src" "true")])
5320
5321 (define_split
5322   [(set (match_operand:X87MODEF 0 "register_operand" "")
5323         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5324    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5325   "TARGET_80387
5326    && reload_completed
5327    && FP_REG_P (operands[0])"
5328   [(set (match_dup 2) (match_dup 1))
5329    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5330   "")
5331
5332 (define_split
5333   [(set (match_operand:X87MODEF 0 "register_operand" "")
5334         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5335    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5336   "TARGET_80387
5337    && reload_completed
5338    && FP_REG_P (operands[0])"
5339   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5340   "")
5341
5342 ;; Avoid store forwarding (partial memory) stall penalty
5343 ;; by passing DImode value through XMM registers.  */
5344
5345 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5346   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5347         (float:X87MODEF
5348           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5349    (clobber (match_scratch:V4SI 3 "=X,x"))
5350    (clobber (match_scratch:V4SI 4 "=X,x"))
5351    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5352   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5353    && !TARGET_64BIT && !optimize_size"
5354   "#"
5355   [(set_attr "type" "multi")
5356    (set_attr "mode" "<X87MODEF:MODE>")
5357    (set_attr "unit" "i387")
5358    (set_attr "fp_int_src" "true")])
5359
5360 (define_split
5361   [(set (match_operand:X87MODEF 0 "register_operand" "")
5362         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5363    (clobber (match_scratch:V4SI 3 ""))
5364    (clobber (match_scratch:V4SI 4 ""))
5365    (clobber (match_operand:DI 2 "memory_operand" ""))]
5366   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5367    && !TARGET_64BIT && !optimize_size
5368    && reload_completed
5369    && FP_REG_P (operands[0])"
5370   [(set (match_dup 2) (match_dup 3))
5371    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5372 {
5373   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5374      Assemble the 64-bit DImode value in an xmm register.  */
5375   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5376                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5377   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5378                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5379   emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5380
5381   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5382 })
5383
5384 (define_split
5385   [(set (match_operand:X87MODEF 0 "register_operand" "")
5386         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5387    (clobber (match_scratch:V4SI 3 ""))
5388    (clobber (match_scratch:V4SI 4 ""))
5389    (clobber (match_operand:DI 2 "memory_operand" ""))]
5390   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5391    && !TARGET_64BIT && !optimize_size
5392    && reload_completed
5393    && FP_REG_P (operands[0])"
5394   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5395   "")
5396
5397 ;; Avoid store forwarding (partial memory) stall penalty by extending
5398 ;; SImode value to DImode through XMM register instead of pushing two
5399 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5400 ;; targets benefit from this optimization. Also note that fild
5401 ;; loads from memory only.
5402
5403 (define_insn "*floatunssi<mode>2_1"
5404   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5405         (unsigned_float:X87MODEF
5406           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5407    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5408    (clobber (match_scratch:SI 3 "=X,x"))]
5409   "!TARGET_64BIT
5410    && TARGET_80387 && TARGET_SSE"
5411   "#"
5412   [(set_attr "type" "multi")
5413    (set_attr "mode" "<MODE>")])
5414
5415 (define_split
5416   [(set (match_operand:X87MODEF 0 "register_operand" "")
5417         (unsigned_float:X87MODEF
5418           (match_operand:SI 1 "register_operand" "")))
5419    (clobber (match_operand:DI 2 "memory_operand" ""))
5420    (clobber (match_scratch:SI 3 ""))]
5421   "!TARGET_64BIT
5422    && TARGET_80387 && TARGET_SSE
5423    && reload_completed"
5424   [(set (match_dup 2) (match_dup 1))
5425    (set (match_dup 0)
5426         (float:X87MODEF (match_dup 2)))]
5427   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5428
5429 (define_split
5430   [(set (match_operand:X87MODEF 0 "register_operand" "")
5431         (unsigned_float:X87MODEF
5432           (match_operand:SI 1 "memory_operand" "")))
5433    (clobber (match_operand:DI 2 "memory_operand" ""))
5434    (clobber (match_scratch:SI 3 ""))]
5435   "!TARGET_64BIT
5436    && TARGET_80387 && TARGET_SSE
5437    && reload_completed"
5438   [(set (match_dup 2) (match_dup 3))
5439    (set (match_dup 0)
5440         (float:X87MODEF (match_dup 2)))]
5441 {
5442   emit_move_insn (operands[3], operands[1]);
5443   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5444 })
5445
5446 (define_expand "floatunssi<mode>2"
5447   [(parallel
5448      [(set (match_operand:X87MODEF 0 "register_operand" "")
5449            (unsigned_float:X87MODEF
5450              (match_operand:SI 1 "nonimmediate_operand" "")))
5451       (clobber (match_dup 2))
5452       (clobber (match_scratch:SI 3 ""))])]
5453   "!TARGET_64BIT
5454    && ((TARGET_80387 && TARGET_SSE)
5455        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5456 {
5457   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5458     {
5459       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5460       DONE;
5461     }
5462   else
5463     {
5464       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5465       operands[2] = assign_386_stack_local (DImode, slot);
5466     }
5467 })
5468
5469 (define_expand "floatunsdisf2"
5470   [(use (match_operand:SF 0 "register_operand" ""))
5471    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5472   "TARGET_64BIT && TARGET_SSE_MATH"
5473   "x86_emit_floatuns (operands); DONE;")
5474
5475 (define_expand "floatunsdidf2"
5476   [(use (match_operand:DF 0 "register_operand" ""))
5477    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5478   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5479    && TARGET_SSE2 && TARGET_SSE_MATH"
5480 {
5481   if (TARGET_64BIT)
5482     x86_emit_floatuns (operands);
5483   else
5484     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5485   DONE;
5486 })
5487 \f
5488 ;; Add instructions
5489
5490 ;; %%% splits for addditi3
5491
5492 (define_expand "addti3"
5493   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5494         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5495                  (match_operand:TI 2 "x86_64_general_operand" "")))
5496    (clobber (reg:CC FLAGS_REG))]
5497   "TARGET_64BIT"
5498   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5499
5500 (define_insn "*addti3_1"
5501   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5502         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5503                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5504    (clobber (reg:CC FLAGS_REG))]
5505   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5506   "#")
5507
5508 (define_split
5509   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5510         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5511                  (match_operand:TI 2 "x86_64_general_operand" "")))
5512    (clobber (reg:CC FLAGS_REG))]
5513   "TARGET_64BIT && reload_completed"
5514   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5515                                           UNSPEC_ADD_CARRY))
5516               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5517    (parallel [(set (match_dup 3)
5518                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5519                                      (match_dup 4))
5520                             (match_dup 5)))
5521               (clobber (reg:CC FLAGS_REG))])]
5522   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5523
5524 ;; %%% splits for addsidi3
5525 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5526 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5527 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5528
5529 (define_expand "adddi3"
5530   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5531         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5532                  (match_operand:DI 2 "x86_64_general_operand" "")))
5533    (clobber (reg:CC FLAGS_REG))]
5534   ""
5535   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5536
5537 (define_insn "*adddi3_1"
5538   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5539         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5540                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5541    (clobber (reg:CC FLAGS_REG))]
5542   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5543   "#")
5544
5545 (define_split
5546   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5547         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5548                  (match_operand:DI 2 "general_operand" "")))
5549    (clobber (reg:CC FLAGS_REG))]
5550   "!TARGET_64BIT && reload_completed"
5551   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5552                                           UNSPEC_ADD_CARRY))
5553               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5554    (parallel [(set (match_dup 3)
5555                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5556                                      (match_dup 4))
5557                             (match_dup 5)))
5558               (clobber (reg:CC FLAGS_REG))])]
5559   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5560
5561 (define_insn "adddi3_carry_rex64"
5562   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5563           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5564                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5565                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5566    (clobber (reg:CC FLAGS_REG))]
5567   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5568   "adc{q}\t{%2, %0|%0, %2}"
5569   [(set_attr "type" "alu")
5570    (set_attr "pent_pair" "pu")
5571    (set_attr "mode" "DI")])
5572
5573 (define_insn "*adddi3_cc_rex64"
5574   [(set (reg:CC FLAGS_REG)
5575         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5576                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5577                    UNSPEC_ADD_CARRY))
5578    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5579         (plus:DI (match_dup 1) (match_dup 2)))]
5580   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5581   "add{q}\t{%2, %0|%0, %2}"
5582   [(set_attr "type" "alu")
5583    (set_attr "mode" "DI")])
5584
5585 (define_insn "*<addsub><mode>3_cc_overflow"
5586   [(set (reg:CCC FLAGS_REG)
5587         (compare:CCC
5588             (plusminus:SWI
5589                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5590                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5591             (match_dup 1)))
5592    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5593         (plusminus:SWI (match_dup 1) (match_dup 2)))]
5594   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5595   "<addsub>{<imodesuffix>}\t{%2, %0|%0, %2}"
5596   [(set_attr "type" "alu")
5597    (set_attr "mode" "<MODE>")])
5598
5599 (define_insn "*add<mode>3_cconly_overflow"
5600   [(set (reg:CCC FLAGS_REG)
5601         (compare:CCC
5602                 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5603                           (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5604                 (match_dup 1)))
5605    (clobber (match_scratch:SWI 0 "=<r>"))]
5606   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5607   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5608   [(set_attr "type" "alu")
5609    (set_attr "mode" "<MODE>")])
5610
5611 (define_insn "*sub<mode>3_cconly_overflow"
5612   [(set (reg:CCC FLAGS_REG)
5613         (compare:CCC
5614              (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5615                         (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5616              (match_dup 0)))]
5617   ""
5618   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5619   [(set_attr "type" "icmp")
5620    (set_attr "mode" "<MODE>")])
5621
5622 (define_insn "*<addsub>si3_zext_cc_overflow"
5623   [(set (reg:CCC FLAGS_REG)
5624         (compare:CCC
5625             (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5626                           (match_operand:SI 2 "general_operand" "g"))
5627             (match_dup 1)))
5628    (set (match_operand:DI 0 "register_operand" "=r")
5629         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5630   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5631   "<addsub>{l}\t{%2, %k0|%k0, %2}"
5632   [(set_attr "type" "alu")
5633    (set_attr "mode" "SI")])
5634
5635 (define_insn "addqi3_carry"
5636   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5637           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5638                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5639                    (match_operand:QI 2 "general_operand" "qi,qm")))
5640    (clobber (reg:CC FLAGS_REG))]
5641   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5642   "adc{b}\t{%2, %0|%0, %2}"
5643   [(set_attr "type" "alu")
5644    (set_attr "pent_pair" "pu")
5645    (set_attr "mode" "QI")])
5646
5647 (define_insn "addhi3_carry"
5648   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5649           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5650                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5651                    (match_operand:HI 2 "general_operand" "ri,rm")))
5652    (clobber (reg:CC FLAGS_REG))]
5653   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5654   "adc{w}\t{%2, %0|%0, %2}"
5655   [(set_attr "type" "alu")
5656    (set_attr "pent_pair" "pu")
5657    (set_attr "mode" "HI")])
5658
5659 (define_insn "addsi3_carry"
5660   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5661           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5662                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5663                    (match_operand:SI 2 "general_operand" "ri,rm")))
5664    (clobber (reg:CC FLAGS_REG))]
5665   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5666   "adc{l}\t{%2, %0|%0, %2}"
5667   [(set_attr "type" "alu")
5668    (set_attr "pent_pair" "pu")
5669    (set_attr "mode" "SI")])
5670
5671 (define_insn "*addsi3_carry_zext"
5672   [(set (match_operand:DI 0 "register_operand" "=r")
5673           (zero_extend:DI
5674             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5675                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5676                      (match_operand:SI 2 "general_operand" "g"))))
5677    (clobber (reg:CC FLAGS_REG))]
5678   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5679   "adc{l}\t{%2, %k0|%k0, %2}"
5680   [(set_attr "type" "alu")
5681    (set_attr "pent_pair" "pu")
5682    (set_attr "mode" "SI")])
5683
5684 (define_insn "*addsi3_cc"
5685   [(set (reg:CC FLAGS_REG)
5686         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5687                     (match_operand:SI 2 "general_operand" "ri,rm")]
5688                    UNSPEC_ADD_CARRY))
5689    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5690         (plus:SI (match_dup 1) (match_dup 2)))]
5691   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5692   "add{l}\t{%2, %0|%0, %2}"
5693   [(set_attr "type" "alu")
5694    (set_attr "mode" "SI")])
5695
5696 (define_insn "addqi3_cc"
5697   [(set (reg:CC FLAGS_REG)
5698         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5699                     (match_operand:QI 2 "general_operand" "qi,qm")]
5700                    UNSPEC_ADD_CARRY))
5701    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5702         (plus:QI (match_dup 1) (match_dup 2)))]
5703   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5704   "add{b}\t{%2, %0|%0, %2}"
5705   [(set_attr "type" "alu")
5706    (set_attr "mode" "QI")])
5707
5708 (define_expand "addsi3"
5709   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5710                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5711                             (match_operand:SI 2 "general_operand" "")))
5712               (clobber (reg:CC FLAGS_REG))])]
5713   ""
5714   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5715
5716 (define_insn "*lea_1"
5717   [(set (match_operand:SI 0 "register_operand" "=r")
5718         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5719   "!TARGET_64BIT"
5720   "lea{l}\t{%a1, %0|%0, %a1}"
5721   [(set_attr "type" "lea")
5722    (set_attr "mode" "SI")])
5723
5724 (define_insn "*lea_1_rex64"
5725   [(set (match_operand:SI 0 "register_operand" "=r")
5726         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5727   "TARGET_64BIT"
5728   "lea{l}\t{%a1, %0|%0, %a1}"
5729   [(set_attr "type" "lea")
5730    (set_attr "mode" "SI")])
5731
5732 (define_insn "*lea_1_zext"
5733   [(set (match_operand:DI 0 "register_operand" "=r")
5734         (zero_extend:DI
5735          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5736   "TARGET_64BIT"
5737   "lea{l}\t{%a1, %k0|%k0, %a1}"
5738   [(set_attr "type" "lea")
5739    (set_attr "mode" "SI")])
5740
5741 (define_insn "*lea_2_rex64"
5742   [(set (match_operand:DI 0 "register_operand" "=r")
5743         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5744   "TARGET_64BIT"
5745   "lea{q}\t{%a1, %0|%0, %a1}"
5746   [(set_attr "type" "lea")
5747    (set_attr "mode" "DI")])
5748
5749 ;; The lea patterns for non-Pmodes needs to be matched by several
5750 ;; insns converted to real lea by splitters.
5751
5752 (define_insn_and_split "*lea_general_1"
5753   [(set (match_operand 0 "register_operand" "=r")
5754         (plus (plus (match_operand 1 "index_register_operand" "l")
5755                     (match_operand 2 "register_operand" "r"))
5756               (match_operand 3 "immediate_operand" "i")))]
5757   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5758     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5759    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5760    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5761    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5762    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5763        || GET_MODE (operands[3]) == VOIDmode)"
5764   "#"
5765   "&& reload_completed"
5766   [(const_int 0)]
5767 {
5768   rtx pat;
5769   operands[0] = gen_lowpart (SImode, operands[0]);
5770   operands[1] = gen_lowpart (Pmode, operands[1]);
5771   operands[2] = gen_lowpart (Pmode, operands[2]);
5772   operands[3] = gen_lowpart (Pmode, operands[3]);
5773   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5774                       operands[3]);
5775   if (Pmode != SImode)
5776     pat = gen_rtx_SUBREG (SImode, pat, 0);
5777   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5778   DONE;
5779 }
5780   [(set_attr "type" "lea")
5781    (set_attr "mode" "SI")])
5782
5783 (define_insn_and_split "*lea_general_1_zext"
5784   [(set (match_operand:DI 0 "register_operand" "=r")
5785         (zero_extend:DI
5786           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5787                             (match_operand:SI 2 "register_operand" "r"))
5788                    (match_operand:SI 3 "immediate_operand" "i"))))]
5789   "TARGET_64BIT"
5790   "#"
5791   "&& reload_completed"
5792   [(set (match_dup 0)
5793         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5794                                                      (match_dup 2))
5795                                             (match_dup 3)) 0)))]
5796 {
5797   operands[1] = gen_lowpart (Pmode, operands[1]);
5798   operands[2] = gen_lowpart (Pmode, operands[2]);
5799   operands[3] = gen_lowpart (Pmode, operands[3]);
5800 }
5801   [(set_attr "type" "lea")
5802    (set_attr "mode" "SI")])
5803
5804 (define_insn_and_split "*lea_general_2"
5805   [(set (match_operand 0 "register_operand" "=r")
5806         (plus (mult (match_operand 1 "index_register_operand" "l")
5807                     (match_operand 2 "const248_operand" "i"))
5808               (match_operand 3 "nonmemory_operand" "ri")))]
5809   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5810     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5811    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5812    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5813    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5814        || GET_MODE (operands[3]) == VOIDmode)"
5815   "#"
5816   "&& reload_completed"
5817   [(const_int 0)]
5818 {
5819   rtx pat;
5820   operands[0] = gen_lowpart (SImode, operands[0]);
5821   operands[1] = gen_lowpart (Pmode, operands[1]);
5822   operands[3] = gen_lowpart (Pmode, operands[3]);
5823   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5824                       operands[3]);
5825   if (Pmode != SImode)
5826     pat = gen_rtx_SUBREG (SImode, pat, 0);
5827   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5828   DONE;
5829 }
5830   [(set_attr "type" "lea")
5831    (set_attr "mode" "SI")])
5832
5833 (define_insn_and_split "*lea_general_2_zext"
5834   [(set (match_operand:DI 0 "register_operand" "=r")
5835         (zero_extend:DI
5836           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5837                             (match_operand:SI 2 "const248_operand" "n"))
5838                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5839   "TARGET_64BIT"
5840   "#"
5841   "&& reload_completed"
5842   [(set (match_dup 0)
5843         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5844                                                      (match_dup 2))
5845                                             (match_dup 3)) 0)))]
5846 {
5847   operands[1] = gen_lowpart (Pmode, operands[1]);
5848   operands[3] = gen_lowpart (Pmode, operands[3]);
5849 }
5850   [(set_attr "type" "lea")
5851    (set_attr "mode" "SI")])
5852
5853 (define_insn_and_split "*lea_general_3"
5854   [(set (match_operand 0 "register_operand" "=r")
5855         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5856                           (match_operand 2 "const248_operand" "i"))
5857                     (match_operand 3 "register_operand" "r"))
5858               (match_operand 4 "immediate_operand" "i")))]
5859   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5860     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5861    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5862    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5863    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5864   "#"
5865   "&& reload_completed"
5866   [(const_int 0)]
5867 {
5868   rtx pat;
5869   operands[0] = gen_lowpart (SImode, operands[0]);
5870   operands[1] = gen_lowpart (Pmode, operands[1]);
5871   operands[3] = gen_lowpart (Pmode, operands[3]);
5872   operands[4] = gen_lowpart (Pmode, operands[4]);
5873   pat = gen_rtx_PLUS (Pmode,
5874                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5875                                                          operands[2]),
5876                                     operands[3]),
5877                       operands[4]);
5878   if (Pmode != SImode)
5879     pat = gen_rtx_SUBREG (SImode, pat, 0);
5880   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5881   DONE;
5882 }
5883   [(set_attr "type" "lea")
5884    (set_attr "mode" "SI")])
5885
5886 (define_insn_and_split "*lea_general_3_zext"
5887   [(set (match_operand:DI 0 "register_operand" "=r")
5888         (zero_extend:DI
5889           (plus:SI (plus:SI (mult:SI
5890                               (match_operand:SI 1 "index_register_operand" "l")
5891                               (match_operand:SI 2 "const248_operand" "n"))
5892                             (match_operand:SI 3 "register_operand" "r"))
5893                    (match_operand:SI 4 "immediate_operand" "i"))))]
5894   "TARGET_64BIT"
5895   "#"
5896   "&& reload_completed"
5897   [(set (match_dup 0)
5898         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5899                                                               (match_dup 2))
5900                                                      (match_dup 3))
5901                                             (match_dup 4)) 0)))]
5902 {
5903   operands[1] = gen_lowpart (Pmode, operands[1]);
5904   operands[3] = gen_lowpart (Pmode, operands[3]);
5905   operands[4] = gen_lowpart (Pmode, operands[4]);
5906 }
5907   [(set_attr "type" "lea")
5908    (set_attr "mode" "SI")])
5909
5910 (define_insn "*adddi_1_rex64"
5911   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5912         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5913                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5914    (clobber (reg:CC FLAGS_REG))]
5915   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5916 {
5917   switch (get_attr_type (insn))
5918     {
5919     case TYPE_LEA:
5920       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5921       return "lea{q}\t{%a2, %0|%0, %a2}";
5922
5923     case TYPE_INCDEC:
5924       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5925       if (operands[2] == const1_rtx)
5926         return "inc{q}\t%0";
5927       else
5928         {
5929           gcc_assert (operands[2] == constm1_rtx);
5930           return "dec{q}\t%0";
5931         }
5932
5933     default:
5934       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5935
5936       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5937          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5938       if (CONST_INT_P (operands[2])
5939           /* Avoid overflows.  */
5940           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5941           && (INTVAL (operands[2]) == 128
5942               || (INTVAL (operands[2]) < 0
5943                   && INTVAL (operands[2]) != -128)))
5944         {
5945           operands[2] = GEN_INT (-INTVAL (operands[2]));
5946           return "sub{q}\t{%2, %0|%0, %2}";
5947         }
5948       return "add{q}\t{%2, %0|%0, %2}";
5949     }
5950 }
5951   [(set (attr "type")
5952      (cond [(eq_attr "alternative" "2")
5953               (const_string "lea")
5954             ; Current assemblers are broken and do not allow @GOTOFF in
5955             ; ought but a memory context.
5956             (match_operand:DI 2 "pic_symbolic_operand" "")
5957               (const_string "lea")
5958             (match_operand:DI 2 "incdec_operand" "")
5959               (const_string "incdec")
5960            ]
5961            (const_string "alu")))
5962    (set_attr "mode" "DI")])
5963
5964 ;; Convert lea to the lea pattern to avoid flags dependency.
5965 (define_split
5966   [(set (match_operand:DI 0 "register_operand" "")
5967         (plus:DI (match_operand:DI 1 "register_operand" "")
5968                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5969    (clobber (reg:CC FLAGS_REG))]
5970   "TARGET_64BIT && reload_completed
5971    && true_regnum (operands[0]) != true_regnum (operands[1])"
5972   [(set (match_dup 0)
5973         (plus:DI (match_dup 1)
5974                  (match_dup 2)))]
5975   "")
5976
5977 (define_insn "*adddi_2_rex64"
5978   [(set (reg FLAGS_REG)
5979         (compare
5980           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5981                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5982           (const_int 0)))
5983    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5984         (plus:DI (match_dup 1) (match_dup 2)))]
5985   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5986    && ix86_binary_operator_ok (PLUS, DImode, operands)
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       /* ???? We ought to handle there the 32bit case too
6006          - do we need new constraint?  */
6007       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6008          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6009       if (CONST_INT_P (operands[2])
6010           /* Avoid overflows.  */
6011           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6012           && (INTVAL (operands[2]) == 128
6013               || (INTVAL (operands[2]) < 0
6014                   && INTVAL (operands[2]) != -128)))
6015         {
6016           operands[2] = GEN_INT (-INTVAL (operands[2]));
6017           return "sub{q}\t{%2, %0|%0, %2}";
6018         }
6019       return "add{q}\t{%2, %0|%0, %2}";
6020     }
6021 }
6022   [(set (attr "type")
6023      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6024         (const_string "incdec")
6025         (const_string "alu")))
6026    (set_attr "mode" "DI")])
6027
6028 (define_insn "*adddi_3_rex64"
6029   [(set (reg FLAGS_REG)
6030         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6031                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
6032    (clobber (match_scratch:DI 0 "=r"))]
6033   "TARGET_64BIT
6034    && ix86_match_ccmode (insn, CCZmode)
6035    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6036    /* Current assemblers are broken and do not allow @GOTOFF in
6037       ought but a memory context.  */
6038    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6039 {
6040   switch (get_attr_type (insn))
6041     {
6042     case TYPE_INCDEC:
6043       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6044       if (operands[2] == const1_rtx)
6045         return "inc{q}\t%0";
6046       else
6047         {
6048           gcc_assert (operands[2] == constm1_rtx);
6049           return "dec{q}\t%0";
6050         }
6051
6052     default:
6053       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6054       /* ???? We ought to handle there the 32bit case too
6055          - do we need new constraint?  */
6056       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6057          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6058       if (CONST_INT_P (operands[2])
6059           /* Avoid overflows.  */
6060           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6061           && (INTVAL (operands[2]) == 128
6062               || (INTVAL (operands[2]) < 0
6063                   && INTVAL (operands[2]) != -128)))
6064         {
6065           operands[2] = GEN_INT (-INTVAL (operands[2]));
6066           return "sub{q}\t{%2, %0|%0, %2}";
6067         }
6068       return "add{q}\t{%2, %0|%0, %2}";
6069     }
6070 }
6071   [(set (attr "type")
6072      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6073         (const_string "incdec")
6074         (const_string "alu")))
6075    (set_attr "mode" "DI")])
6076
6077 ; For comparisons against 1, -1 and 128, we may generate better code
6078 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6079 ; is matched then.  We can't accept general immediate, because for
6080 ; case of overflows,  the result is messed up.
6081 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6082 ; when negated.
6083 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6084 ; only for comparisons not depending on it.
6085 (define_insn "*adddi_4_rex64"
6086   [(set (reg FLAGS_REG)
6087         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6088                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6089    (clobber (match_scratch:DI 0 "=rm"))]
6090   "TARGET_64BIT
6091    &&  ix86_match_ccmode (insn, CCGCmode)"
6092 {
6093   switch (get_attr_type (insn))
6094     {
6095     case TYPE_INCDEC:
6096       if (operands[2] == constm1_rtx)
6097         return "inc{q}\t%0";
6098       else
6099         {
6100           gcc_assert (operands[2] == const1_rtx);
6101           return "dec{q}\t%0";
6102         }
6103
6104     default:
6105       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6106       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6107          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6108       if ((INTVAL (operands[2]) == -128
6109            || (INTVAL (operands[2]) > 0
6110                && INTVAL (operands[2]) != 128))
6111           /* Avoid overflows.  */
6112           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6113         return "sub{q}\t{%2, %0|%0, %2}";
6114       operands[2] = GEN_INT (-INTVAL (operands[2]));
6115       return "add{q}\t{%2, %0|%0, %2}";
6116     }
6117 }
6118   [(set (attr "type")
6119      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6120         (const_string "incdec")
6121         (const_string "alu")))
6122    (set_attr "mode" "DI")])
6123
6124 (define_insn "*adddi_5_rex64"
6125   [(set (reg FLAGS_REG)
6126         (compare
6127           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6128                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
6129           (const_int 0)))
6130    (clobber (match_scratch:DI 0 "=r"))]
6131   "TARGET_64BIT
6132    && ix86_match_ccmode (insn, CCGOCmode)
6133    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6134    /* Current assemblers are broken and do not allow @GOTOFF in
6135       ought but a memory context.  */
6136    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6137 {
6138   switch (get_attr_type (insn))
6139     {
6140     case TYPE_INCDEC:
6141       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6142       if (operands[2] == const1_rtx)
6143         return "inc{q}\t%0";
6144       else
6145         {
6146           gcc_assert (operands[2] == constm1_rtx);
6147           return "dec{q}\t%0";
6148         }
6149
6150     default:
6151       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6152       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6153          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6154       if (CONST_INT_P (operands[2])
6155           /* Avoid overflows.  */
6156           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6157           && (INTVAL (operands[2]) == 128
6158               || (INTVAL (operands[2]) < 0
6159                   && INTVAL (operands[2]) != -128)))
6160         {
6161           operands[2] = GEN_INT (-INTVAL (operands[2]));
6162           return "sub{q}\t{%2, %0|%0, %2}";
6163         }
6164       return "add{q}\t{%2, %0|%0, %2}";
6165     }
6166 }
6167   [(set (attr "type")
6168      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6169         (const_string "incdec")
6170         (const_string "alu")))
6171    (set_attr "mode" "DI")])
6172
6173
6174 (define_insn "*addsi_1"
6175   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6176         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6177                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
6178    (clobber (reg:CC FLAGS_REG))]
6179   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6180 {
6181   switch (get_attr_type (insn))
6182     {
6183     case TYPE_LEA:
6184       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6185       return "lea{l}\t{%a2, %0|%0, %a2}";
6186
6187     case TYPE_INCDEC:
6188       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6189       if (operands[2] == const1_rtx)
6190         return "inc{l}\t%0";
6191       else
6192         {
6193           gcc_assert (operands[2] == constm1_rtx);
6194           return "dec{l}\t%0";
6195         }
6196
6197     default:
6198       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6199
6200       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6201          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6202       if (CONST_INT_P (operands[2])
6203           && (INTVAL (operands[2]) == 128
6204               || (INTVAL (operands[2]) < 0
6205                   && INTVAL (operands[2]) != -128)))
6206         {
6207           operands[2] = GEN_INT (-INTVAL (operands[2]));
6208           return "sub{l}\t{%2, %0|%0, %2}";
6209         }
6210       return "add{l}\t{%2, %0|%0, %2}";
6211     }
6212 }
6213   [(set (attr "type")
6214      (cond [(eq_attr "alternative" "2")
6215               (const_string "lea")
6216             ; Current assemblers are broken and do not allow @GOTOFF in
6217             ; ought but a memory context.
6218             (match_operand:SI 2 "pic_symbolic_operand" "")
6219               (const_string "lea")
6220             (match_operand:SI 2 "incdec_operand" "")
6221               (const_string "incdec")
6222            ]
6223            (const_string "alu")))
6224    (set_attr "mode" "SI")])
6225
6226 ;; Convert lea to the lea pattern to avoid flags dependency.
6227 (define_split
6228   [(set (match_operand 0 "register_operand" "")
6229         (plus (match_operand 1 "register_operand" "")
6230               (match_operand 2 "nonmemory_operand" "")))
6231    (clobber (reg:CC FLAGS_REG))]
6232   "reload_completed
6233    && true_regnum (operands[0]) != true_regnum (operands[1])"
6234   [(const_int 0)]
6235 {
6236   rtx pat;
6237   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6238      may confuse gen_lowpart.  */
6239   if (GET_MODE (operands[0]) != Pmode)
6240     {
6241       operands[1] = gen_lowpart (Pmode, operands[1]);
6242       operands[2] = gen_lowpart (Pmode, operands[2]);
6243     }
6244   operands[0] = gen_lowpart (SImode, operands[0]);
6245   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6246   if (Pmode != SImode)
6247     pat = gen_rtx_SUBREG (SImode, pat, 0);
6248   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6249   DONE;
6250 })
6251
6252 ;; It may seem that nonimmediate operand is proper one for operand 1.
6253 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6254 ;; we take care in ix86_binary_operator_ok to not allow two memory
6255 ;; operands so proper swapping will be done in reload.  This allow
6256 ;; patterns constructed from addsi_1 to match.
6257 (define_insn "addsi_1_zext"
6258   [(set (match_operand:DI 0 "register_operand" "=r,r")
6259         (zero_extend:DI
6260           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6261                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
6262    (clobber (reg:CC FLAGS_REG))]
6263   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6264 {
6265   switch (get_attr_type (insn))
6266     {
6267     case TYPE_LEA:
6268       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6269       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6270
6271     case TYPE_INCDEC:
6272       if (operands[2] == const1_rtx)
6273         return "inc{l}\t%k0";
6274       else
6275         {
6276           gcc_assert (operands[2] == constm1_rtx);
6277           return "dec{l}\t%k0";
6278         }
6279
6280     default:
6281       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6282          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6283       if (CONST_INT_P (operands[2])
6284           && (INTVAL (operands[2]) == 128
6285               || (INTVAL (operands[2]) < 0
6286                   && INTVAL (operands[2]) != -128)))
6287         {
6288           operands[2] = GEN_INT (-INTVAL (operands[2]));
6289           return "sub{l}\t{%2, %k0|%k0, %2}";
6290         }
6291       return "add{l}\t{%2, %k0|%k0, %2}";
6292     }
6293 }
6294   [(set (attr "type")
6295      (cond [(eq_attr "alternative" "1")
6296               (const_string "lea")
6297             ; Current assemblers are broken and do not allow @GOTOFF in
6298             ; ought but a memory context.
6299             (match_operand:SI 2 "pic_symbolic_operand" "")
6300               (const_string "lea")
6301             (match_operand:SI 2 "incdec_operand" "")
6302               (const_string "incdec")
6303            ]
6304            (const_string "alu")))
6305    (set_attr "mode" "SI")])
6306
6307 ;; Convert lea to the lea pattern to avoid flags dependency.
6308 (define_split
6309   [(set (match_operand:DI 0 "register_operand" "")
6310         (zero_extend:DI
6311           (plus:SI (match_operand:SI 1 "register_operand" "")
6312                    (match_operand:SI 2 "nonmemory_operand" ""))))
6313    (clobber (reg:CC FLAGS_REG))]
6314   "TARGET_64BIT && reload_completed
6315    && true_regnum (operands[0]) != true_regnum (operands[1])"
6316   [(set (match_dup 0)
6317         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6318 {
6319   operands[1] = gen_lowpart (Pmode, operands[1]);
6320   operands[2] = gen_lowpart (Pmode, operands[2]);
6321 })
6322
6323 (define_insn "*addsi_2"
6324   [(set (reg FLAGS_REG)
6325         (compare
6326           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6327                    (match_operand:SI 2 "general_operand" "rmni,rni"))
6328           (const_int 0)))
6329    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6330         (plus:SI (match_dup 1) (match_dup 2)))]
6331   "ix86_match_ccmode (insn, CCGOCmode)
6332    && ix86_binary_operator_ok (PLUS, SImode, operands)
6333    /* Current assemblers are broken and do not allow @GOTOFF in
6334       ought but a memory context.  */
6335    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6336 {
6337   switch (get_attr_type (insn))
6338     {
6339     case TYPE_INCDEC:
6340       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6341       if (operands[2] == const1_rtx)
6342         return "inc{l}\t%0";
6343       else
6344         {
6345           gcc_assert (operands[2] == constm1_rtx);
6346           return "dec{l}\t%0";
6347         }
6348
6349     default:
6350       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6351       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6352          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6353       if (CONST_INT_P (operands[2])
6354           && (INTVAL (operands[2]) == 128
6355               || (INTVAL (operands[2]) < 0
6356                   && INTVAL (operands[2]) != -128)))
6357         {
6358           operands[2] = GEN_INT (-INTVAL (operands[2]));
6359           return "sub{l}\t{%2, %0|%0, %2}";
6360         }
6361       return "add{l}\t{%2, %0|%0, %2}";
6362     }
6363 }
6364   [(set (attr "type")
6365      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6366         (const_string "incdec")
6367         (const_string "alu")))
6368    (set_attr "mode" "SI")])
6369
6370 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6371 (define_insn "*addsi_2_zext"
6372   [(set (reg FLAGS_REG)
6373         (compare
6374           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6375                    (match_operand:SI 2 "general_operand" "rmni"))
6376           (const_int 0)))
6377    (set (match_operand:DI 0 "register_operand" "=r")
6378         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6379   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6380    && ix86_binary_operator_ok (PLUS, SImode, operands)
6381    /* Current assemblers are broken and do not allow @GOTOFF in
6382       ought but a memory context.  */
6383    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6384 {
6385   switch (get_attr_type (insn))
6386     {
6387     case TYPE_INCDEC:
6388       if (operands[2] == const1_rtx)
6389         return "inc{l}\t%k0";
6390       else
6391         {
6392           gcc_assert (operands[2] == constm1_rtx);
6393           return "dec{l}\t%k0";
6394         }
6395
6396     default:
6397       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6398          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6399       if (CONST_INT_P (operands[2])
6400           && (INTVAL (operands[2]) == 128
6401               || (INTVAL (operands[2]) < 0
6402                   && INTVAL (operands[2]) != -128)))
6403         {
6404           operands[2] = GEN_INT (-INTVAL (operands[2]));
6405           return "sub{l}\t{%2, %k0|%k0, %2}";
6406         }
6407       return "add{l}\t{%2, %k0|%k0, %2}";
6408     }
6409 }
6410   [(set (attr "type")
6411      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6412         (const_string "incdec")
6413         (const_string "alu")))
6414    (set_attr "mode" "SI")])
6415
6416 (define_insn "*addsi_3"
6417   [(set (reg FLAGS_REG)
6418         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6419                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6420    (clobber (match_scratch:SI 0 "=r"))]
6421   "ix86_match_ccmode (insn, CCZmode)
6422    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6423    /* Current assemblers are broken and do not allow @GOTOFF in
6424       ought but a memory context.  */
6425    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6426 {
6427   switch (get_attr_type (insn))
6428     {
6429     case TYPE_INCDEC:
6430       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6431       if (operands[2] == const1_rtx)
6432         return "inc{l}\t%0";
6433       else
6434         {
6435           gcc_assert (operands[2] == constm1_rtx);
6436           return "dec{l}\t%0";
6437         }
6438
6439     default:
6440       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6441       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6442          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6443       if (CONST_INT_P (operands[2])
6444           && (INTVAL (operands[2]) == 128
6445               || (INTVAL (operands[2]) < 0
6446                   && INTVAL (operands[2]) != -128)))
6447         {
6448           operands[2] = GEN_INT (-INTVAL (operands[2]));
6449           return "sub{l}\t{%2, %0|%0, %2}";
6450         }
6451       return "add{l}\t{%2, %0|%0, %2}";
6452     }
6453 }
6454   [(set (attr "type")
6455      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6456         (const_string "incdec")
6457         (const_string "alu")))
6458    (set_attr "mode" "SI")])
6459
6460 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6461 (define_insn "*addsi_3_zext"
6462   [(set (reg FLAGS_REG)
6463         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6464                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6465    (set (match_operand:DI 0 "register_operand" "=r")
6466         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6467   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6468    && ix86_binary_operator_ok (PLUS, SImode, operands)
6469    /* Current assemblers are broken and do not allow @GOTOFF in
6470       ought but a memory context.  */
6471    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6472 {
6473   switch (get_attr_type (insn))
6474     {
6475     case TYPE_INCDEC:
6476       if (operands[2] == const1_rtx)
6477         return "inc{l}\t%k0";
6478       else
6479         {
6480           gcc_assert (operands[2] == constm1_rtx);
6481           return "dec{l}\t%k0";
6482         }
6483
6484     default:
6485       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6486          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6487       if (CONST_INT_P (operands[2])
6488           && (INTVAL (operands[2]) == 128
6489               || (INTVAL (operands[2]) < 0
6490                   && INTVAL (operands[2]) != -128)))
6491         {
6492           operands[2] = GEN_INT (-INTVAL (operands[2]));
6493           return "sub{l}\t{%2, %k0|%k0, %2}";
6494         }
6495       return "add{l}\t{%2, %k0|%k0, %2}";
6496     }
6497 }
6498   [(set (attr "type")
6499      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6500         (const_string "incdec")
6501         (const_string "alu")))
6502    (set_attr "mode" "SI")])
6503
6504 ; For comparisons against 1, -1 and 128, we may generate better code
6505 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6506 ; is matched then.  We can't accept general immediate, because for
6507 ; case of overflows,  the result is messed up.
6508 ; This pattern also don't hold of 0x80000000, since the value overflows
6509 ; when negated.
6510 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6511 ; only for comparisons not depending on it.
6512 (define_insn "*addsi_4"
6513   [(set (reg FLAGS_REG)
6514         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6515                  (match_operand:SI 2 "const_int_operand" "n")))
6516    (clobber (match_scratch:SI 0 "=rm"))]
6517   "ix86_match_ccmode (insn, CCGCmode)
6518    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6519 {
6520   switch (get_attr_type (insn))
6521     {
6522     case TYPE_INCDEC:
6523       if (operands[2] == constm1_rtx)
6524         return "inc{l}\t%0";
6525       else
6526         {
6527           gcc_assert (operands[2] == const1_rtx);
6528           return "dec{l}\t%0";
6529         }
6530
6531     default:
6532       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6533       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6534          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6535       if ((INTVAL (operands[2]) == -128
6536            || (INTVAL (operands[2]) > 0
6537                && INTVAL (operands[2]) != 128)))
6538         return "sub{l}\t{%2, %0|%0, %2}";
6539       operands[2] = GEN_INT (-INTVAL (operands[2]));
6540       return "add{l}\t{%2, %0|%0, %2}";
6541     }
6542 }
6543   [(set (attr "type")
6544      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6545         (const_string "incdec")
6546         (const_string "alu")))
6547    (set_attr "mode" "SI")])
6548
6549 (define_insn "*addsi_5"
6550   [(set (reg FLAGS_REG)
6551         (compare
6552           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6553                    (match_operand:SI 2 "general_operand" "rmni"))
6554           (const_int 0)))
6555    (clobber (match_scratch:SI 0 "=r"))]
6556   "ix86_match_ccmode (insn, CCGOCmode)
6557    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6558    /* Current assemblers are broken and do not allow @GOTOFF in
6559       ought but a memory context.  */
6560    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6561 {
6562   switch (get_attr_type (insn))
6563     {
6564     case TYPE_INCDEC:
6565       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6566       if (operands[2] == const1_rtx)
6567         return "inc{l}\t%0";
6568       else
6569         {
6570           gcc_assert (operands[2] == constm1_rtx);
6571           return "dec{l}\t%0";
6572         }
6573
6574     default:
6575       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6576       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6577          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6578       if (CONST_INT_P (operands[2])
6579           && (INTVAL (operands[2]) == 128
6580               || (INTVAL (operands[2]) < 0
6581                   && INTVAL (operands[2]) != -128)))
6582         {
6583           operands[2] = GEN_INT (-INTVAL (operands[2]));
6584           return "sub{l}\t{%2, %0|%0, %2}";
6585         }
6586       return "add{l}\t{%2, %0|%0, %2}";
6587     }
6588 }
6589   [(set (attr "type")
6590      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6591         (const_string "incdec")
6592         (const_string "alu")))
6593    (set_attr "mode" "SI")])
6594
6595 (define_expand "addhi3"
6596   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6597                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6598                             (match_operand:HI 2 "general_operand" "")))
6599               (clobber (reg:CC FLAGS_REG))])]
6600   "TARGET_HIMODE_MATH"
6601   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6602
6603 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6604 ;; type optimizations enabled by define-splits.  This is not important
6605 ;; for PII, and in fact harmful because of partial register stalls.
6606
6607 (define_insn "*addhi_1_lea"
6608   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6609         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6610                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6611    (clobber (reg:CC FLAGS_REG))]
6612   "!TARGET_PARTIAL_REG_STALL
6613    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6614 {
6615   switch (get_attr_type (insn))
6616     {
6617     case TYPE_LEA:
6618       return "#";
6619     case TYPE_INCDEC:
6620       if (operands[2] == const1_rtx)
6621         return "inc{w}\t%0";
6622       else
6623         {
6624           gcc_assert (operands[2] == constm1_rtx);
6625           return "dec{w}\t%0";
6626         }
6627
6628     default:
6629       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6630          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6631       if (CONST_INT_P (operands[2])
6632           && (INTVAL (operands[2]) == 128
6633               || (INTVAL (operands[2]) < 0
6634                   && INTVAL (operands[2]) != -128)))
6635         {
6636           operands[2] = GEN_INT (-INTVAL (operands[2]));
6637           return "sub{w}\t{%2, %0|%0, %2}";
6638         }
6639       return "add{w}\t{%2, %0|%0, %2}";
6640     }
6641 }
6642   [(set (attr "type")
6643      (if_then_else (eq_attr "alternative" "2")
6644         (const_string "lea")
6645         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6646            (const_string "incdec")
6647            (const_string "alu"))))
6648    (set_attr "mode" "HI,HI,SI")])
6649
6650 (define_insn "*addhi_1"
6651   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6652         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6653                  (match_operand:HI 2 "general_operand" "ri,rm")))
6654    (clobber (reg:CC FLAGS_REG))]
6655   "TARGET_PARTIAL_REG_STALL
6656    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6657 {
6658   switch (get_attr_type (insn))
6659     {
6660     case TYPE_INCDEC:
6661       if (operands[2] == const1_rtx)
6662         return "inc{w}\t%0";
6663       else
6664         {
6665           gcc_assert (operands[2] == constm1_rtx);
6666           return "dec{w}\t%0";
6667         }
6668
6669     default:
6670       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6671          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6672       if (CONST_INT_P (operands[2])
6673           && (INTVAL (operands[2]) == 128
6674               || (INTVAL (operands[2]) < 0
6675                   && INTVAL (operands[2]) != -128)))
6676         {
6677           operands[2] = GEN_INT (-INTVAL (operands[2]));
6678           return "sub{w}\t{%2, %0|%0, %2}";
6679         }
6680       return "add{w}\t{%2, %0|%0, %2}";
6681     }
6682 }
6683   [(set (attr "type")
6684      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6685         (const_string "incdec")
6686         (const_string "alu")))
6687    (set_attr "mode" "HI")])
6688
6689 (define_insn "*addhi_2"
6690   [(set (reg FLAGS_REG)
6691         (compare
6692           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6693                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6694           (const_int 0)))
6695    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6696         (plus:HI (match_dup 1) (match_dup 2)))]
6697   "ix86_match_ccmode (insn, CCGOCmode)
6698    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6699 {
6700   switch (get_attr_type (insn))
6701     {
6702     case TYPE_INCDEC:
6703       if (operands[2] == const1_rtx)
6704         return "inc{w}\t%0";
6705       else
6706         {
6707           gcc_assert (operands[2] == constm1_rtx);
6708           return "dec{w}\t%0";
6709         }
6710
6711     default:
6712       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6713          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6714       if (CONST_INT_P (operands[2])
6715           && (INTVAL (operands[2]) == 128
6716               || (INTVAL (operands[2]) < 0
6717                   && INTVAL (operands[2]) != -128)))
6718         {
6719           operands[2] = GEN_INT (-INTVAL (operands[2]));
6720           return "sub{w}\t{%2, %0|%0, %2}";
6721         }
6722       return "add{w}\t{%2, %0|%0, %2}";
6723     }
6724 }
6725   [(set (attr "type")
6726      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6727         (const_string "incdec")
6728         (const_string "alu")))
6729    (set_attr "mode" "HI")])
6730
6731 (define_insn "*addhi_3"
6732   [(set (reg FLAGS_REG)
6733         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6734                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6735    (clobber (match_scratch:HI 0 "=r"))]
6736   "ix86_match_ccmode (insn, CCZmode)
6737    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6738 {
6739   switch (get_attr_type (insn))
6740     {
6741     case TYPE_INCDEC:
6742       if (operands[2] == const1_rtx)
6743         return "inc{w}\t%0";
6744       else
6745         {
6746           gcc_assert (operands[2] == constm1_rtx);
6747           return "dec{w}\t%0";
6748         }
6749
6750     default:
6751       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6752          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6753       if (CONST_INT_P (operands[2])
6754           && (INTVAL (operands[2]) == 128
6755               || (INTVAL (operands[2]) < 0
6756                   && INTVAL (operands[2]) != -128)))
6757         {
6758           operands[2] = GEN_INT (-INTVAL (operands[2]));
6759           return "sub{w}\t{%2, %0|%0, %2}";
6760         }
6761       return "add{w}\t{%2, %0|%0, %2}";
6762     }
6763 }
6764   [(set (attr "type")
6765      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6766         (const_string "incdec")
6767         (const_string "alu")))
6768    (set_attr "mode" "HI")])
6769
6770 ; See comments above addsi_4 for details.
6771 (define_insn "*addhi_4"
6772   [(set (reg FLAGS_REG)
6773         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6774                  (match_operand:HI 2 "const_int_operand" "n")))
6775    (clobber (match_scratch:HI 0 "=rm"))]
6776   "ix86_match_ccmode (insn, CCGCmode)
6777    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6778 {
6779   switch (get_attr_type (insn))
6780     {
6781     case TYPE_INCDEC:
6782       if (operands[2] == constm1_rtx)
6783         return "inc{w}\t%0";
6784       else
6785         {
6786           gcc_assert (operands[2] == const1_rtx);
6787           return "dec{w}\t%0";
6788         }
6789
6790     default:
6791       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6792       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6793          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6794       if ((INTVAL (operands[2]) == -128
6795            || (INTVAL (operands[2]) > 0
6796                && INTVAL (operands[2]) != 128)))
6797         return "sub{w}\t{%2, %0|%0, %2}";
6798       operands[2] = GEN_INT (-INTVAL (operands[2]));
6799       return "add{w}\t{%2, %0|%0, %2}";
6800     }
6801 }
6802   [(set (attr "type")
6803      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6804         (const_string "incdec")
6805         (const_string "alu")))
6806    (set_attr "mode" "SI")])
6807
6808
6809 (define_insn "*addhi_5"
6810   [(set (reg FLAGS_REG)
6811         (compare
6812           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6813                    (match_operand:HI 2 "general_operand" "rmni"))
6814           (const_int 0)))
6815    (clobber (match_scratch:HI 0 "=r"))]
6816   "ix86_match_ccmode (insn, CCGOCmode)
6817    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6818 {
6819   switch (get_attr_type (insn))
6820     {
6821     case TYPE_INCDEC:
6822       if (operands[2] == const1_rtx)
6823         return "inc{w}\t%0";
6824       else
6825         {
6826           gcc_assert (operands[2] == constm1_rtx);
6827           return "dec{w}\t%0";
6828         }
6829
6830     default:
6831       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6832          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6833       if (CONST_INT_P (operands[2])
6834           && (INTVAL (operands[2]) == 128
6835               || (INTVAL (operands[2]) < 0
6836                   && INTVAL (operands[2]) != -128)))
6837         {
6838           operands[2] = GEN_INT (-INTVAL (operands[2]));
6839           return "sub{w}\t{%2, %0|%0, %2}";
6840         }
6841       return "add{w}\t{%2, %0|%0, %2}";
6842     }
6843 }
6844   [(set (attr "type")
6845      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6846         (const_string "incdec")
6847         (const_string "alu")))
6848    (set_attr "mode" "HI")])
6849
6850 (define_expand "addqi3"
6851   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6852                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6853                             (match_operand:QI 2 "general_operand" "")))
6854               (clobber (reg:CC FLAGS_REG))])]
6855   "TARGET_QIMODE_MATH"
6856   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6857
6858 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6859 (define_insn "*addqi_1_lea"
6860   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6861         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6862                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6863    (clobber (reg:CC FLAGS_REG))]
6864   "!TARGET_PARTIAL_REG_STALL
6865    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6866 {
6867   int widen = (which_alternative == 2);
6868   switch (get_attr_type (insn))
6869     {
6870     case TYPE_LEA:
6871       return "#";
6872     case TYPE_INCDEC:
6873       if (operands[2] == const1_rtx)
6874         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6875       else
6876         {
6877           gcc_assert (operands[2] == constm1_rtx);
6878           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6879         }
6880
6881     default:
6882       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6883          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6884       if (CONST_INT_P (operands[2])
6885           && (INTVAL (operands[2]) == 128
6886               || (INTVAL (operands[2]) < 0
6887                   && INTVAL (operands[2]) != -128)))
6888         {
6889           operands[2] = GEN_INT (-INTVAL (operands[2]));
6890           if (widen)
6891             return "sub{l}\t{%2, %k0|%k0, %2}";
6892           else
6893             return "sub{b}\t{%2, %0|%0, %2}";
6894         }
6895       if (widen)
6896         return "add{l}\t{%k2, %k0|%k0, %k2}";
6897       else
6898         return "add{b}\t{%2, %0|%0, %2}";
6899     }
6900 }
6901   [(set (attr "type")
6902      (if_then_else (eq_attr "alternative" "3")
6903         (const_string "lea")
6904         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6905            (const_string "incdec")
6906            (const_string "alu"))))
6907    (set_attr "mode" "QI,QI,SI,SI")])
6908
6909 (define_insn "*addqi_1"
6910   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6911         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6912                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6913    (clobber (reg:CC FLAGS_REG))]
6914   "TARGET_PARTIAL_REG_STALL
6915    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6916 {
6917   int widen = (which_alternative == 2);
6918   switch (get_attr_type (insn))
6919     {
6920     case TYPE_INCDEC:
6921       if (operands[2] == const1_rtx)
6922         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6923       else
6924         {
6925           gcc_assert (operands[2] == constm1_rtx);
6926           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6927         }
6928
6929     default:
6930       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6931          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6932       if (CONST_INT_P (operands[2])
6933           && (INTVAL (operands[2]) == 128
6934               || (INTVAL (operands[2]) < 0
6935                   && INTVAL (operands[2]) != -128)))
6936         {
6937           operands[2] = GEN_INT (-INTVAL (operands[2]));
6938           if (widen)
6939             return "sub{l}\t{%2, %k0|%k0, %2}";
6940           else
6941             return "sub{b}\t{%2, %0|%0, %2}";
6942         }
6943       if (widen)
6944         return "add{l}\t{%k2, %k0|%k0, %k2}";
6945       else
6946         return "add{b}\t{%2, %0|%0, %2}";
6947     }
6948 }
6949   [(set (attr "type")
6950      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6951         (const_string "incdec")
6952         (const_string "alu")))
6953    (set_attr "mode" "QI,QI,SI")])
6954
6955 (define_insn "*addqi_1_slp"
6956   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6957         (plus:QI (match_dup 0)
6958                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6959    (clobber (reg:CC FLAGS_REG))]
6960   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6961    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6962 {
6963   switch (get_attr_type (insn))
6964     {
6965     case TYPE_INCDEC:
6966       if (operands[1] == const1_rtx)
6967         return "inc{b}\t%0";
6968       else
6969         {
6970           gcc_assert (operands[1] == constm1_rtx);
6971           return "dec{b}\t%0";
6972         }
6973
6974     default:
6975       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6976       if (CONST_INT_P (operands[1])
6977           && INTVAL (operands[1]) < 0)
6978         {
6979           operands[1] = GEN_INT (-INTVAL (operands[1]));
6980           return "sub{b}\t{%1, %0|%0, %1}";
6981         }
6982       return "add{b}\t{%1, %0|%0, %1}";
6983     }
6984 }
6985   [(set (attr "type")
6986      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6987         (const_string "incdec")
6988         (const_string "alu1")))
6989    (set (attr "memory")
6990      (if_then_else (match_operand 1 "memory_operand" "")
6991         (const_string "load")
6992         (const_string "none")))
6993    (set_attr "mode" "QI")])
6994
6995 (define_insn "*addqi_2"
6996   [(set (reg FLAGS_REG)
6997         (compare
6998           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6999                    (match_operand:QI 2 "general_operand" "qmni,qni"))
7000           (const_int 0)))
7001    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7002         (plus:QI (match_dup 1) (match_dup 2)))]
7003   "ix86_match_ccmode (insn, CCGOCmode)
7004    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7005 {
7006   switch (get_attr_type (insn))
7007     {
7008     case TYPE_INCDEC:
7009       if (operands[2] == const1_rtx)
7010         return "inc{b}\t%0";
7011       else
7012         {
7013           gcc_assert (operands[2] == constm1_rtx
7014                       || (CONST_INT_P (operands[2])
7015                           && INTVAL (operands[2]) == 255));
7016           return "dec{b}\t%0";
7017         }
7018
7019     default:
7020       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7021       if (CONST_INT_P (operands[2])
7022           && INTVAL (operands[2]) < 0)
7023         {
7024           operands[2] = GEN_INT (-INTVAL (operands[2]));
7025           return "sub{b}\t{%2, %0|%0, %2}";
7026         }
7027       return "add{b}\t{%2, %0|%0, %2}";
7028     }
7029 }
7030   [(set (attr "type")
7031      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7032         (const_string "incdec")
7033         (const_string "alu")))
7034    (set_attr "mode" "QI")])
7035
7036 (define_insn "*addqi_3"
7037   [(set (reg FLAGS_REG)
7038         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
7039                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
7040    (clobber (match_scratch:QI 0 "=q"))]
7041   "ix86_match_ccmode (insn, CCZmode)
7042    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7043 {
7044   switch (get_attr_type (insn))
7045     {
7046     case TYPE_INCDEC:
7047       if (operands[2] == const1_rtx)
7048         return "inc{b}\t%0";
7049       else
7050         {
7051           gcc_assert (operands[2] == constm1_rtx
7052                       || (CONST_INT_P (operands[2])
7053                           && INTVAL (operands[2]) == 255));
7054           return "dec{b}\t%0";
7055         }
7056
7057     default:
7058       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7059       if (CONST_INT_P (operands[2])
7060           && INTVAL (operands[2]) < 0)
7061         {
7062           operands[2] = GEN_INT (-INTVAL (operands[2]));
7063           return "sub{b}\t{%2, %0|%0, %2}";
7064         }
7065       return "add{b}\t{%2, %0|%0, %2}";
7066     }
7067 }
7068   [(set (attr "type")
7069      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7070         (const_string "incdec")
7071         (const_string "alu")))
7072    (set_attr "mode" "QI")])
7073
7074 ; See comments above addsi_4 for details.
7075 (define_insn "*addqi_4"
7076   [(set (reg FLAGS_REG)
7077         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7078                  (match_operand:QI 2 "const_int_operand" "n")))
7079    (clobber (match_scratch:QI 0 "=qm"))]
7080   "ix86_match_ccmode (insn, CCGCmode)
7081    && (INTVAL (operands[2]) & 0xff) != 0x80"
7082 {
7083   switch (get_attr_type (insn))
7084     {
7085     case TYPE_INCDEC:
7086       if (operands[2] == constm1_rtx
7087           || (CONST_INT_P (operands[2])
7088               && INTVAL (operands[2]) == 255))
7089         return "inc{b}\t%0";
7090       else
7091         {
7092           gcc_assert (operands[2] == const1_rtx);
7093           return "dec{b}\t%0";
7094         }
7095
7096     default:
7097       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7098       if (INTVAL (operands[2]) < 0)
7099         {
7100           operands[2] = GEN_INT (-INTVAL (operands[2]));
7101           return "add{b}\t{%2, %0|%0, %2}";
7102         }
7103       return "sub{b}\t{%2, %0|%0, %2}";
7104     }
7105 }
7106   [(set (attr "type")
7107      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7108         (const_string "incdec")
7109         (const_string "alu")))
7110    (set_attr "mode" "QI")])
7111
7112
7113 (define_insn "*addqi_5"
7114   [(set (reg FLAGS_REG)
7115         (compare
7116           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7117                    (match_operand:QI 2 "general_operand" "qmni"))
7118           (const_int 0)))
7119    (clobber (match_scratch:QI 0 "=q"))]
7120   "ix86_match_ccmode (insn, CCGOCmode)
7121    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7122 {
7123   switch (get_attr_type (insn))
7124     {
7125     case TYPE_INCDEC:
7126       if (operands[2] == const1_rtx)
7127         return "inc{b}\t%0";
7128       else
7129         {
7130           gcc_assert (operands[2] == constm1_rtx
7131                       || (CONST_INT_P (operands[2])
7132                           && INTVAL (operands[2]) == 255));
7133           return "dec{b}\t%0";
7134         }
7135
7136     default:
7137       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7138       if (CONST_INT_P (operands[2])
7139           && INTVAL (operands[2]) < 0)
7140         {
7141           operands[2] = GEN_INT (-INTVAL (operands[2]));
7142           return "sub{b}\t{%2, %0|%0, %2}";
7143         }
7144       return "add{b}\t{%2, %0|%0, %2}";
7145     }
7146 }
7147   [(set (attr "type")
7148      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7149         (const_string "incdec")
7150         (const_string "alu")))
7151    (set_attr "mode" "QI")])
7152
7153
7154 (define_insn "addqi_ext_1"
7155   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7156                          (const_int 8)
7157                          (const_int 8))
7158         (plus:SI
7159           (zero_extract:SI
7160             (match_operand 1 "ext_register_operand" "0")
7161             (const_int 8)
7162             (const_int 8))
7163           (match_operand:QI 2 "general_operand" "Qmn")))
7164    (clobber (reg:CC FLAGS_REG))]
7165   "!TARGET_64BIT"
7166 {
7167   switch (get_attr_type (insn))
7168     {
7169     case TYPE_INCDEC:
7170       if (operands[2] == const1_rtx)
7171         return "inc{b}\t%h0";
7172       else
7173         {
7174           gcc_assert (operands[2] == constm1_rtx
7175                       || (CONST_INT_P (operands[2])
7176                           && INTVAL (operands[2]) == 255));
7177           return "dec{b}\t%h0";
7178         }
7179
7180     default:
7181       return "add{b}\t{%2, %h0|%h0, %2}";
7182     }
7183 }
7184   [(set (attr "type")
7185      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7186         (const_string "incdec")
7187         (const_string "alu")))
7188    (set_attr "mode" "QI")])
7189
7190 (define_insn "*addqi_ext_1_rex64"
7191   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7192                          (const_int 8)
7193                          (const_int 8))
7194         (plus:SI
7195           (zero_extract:SI
7196             (match_operand 1 "ext_register_operand" "0")
7197             (const_int 8)
7198             (const_int 8))
7199           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7200    (clobber (reg:CC FLAGS_REG))]
7201   "TARGET_64BIT"
7202 {
7203   switch (get_attr_type (insn))
7204     {
7205     case TYPE_INCDEC:
7206       if (operands[2] == const1_rtx)
7207         return "inc{b}\t%h0";
7208       else
7209         {
7210           gcc_assert (operands[2] == constm1_rtx
7211                       || (CONST_INT_P (operands[2])
7212                           && INTVAL (operands[2]) == 255));
7213           return "dec{b}\t%h0";
7214         }
7215
7216     default:
7217       return "add{b}\t{%2, %h0|%h0, %2}";
7218     }
7219 }
7220   [(set (attr "type")
7221      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7222         (const_string "incdec")
7223         (const_string "alu")))
7224    (set_attr "mode" "QI")])
7225
7226 (define_insn "*addqi_ext_2"
7227   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7228                          (const_int 8)
7229                          (const_int 8))
7230         (plus:SI
7231           (zero_extract:SI
7232             (match_operand 1 "ext_register_operand" "%0")
7233             (const_int 8)
7234             (const_int 8))
7235           (zero_extract:SI
7236             (match_operand 2 "ext_register_operand" "Q")
7237             (const_int 8)
7238             (const_int 8))))
7239    (clobber (reg:CC FLAGS_REG))]
7240   ""
7241   "add{b}\t{%h2, %h0|%h0, %h2}"
7242   [(set_attr "type" "alu")
7243    (set_attr "mode" "QI")])
7244
7245 ;; The patterns that match these are at the end of this file.
7246
7247 (define_expand "addxf3"
7248   [(set (match_operand:XF 0 "register_operand" "")
7249         (plus:XF (match_operand:XF 1 "register_operand" "")
7250                  (match_operand:XF 2 "register_operand" "")))]
7251   "TARGET_80387"
7252   "")
7253
7254 (define_expand "add<mode>3"
7255   [(set (match_operand:MODEF 0 "register_operand" "")
7256         (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7257                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7258   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7259   "")
7260 \f
7261 ;; Subtract instructions
7262
7263 ;; %%% splits for subditi3
7264
7265 (define_expand "subti3"
7266   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
7267                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7268                              (match_operand:TI 2 "x86_64_general_operand" "")))
7269               (clobber (reg:CC FLAGS_REG))])]
7270   "TARGET_64BIT"
7271   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7272
7273 (define_insn "*subti3_1"
7274   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7275         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7276                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7277    (clobber (reg:CC FLAGS_REG))]
7278   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7279   "#")
7280
7281 (define_split
7282   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7283         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7284                   (match_operand:TI 2 "x86_64_general_operand" "")))
7285    (clobber (reg:CC FLAGS_REG))]
7286   "TARGET_64BIT && reload_completed"
7287   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7288               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7289    (parallel [(set (match_dup 3)
7290                    (minus:DI (match_dup 4)
7291                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7292                                       (match_dup 5))))
7293               (clobber (reg:CC FLAGS_REG))])]
7294   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7295
7296 ;; %%% splits for subsidi3
7297
7298 (define_expand "subdi3"
7299   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
7300                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7301                              (match_operand:DI 2 "x86_64_general_operand" "")))
7302               (clobber (reg:CC FLAGS_REG))])]
7303   ""
7304   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7305
7306 (define_insn "*subdi3_1"
7307   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7308         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7309                   (match_operand:DI 2 "general_operand" "roiF,riF")))
7310    (clobber (reg:CC FLAGS_REG))]
7311   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7312   "#")
7313
7314 (define_split
7315   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7316         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7317                   (match_operand:DI 2 "general_operand" "")))
7318    (clobber (reg:CC FLAGS_REG))]
7319   "!TARGET_64BIT && reload_completed"
7320   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7321               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7322    (parallel [(set (match_dup 3)
7323                    (minus:SI (match_dup 4)
7324                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7325                                       (match_dup 5))))
7326               (clobber (reg:CC FLAGS_REG))])]
7327   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7328
7329 (define_insn "subdi3_carry_rex64"
7330   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7331           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7332             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7333                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7334    (clobber (reg:CC FLAGS_REG))]
7335   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7336   "sbb{q}\t{%2, %0|%0, %2}"
7337   [(set_attr "type" "alu")
7338    (set_attr "pent_pair" "pu")
7339    (set_attr "mode" "DI")])
7340
7341 (define_insn "*subdi_1_rex64"
7342   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7343         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7344                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7345    (clobber (reg:CC FLAGS_REG))]
7346   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7347   "sub{q}\t{%2, %0|%0, %2}"
7348   [(set_attr "type" "alu")
7349    (set_attr "mode" "DI")])
7350
7351 (define_insn "*subdi_2_rex64"
7352   [(set (reg FLAGS_REG)
7353         (compare
7354           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7355                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7356           (const_int 0)))
7357    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7358         (minus:DI (match_dup 1) (match_dup 2)))]
7359   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7360    && ix86_binary_operator_ok (MINUS, DImode, operands)"
7361   "sub{q}\t{%2, %0|%0, %2}"
7362   [(set_attr "type" "alu")
7363    (set_attr "mode" "DI")])
7364
7365 (define_insn "*subdi_3_rex63"
7366   [(set (reg FLAGS_REG)
7367         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7368                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7369    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7370         (minus:DI (match_dup 1) (match_dup 2)))]
7371   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7372    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7373   "sub{q}\t{%2, %0|%0, %2}"
7374   [(set_attr "type" "alu")
7375    (set_attr "mode" "DI")])
7376
7377 (define_insn "subqi3_carry"
7378   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7379           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7380             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7381                (match_operand:QI 2 "general_operand" "qi,qm"))))
7382    (clobber (reg:CC FLAGS_REG))]
7383   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7384   "sbb{b}\t{%2, %0|%0, %2}"
7385   [(set_attr "type" "alu")
7386    (set_attr "pent_pair" "pu")
7387    (set_attr "mode" "QI")])
7388
7389 (define_insn "subhi3_carry"
7390   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7391           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7392             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7393                (match_operand:HI 2 "general_operand" "ri,rm"))))
7394    (clobber (reg:CC FLAGS_REG))]
7395   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7396   "sbb{w}\t{%2, %0|%0, %2}"
7397   [(set_attr "type" "alu")
7398    (set_attr "pent_pair" "pu")
7399    (set_attr "mode" "HI")])
7400
7401 (define_insn "subsi3_carry"
7402   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7403           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7404             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7405                (match_operand:SI 2 "general_operand" "ri,rm"))))
7406    (clobber (reg:CC FLAGS_REG))]
7407   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7408   "sbb{l}\t{%2, %0|%0, %2}"
7409   [(set_attr "type" "alu")
7410    (set_attr "pent_pair" "pu")
7411    (set_attr "mode" "SI")])
7412
7413 (define_insn "subsi3_carry_zext"
7414   [(set (match_operand:DI 0 "register_operand" "=r")
7415           (zero_extend:DI
7416             (minus:SI (match_operand:SI 1 "register_operand" "0")
7417               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7418                  (match_operand:SI 2 "general_operand" "g")))))
7419    (clobber (reg:CC FLAGS_REG))]
7420   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7421   "sbb{l}\t{%2, %k0|%k0, %2}"
7422   [(set_attr "type" "alu")
7423    (set_attr "pent_pair" "pu")
7424    (set_attr "mode" "SI")])
7425
7426 (define_expand "subsi3"
7427   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7428                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7429                              (match_operand:SI 2 "general_operand" "")))
7430               (clobber (reg:CC FLAGS_REG))])]
7431   ""
7432   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7433
7434 (define_insn "*subsi_1"
7435   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7436         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7437                   (match_operand:SI 2 "general_operand" "ri,rm")))
7438    (clobber (reg:CC FLAGS_REG))]
7439   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7440   "sub{l}\t{%2, %0|%0, %2}"
7441   [(set_attr "type" "alu")
7442    (set_attr "mode" "SI")])
7443
7444 (define_insn "*subsi_1_zext"
7445   [(set (match_operand:DI 0 "register_operand" "=r")
7446         (zero_extend:DI
7447           (minus:SI (match_operand:SI 1 "register_operand" "0")
7448                     (match_operand:SI 2 "general_operand" "g"))))
7449    (clobber (reg:CC FLAGS_REG))]
7450   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7451   "sub{l}\t{%2, %k0|%k0, %2}"
7452   [(set_attr "type" "alu")
7453    (set_attr "mode" "SI")])
7454
7455 (define_insn "*subsi_2"
7456   [(set (reg FLAGS_REG)
7457         (compare
7458           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7459                     (match_operand:SI 2 "general_operand" "ri,rm"))
7460           (const_int 0)))
7461    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7462         (minus:SI (match_dup 1) (match_dup 2)))]
7463   "ix86_match_ccmode (insn, CCGOCmode)
7464    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7465   "sub{l}\t{%2, %0|%0, %2}"
7466   [(set_attr "type" "alu")
7467    (set_attr "mode" "SI")])
7468
7469 (define_insn "*subsi_2_zext"
7470   [(set (reg FLAGS_REG)
7471         (compare
7472           (minus:SI (match_operand:SI 1 "register_operand" "0")
7473                     (match_operand:SI 2 "general_operand" "g"))
7474           (const_int 0)))
7475    (set (match_operand:DI 0 "register_operand" "=r")
7476         (zero_extend:DI
7477           (minus:SI (match_dup 1)
7478                     (match_dup 2))))]
7479   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7480    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7481   "sub{l}\t{%2, %k0|%k0, %2}"
7482   [(set_attr "type" "alu")
7483    (set_attr "mode" "SI")])
7484
7485 (define_insn "*subsi_3"
7486   [(set (reg FLAGS_REG)
7487         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7488                  (match_operand:SI 2 "general_operand" "ri,rm")))
7489    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7490         (minus:SI (match_dup 1) (match_dup 2)))]
7491   "ix86_match_ccmode (insn, CCmode)
7492    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7493   "sub{l}\t{%2, %0|%0, %2}"
7494   [(set_attr "type" "alu")
7495    (set_attr "mode" "SI")])
7496
7497 (define_insn "*subsi_3_zext"
7498   [(set (reg FLAGS_REG)
7499         (compare (match_operand:SI 1 "register_operand" "0")
7500                  (match_operand:SI 2 "general_operand" "g")))
7501    (set (match_operand:DI 0 "register_operand" "=r")
7502         (zero_extend:DI
7503           (minus:SI (match_dup 1)
7504                     (match_dup 2))))]
7505   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7506    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7507   "sub{l}\t{%2, %1|%1, %2}"
7508   [(set_attr "type" "alu")
7509    (set_attr "mode" "DI")])
7510
7511 (define_expand "subhi3"
7512   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7513                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7514                              (match_operand:HI 2 "general_operand" "")))
7515               (clobber (reg:CC FLAGS_REG))])]
7516   "TARGET_HIMODE_MATH"
7517   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7518
7519 (define_insn "*subhi_1"
7520   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7521         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7522                   (match_operand:HI 2 "general_operand" "ri,rm")))
7523    (clobber (reg:CC FLAGS_REG))]
7524   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7525   "sub{w}\t{%2, %0|%0, %2}"
7526   [(set_attr "type" "alu")
7527    (set_attr "mode" "HI")])
7528
7529 (define_insn "*subhi_2"
7530   [(set (reg FLAGS_REG)
7531         (compare
7532           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7533                     (match_operand:HI 2 "general_operand" "ri,rm"))
7534           (const_int 0)))
7535    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7536         (minus:HI (match_dup 1) (match_dup 2)))]
7537   "ix86_match_ccmode (insn, CCGOCmode)
7538    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7539   "sub{w}\t{%2, %0|%0, %2}"
7540   [(set_attr "type" "alu")
7541    (set_attr "mode" "HI")])
7542
7543 (define_insn "*subhi_3"
7544   [(set (reg FLAGS_REG)
7545         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7546                  (match_operand:HI 2 "general_operand" "ri,rm")))
7547    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7548         (minus:HI (match_dup 1) (match_dup 2)))]
7549   "ix86_match_ccmode (insn, CCmode)
7550    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7551   "sub{w}\t{%2, %0|%0, %2}"
7552   [(set_attr "type" "alu")
7553    (set_attr "mode" "HI")])
7554
7555 (define_expand "subqi3"
7556   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7557                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7558                              (match_operand:QI 2 "general_operand" "")))
7559               (clobber (reg:CC FLAGS_REG))])]
7560   "TARGET_QIMODE_MATH"
7561   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7562
7563 (define_insn "*subqi_1"
7564   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7565         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7566                   (match_operand:QI 2 "general_operand" "qn,qmn")))
7567    (clobber (reg:CC FLAGS_REG))]
7568   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7569   "sub{b}\t{%2, %0|%0, %2}"
7570   [(set_attr "type" "alu")
7571    (set_attr "mode" "QI")])
7572
7573 (define_insn "*subqi_1_slp"
7574   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7575         (minus:QI (match_dup 0)
7576                   (match_operand:QI 1 "general_operand" "qn,qmn")))
7577    (clobber (reg:CC FLAGS_REG))]
7578   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7579    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7580   "sub{b}\t{%1, %0|%0, %1}"
7581   [(set_attr "type" "alu1")
7582    (set_attr "mode" "QI")])
7583
7584 (define_insn "*subqi_2"
7585   [(set (reg FLAGS_REG)
7586         (compare
7587           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7588                     (match_operand:QI 2 "general_operand" "qi,qm"))
7589           (const_int 0)))
7590    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7591         (minus:HI (match_dup 1) (match_dup 2)))]
7592   "ix86_match_ccmode (insn, CCGOCmode)
7593    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7594   "sub{b}\t{%2, %0|%0, %2}"
7595   [(set_attr "type" "alu")
7596    (set_attr "mode" "QI")])
7597
7598 (define_insn "*subqi_3"
7599   [(set (reg FLAGS_REG)
7600         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7601                  (match_operand:QI 2 "general_operand" "qi,qm")))
7602    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7603         (minus:HI (match_dup 1) (match_dup 2)))]
7604   "ix86_match_ccmode (insn, CCmode)
7605    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7606   "sub{b}\t{%2, %0|%0, %2}"
7607   [(set_attr "type" "alu")
7608    (set_attr "mode" "QI")])
7609
7610 ;; The patterns that match these are at the end of this file.
7611
7612 (define_expand "subxf3"
7613   [(set (match_operand:XF 0 "register_operand" "")
7614         (minus:XF (match_operand:XF 1 "register_operand" "")
7615                   (match_operand:XF 2 "register_operand" "")))]
7616   "TARGET_80387"
7617   "")
7618
7619 (define_expand "sub<mode>3"
7620   [(set (match_operand:MODEF 0 "register_operand" "")
7621         (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7622                      (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7623   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7624   "")
7625 \f
7626 ;; Multiply instructions
7627
7628 (define_expand "muldi3"
7629   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7630                    (mult:DI (match_operand:DI 1 "register_operand" "")
7631                             (match_operand:DI 2 "x86_64_general_operand" "")))
7632               (clobber (reg:CC FLAGS_REG))])]
7633   "TARGET_64BIT"
7634   "")
7635
7636 ;; On AMDFAM10
7637 ;; IMUL reg64, reg64, imm8      Direct
7638 ;; IMUL reg64, mem64, imm8      VectorPath
7639 ;; IMUL reg64, reg64, imm32     Direct
7640 ;; IMUL reg64, mem64, imm32     VectorPath
7641 ;; IMUL reg64, reg64            Direct
7642 ;; IMUL reg64, mem64            Direct
7643
7644 (define_insn "*muldi3_1_rex64"
7645   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7646         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7647                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7648    (clobber (reg:CC FLAGS_REG))]
7649   "TARGET_64BIT
7650    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7651   "@
7652    imul{q}\t{%2, %1, %0|%0, %1, %2}
7653    imul{q}\t{%2, %1, %0|%0, %1, %2}
7654    imul{q}\t{%2, %0|%0, %2}"
7655   [(set_attr "type" "imul")
7656    (set_attr "prefix_0f" "0,0,1")
7657    (set (attr "athlon_decode")
7658         (cond [(eq_attr "cpu" "athlon")
7659                   (const_string "vector")
7660                (eq_attr "alternative" "1")
7661                   (const_string "vector")
7662                (and (eq_attr "alternative" "2")
7663                     (match_operand 1 "memory_operand" ""))
7664                   (const_string "vector")]
7665               (const_string "direct")))
7666    (set (attr "amdfam10_decode")
7667         (cond [(and (eq_attr "alternative" "0,1")
7668                     (match_operand 1 "memory_operand" ""))
7669                   (const_string "vector")]
7670               (const_string "direct")))
7671    (set_attr "mode" "DI")])
7672
7673 (define_expand "mulsi3"
7674   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7675                    (mult:SI (match_operand:SI 1 "register_operand" "")
7676                             (match_operand:SI 2 "general_operand" "")))
7677               (clobber (reg:CC FLAGS_REG))])]
7678   ""
7679   "")
7680
7681 ;; On AMDFAM10
7682 ;; IMUL reg32, reg32, imm8      Direct
7683 ;; IMUL reg32, mem32, imm8      VectorPath
7684 ;; IMUL reg32, reg32, imm32     Direct
7685 ;; IMUL reg32, mem32, imm32     VectorPath
7686 ;; IMUL reg32, reg32            Direct
7687 ;; IMUL reg32, mem32            Direct
7688
7689 (define_insn "*mulsi3_1"
7690   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7691         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7692                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7693    (clobber (reg:CC FLAGS_REG))]
7694   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7695   "@
7696    imul{l}\t{%2, %1, %0|%0, %1, %2}
7697    imul{l}\t{%2, %1, %0|%0, %1, %2}
7698    imul{l}\t{%2, %0|%0, %2}"
7699   [(set_attr "type" "imul")
7700    (set_attr "prefix_0f" "0,0,1")
7701    (set (attr "athlon_decode")
7702         (cond [(eq_attr "cpu" "athlon")
7703                   (const_string "vector")
7704                (eq_attr "alternative" "1")
7705                   (const_string "vector")
7706                (and (eq_attr "alternative" "2")
7707                     (match_operand 1 "memory_operand" ""))
7708                   (const_string "vector")]
7709               (const_string "direct")))
7710    (set (attr "amdfam10_decode")
7711         (cond [(and (eq_attr "alternative" "0,1")
7712                     (match_operand 1 "memory_operand" ""))
7713                   (const_string "vector")]
7714               (const_string "direct")))
7715    (set_attr "mode" "SI")])
7716
7717 (define_insn "*mulsi3_1_zext"
7718   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7719         (zero_extend:DI
7720           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7721                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7722    (clobber (reg:CC FLAGS_REG))]
7723   "TARGET_64BIT
7724    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7725   "@
7726    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7727    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7728    imul{l}\t{%2, %k0|%k0, %2}"
7729   [(set_attr "type" "imul")
7730    (set_attr "prefix_0f" "0,0,1")
7731    (set (attr "athlon_decode")
7732         (cond [(eq_attr "cpu" "athlon")
7733                   (const_string "vector")
7734                (eq_attr "alternative" "1")
7735                   (const_string "vector")
7736                (and (eq_attr "alternative" "2")
7737                     (match_operand 1 "memory_operand" ""))
7738                   (const_string "vector")]
7739               (const_string "direct")))
7740    (set (attr "amdfam10_decode")
7741         (cond [(and (eq_attr "alternative" "0,1")
7742                     (match_operand 1 "memory_operand" ""))
7743                   (const_string "vector")]
7744               (const_string "direct")))
7745    (set_attr "mode" "SI")])
7746
7747 (define_expand "mulhi3"
7748   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7749                    (mult:HI (match_operand:HI 1 "register_operand" "")
7750                             (match_operand:HI 2 "general_operand" "")))
7751               (clobber (reg:CC FLAGS_REG))])]
7752   "TARGET_HIMODE_MATH"
7753   "")
7754
7755 ;; On AMDFAM10
7756 ;; IMUL reg16, reg16, imm8      VectorPath
7757 ;; IMUL reg16, mem16, imm8      VectorPath
7758 ;; IMUL reg16, reg16, imm16     VectorPath
7759 ;; IMUL reg16, mem16, imm16     VectorPath
7760 ;; IMUL reg16, reg16            Direct
7761 ;; IMUL reg16, mem16            Direct
7762 (define_insn "*mulhi3_1"
7763   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7764         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7765                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7766    (clobber (reg:CC FLAGS_REG))]
7767   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7768   "@
7769    imul{w}\t{%2, %1, %0|%0, %1, %2}
7770    imul{w}\t{%2, %1, %0|%0, %1, %2}
7771    imul{w}\t{%2, %0|%0, %2}"
7772   [(set_attr "type" "imul")
7773    (set_attr "prefix_0f" "0,0,1")
7774    (set (attr "athlon_decode")
7775         (cond [(eq_attr "cpu" "athlon")
7776                   (const_string "vector")
7777                (eq_attr "alternative" "1,2")
7778                   (const_string "vector")]
7779               (const_string "direct")))
7780    (set (attr "amdfam10_decode")
7781         (cond [(eq_attr "alternative" "0,1")
7782                   (const_string "vector")]
7783               (const_string "direct")))
7784    (set_attr "mode" "HI")])
7785
7786 (define_expand "mulqi3"
7787   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7788                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7789                             (match_operand:QI 2 "register_operand" "")))
7790               (clobber (reg:CC FLAGS_REG))])]
7791   "TARGET_QIMODE_MATH"
7792   "")
7793
7794 ;;On AMDFAM10
7795 ;; MUL reg8     Direct
7796 ;; MUL mem8     Direct
7797
7798 (define_insn "*mulqi3_1"
7799   [(set (match_operand:QI 0 "register_operand" "=a")
7800         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7801                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7802    (clobber (reg:CC FLAGS_REG))]
7803   "TARGET_QIMODE_MATH
7804    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7805   "mul{b}\t%2"
7806   [(set_attr "type" "imul")
7807    (set_attr "length_immediate" "0")
7808    (set (attr "athlon_decode")
7809      (if_then_else (eq_attr "cpu" "athlon")
7810         (const_string "vector")
7811         (const_string "direct")))
7812    (set_attr "amdfam10_decode" "direct")
7813    (set_attr "mode" "QI")])
7814
7815 (define_expand "umulqihi3"
7816   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7817                    (mult:HI (zero_extend:HI
7818                               (match_operand:QI 1 "nonimmediate_operand" ""))
7819                             (zero_extend:HI
7820                               (match_operand:QI 2 "register_operand" ""))))
7821               (clobber (reg:CC FLAGS_REG))])]
7822   "TARGET_QIMODE_MATH"
7823   "")
7824
7825 (define_insn "*umulqihi3_1"
7826   [(set (match_operand:HI 0 "register_operand" "=a")
7827         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7828                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7829    (clobber (reg:CC FLAGS_REG))]
7830   "TARGET_QIMODE_MATH
7831    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7832   "mul{b}\t%2"
7833   [(set_attr "type" "imul")
7834    (set_attr "length_immediate" "0")
7835    (set (attr "athlon_decode")
7836      (if_then_else (eq_attr "cpu" "athlon")
7837         (const_string "vector")
7838         (const_string "direct")))
7839    (set_attr "amdfam10_decode" "direct")
7840    (set_attr "mode" "QI")])
7841
7842 (define_expand "mulqihi3"
7843   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7844                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7845                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7846               (clobber (reg:CC FLAGS_REG))])]
7847   "TARGET_QIMODE_MATH"
7848   "")
7849
7850 (define_insn "*mulqihi3_insn"
7851   [(set (match_operand:HI 0 "register_operand" "=a")
7852         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7853                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7854    (clobber (reg:CC FLAGS_REG))]
7855   "TARGET_QIMODE_MATH
7856    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7857   "imul{b}\t%2"
7858   [(set_attr "type" "imul")
7859    (set_attr "length_immediate" "0")
7860    (set (attr "athlon_decode")
7861      (if_then_else (eq_attr "cpu" "athlon")
7862         (const_string "vector")
7863         (const_string "direct")))
7864    (set_attr "amdfam10_decode" "direct")
7865    (set_attr "mode" "QI")])
7866
7867 (define_expand "umulditi3"
7868   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7869                    (mult:TI (zero_extend:TI
7870                               (match_operand:DI 1 "nonimmediate_operand" ""))
7871                             (zero_extend:TI
7872                               (match_operand:DI 2 "register_operand" ""))))
7873               (clobber (reg:CC FLAGS_REG))])]
7874   "TARGET_64BIT"
7875   "")
7876
7877 (define_insn "*umulditi3_insn"
7878   [(set (match_operand:TI 0 "register_operand" "=A")
7879         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7880                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7881    (clobber (reg:CC FLAGS_REG))]
7882   "TARGET_64BIT
7883    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7884   "mul{q}\t%2"
7885   [(set_attr "type" "imul")
7886    (set_attr "length_immediate" "0")
7887    (set (attr "athlon_decode")
7888      (if_then_else (eq_attr "cpu" "athlon")
7889         (const_string "vector")
7890         (const_string "double")))
7891    (set_attr "amdfam10_decode" "double")
7892    (set_attr "mode" "DI")])
7893
7894 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7895 (define_expand "umulsidi3"
7896   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7897                    (mult:DI (zero_extend:DI
7898                               (match_operand:SI 1 "nonimmediate_operand" ""))
7899                             (zero_extend:DI
7900                               (match_operand:SI 2 "register_operand" ""))))
7901               (clobber (reg:CC FLAGS_REG))])]
7902   "!TARGET_64BIT"
7903   "")
7904
7905 (define_insn "*umulsidi3_insn"
7906   [(set (match_operand:DI 0 "register_operand" "=A")
7907         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7908                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7909    (clobber (reg:CC FLAGS_REG))]
7910   "!TARGET_64BIT
7911    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7912   "mul{l}\t%2"
7913   [(set_attr "type" "imul")
7914    (set_attr "length_immediate" "0")
7915    (set (attr "athlon_decode")
7916      (if_then_else (eq_attr "cpu" "athlon")
7917         (const_string "vector")
7918         (const_string "double")))
7919    (set_attr "amdfam10_decode" "double")
7920    (set_attr "mode" "SI")])
7921
7922 (define_expand "mulditi3"
7923   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7924                    (mult:TI (sign_extend:TI
7925                               (match_operand:DI 1 "nonimmediate_operand" ""))
7926                             (sign_extend:TI
7927                               (match_operand:DI 2 "register_operand" ""))))
7928               (clobber (reg:CC FLAGS_REG))])]
7929   "TARGET_64BIT"
7930   "")
7931
7932 (define_insn "*mulditi3_insn"
7933   [(set (match_operand:TI 0 "register_operand" "=A")
7934         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7935                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7936    (clobber (reg:CC FLAGS_REG))]
7937   "TARGET_64BIT
7938    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7939   "imul{q}\t%2"
7940   [(set_attr "type" "imul")
7941    (set_attr "length_immediate" "0")
7942    (set (attr "athlon_decode")
7943      (if_then_else (eq_attr "cpu" "athlon")
7944         (const_string "vector")
7945         (const_string "double")))
7946    (set_attr "amdfam10_decode" "double")
7947    (set_attr "mode" "DI")])
7948
7949 (define_expand "mulsidi3"
7950   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7951                    (mult:DI (sign_extend:DI
7952                               (match_operand:SI 1 "nonimmediate_operand" ""))
7953                             (sign_extend:DI
7954                               (match_operand:SI 2 "register_operand" ""))))
7955               (clobber (reg:CC FLAGS_REG))])]
7956   "!TARGET_64BIT"
7957   "")
7958
7959 (define_insn "*mulsidi3_insn"
7960   [(set (match_operand:DI 0 "register_operand" "=A")
7961         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7962                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7963    (clobber (reg:CC FLAGS_REG))]
7964   "!TARGET_64BIT
7965    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7966   "imul{l}\t%2"
7967   [(set_attr "type" "imul")
7968    (set_attr "length_immediate" "0")
7969    (set (attr "athlon_decode")
7970      (if_then_else (eq_attr "cpu" "athlon")
7971         (const_string "vector")
7972         (const_string "double")))
7973    (set_attr "amdfam10_decode" "double")
7974    (set_attr "mode" "SI")])
7975
7976 (define_expand "umuldi3_highpart"
7977   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7978                    (truncate:DI
7979                      (lshiftrt:TI
7980                        (mult:TI (zero_extend:TI
7981                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7982                                 (zero_extend:TI
7983                                   (match_operand:DI 2 "register_operand" "")))
7984                        (const_int 64))))
7985               (clobber (match_scratch:DI 3 ""))
7986               (clobber (reg:CC FLAGS_REG))])]
7987   "TARGET_64BIT"
7988   "")
7989
7990 (define_insn "*umuldi3_highpart_rex64"
7991   [(set (match_operand:DI 0 "register_operand" "=d")
7992         (truncate:DI
7993           (lshiftrt:TI
7994             (mult:TI (zero_extend:TI
7995                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7996                      (zero_extend:TI
7997                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7998             (const_int 64))))
7999    (clobber (match_scratch:DI 3 "=1"))
8000    (clobber (reg:CC FLAGS_REG))]
8001   "TARGET_64BIT
8002    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8003   "mul{q}\t%2"
8004   [(set_attr "type" "imul")
8005    (set_attr "length_immediate" "0")
8006    (set (attr "athlon_decode")
8007      (if_then_else (eq_attr "cpu" "athlon")
8008         (const_string "vector")
8009         (const_string "double")))
8010    (set_attr "amdfam10_decode" "double")
8011    (set_attr "mode" "DI")])
8012
8013 (define_expand "umulsi3_highpart"
8014   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8015                    (truncate:SI
8016                      (lshiftrt:DI
8017                        (mult:DI (zero_extend:DI
8018                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8019                                 (zero_extend:DI
8020                                   (match_operand:SI 2 "register_operand" "")))
8021                        (const_int 32))))
8022               (clobber (match_scratch:SI 3 ""))
8023               (clobber (reg:CC FLAGS_REG))])]
8024   ""
8025   "")
8026
8027 (define_insn "*umulsi3_highpart_insn"
8028   [(set (match_operand:SI 0 "register_operand" "=d")
8029         (truncate:SI
8030           (lshiftrt:DI
8031             (mult:DI (zero_extend:DI
8032                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8033                      (zero_extend:DI
8034                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8035             (const_int 32))))
8036    (clobber (match_scratch:SI 3 "=1"))
8037    (clobber (reg:CC FLAGS_REG))]
8038   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8039   "mul{l}\t%2"
8040   [(set_attr "type" "imul")
8041    (set_attr "length_immediate" "0")
8042    (set (attr "athlon_decode")
8043      (if_then_else (eq_attr "cpu" "athlon")
8044         (const_string "vector")
8045         (const_string "double")))
8046    (set_attr "amdfam10_decode" "double")
8047    (set_attr "mode" "SI")])
8048
8049 (define_insn "*umulsi3_highpart_zext"
8050   [(set (match_operand:DI 0 "register_operand" "=d")
8051         (zero_extend:DI (truncate:SI
8052           (lshiftrt:DI
8053             (mult:DI (zero_extend:DI
8054                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8055                      (zero_extend:DI
8056                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8057             (const_int 32)))))
8058    (clobber (match_scratch:SI 3 "=1"))
8059    (clobber (reg:CC FLAGS_REG))]
8060   "TARGET_64BIT
8061    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8062   "mul{l}\t%2"
8063   [(set_attr "type" "imul")
8064    (set_attr "length_immediate" "0")
8065    (set (attr "athlon_decode")
8066      (if_then_else (eq_attr "cpu" "athlon")
8067         (const_string "vector")
8068         (const_string "double")))
8069    (set_attr "amdfam10_decode" "double")
8070    (set_attr "mode" "SI")])
8071
8072 (define_expand "smuldi3_highpart"
8073   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8074                    (truncate:DI
8075                      (lshiftrt:TI
8076                        (mult:TI (sign_extend:TI
8077                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8078                                 (sign_extend:TI
8079                                   (match_operand:DI 2 "register_operand" "")))
8080                        (const_int 64))))
8081               (clobber (match_scratch:DI 3 ""))
8082               (clobber (reg:CC FLAGS_REG))])]
8083   "TARGET_64BIT"
8084   "")
8085
8086 (define_insn "*smuldi3_highpart_rex64"
8087   [(set (match_operand:DI 0 "register_operand" "=d")
8088         (truncate:DI
8089           (lshiftrt:TI
8090             (mult:TI (sign_extend:TI
8091                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8092                      (sign_extend:TI
8093                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8094             (const_int 64))))
8095    (clobber (match_scratch:DI 3 "=1"))
8096    (clobber (reg:CC FLAGS_REG))]
8097   "TARGET_64BIT
8098    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8099   "imul{q}\t%2"
8100   [(set_attr "type" "imul")
8101    (set (attr "athlon_decode")
8102      (if_then_else (eq_attr "cpu" "athlon")
8103         (const_string "vector")
8104         (const_string "double")))
8105    (set_attr "amdfam10_decode" "double")
8106    (set_attr "mode" "DI")])
8107
8108 (define_expand "smulsi3_highpart"
8109   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8110                    (truncate:SI
8111                      (lshiftrt:DI
8112                        (mult:DI (sign_extend:DI
8113                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8114                                 (sign_extend:DI
8115                                   (match_operand:SI 2 "register_operand" "")))
8116                        (const_int 32))))
8117               (clobber (match_scratch:SI 3 ""))
8118               (clobber (reg:CC FLAGS_REG))])]
8119   ""
8120   "")
8121
8122 (define_insn "*smulsi3_highpart_insn"
8123   [(set (match_operand:SI 0 "register_operand" "=d")
8124         (truncate:SI
8125           (lshiftrt:DI
8126             (mult:DI (sign_extend:DI
8127                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8128                      (sign_extend:DI
8129                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8130             (const_int 32))))
8131    (clobber (match_scratch:SI 3 "=1"))
8132    (clobber (reg:CC FLAGS_REG))]
8133   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8134   "imul{l}\t%2"
8135   [(set_attr "type" "imul")
8136    (set (attr "athlon_decode")
8137      (if_then_else (eq_attr "cpu" "athlon")
8138         (const_string "vector")
8139         (const_string "double")))
8140    (set_attr "amdfam10_decode" "double")
8141    (set_attr "mode" "SI")])
8142
8143 (define_insn "*smulsi3_highpart_zext"
8144   [(set (match_operand:DI 0 "register_operand" "=d")
8145         (zero_extend:DI (truncate:SI
8146           (lshiftrt:DI
8147             (mult:DI (sign_extend:DI
8148                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8149                      (sign_extend:DI
8150                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8151             (const_int 32)))))
8152    (clobber (match_scratch:SI 3 "=1"))
8153    (clobber (reg:CC FLAGS_REG))]
8154   "TARGET_64BIT
8155    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8156   "imul{l}\t%2"
8157   [(set_attr "type" "imul")
8158    (set (attr "athlon_decode")
8159      (if_then_else (eq_attr "cpu" "athlon")
8160         (const_string "vector")
8161         (const_string "double")))
8162    (set_attr "amdfam10_decode" "double")
8163    (set_attr "mode" "SI")])
8164
8165 ;; The patterns that match these are at the end of this file.
8166
8167 (define_expand "mulxf3"
8168   [(set (match_operand:XF 0 "register_operand" "")
8169         (mult:XF (match_operand:XF 1 "register_operand" "")
8170                  (match_operand:XF 2 "register_operand" "")))]
8171   "TARGET_80387"
8172   "")
8173
8174 (define_expand "mul<mode>3"
8175   [(set (match_operand:MODEF 0 "register_operand" "")
8176         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8177                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8178   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8179   "")
8180
8181 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8182
8183 \f
8184 ;; Divide instructions
8185
8186 (define_insn "divqi3"
8187   [(set (match_operand:QI 0 "register_operand" "=a")
8188         (div:QI (match_operand:HI 1 "register_operand" "0")
8189                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8190    (clobber (reg:CC FLAGS_REG))]
8191   "TARGET_QIMODE_MATH"
8192   "idiv{b}\t%2"
8193   [(set_attr "type" "idiv")
8194    (set_attr "mode" "QI")])
8195
8196 (define_insn "udivqi3"
8197   [(set (match_operand:QI 0 "register_operand" "=a")
8198         (udiv:QI (match_operand:HI 1 "register_operand" "0")
8199                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8200    (clobber (reg:CC FLAGS_REG))]
8201   "TARGET_QIMODE_MATH"
8202   "div{b}\t%2"
8203   [(set_attr "type" "idiv")
8204    (set_attr "mode" "QI")])
8205
8206 ;; The patterns that match these are at the end of this file.
8207
8208 (define_expand "divxf3"
8209   [(set (match_operand:XF 0 "register_operand" "")
8210         (div:XF (match_operand:XF 1 "register_operand" "")
8211                 (match_operand:XF 2 "register_operand" "")))]
8212   "TARGET_80387"
8213   "")
8214
8215 (define_expand "divdf3"
8216   [(set (match_operand:DF 0 "register_operand" "")
8217         (div:DF (match_operand:DF 1 "register_operand" "")
8218                 (match_operand:DF 2 "nonimmediate_operand" "")))]
8219    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8220    "")
8221
8222 (define_expand "divsf3"
8223   [(set (match_operand:SF 0 "register_operand" "")
8224         (div:SF (match_operand:SF 1 "register_operand" "")
8225                 (match_operand:SF 2 "nonimmediate_operand" "")))]
8226   "TARGET_80387 || TARGET_SSE_MATH"
8227 {
8228   if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8229       && flag_finite_math_only && !flag_trapping_math
8230       && flag_unsafe_math_optimizations)
8231     {
8232       ix86_emit_swdivsf (operands[0], operands[1],
8233                          operands[2], SFmode);
8234       DONE;
8235     }
8236 })
8237 \f
8238 ;; Remainder instructions.
8239
8240 (define_expand "divmoddi4"
8241   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8242                    (div:DI (match_operand:DI 1 "register_operand" "")
8243                            (match_operand:DI 2 "nonimmediate_operand" "")))
8244               (set (match_operand:DI 3 "register_operand" "")
8245                    (mod:DI (match_dup 1) (match_dup 2)))
8246               (clobber (reg:CC FLAGS_REG))])]
8247   "TARGET_64BIT"
8248   "")
8249
8250 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8251 ;; Penalize eax case slightly because it results in worse scheduling
8252 ;; of code.
8253 (define_insn "*divmoddi4_nocltd_rex64"
8254   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8255         (div:DI (match_operand:DI 2 "register_operand" "1,0")
8256                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8257    (set (match_operand:DI 1 "register_operand" "=&d,&d")
8258         (mod:DI (match_dup 2) (match_dup 3)))
8259    (clobber (reg:CC FLAGS_REG))]
8260   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8261   "#"
8262   [(set_attr "type" "multi")])
8263
8264 (define_insn "*divmoddi4_cltd_rex64"
8265   [(set (match_operand:DI 0 "register_operand" "=a")
8266         (div:DI (match_operand:DI 2 "register_operand" "a")
8267                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8268    (set (match_operand:DI 1 "register_operand" "=&d")
8269         (mod:DI (match_dup 2) (match_dup 3)))
8270    (clobber (reg:CC FLAGS_REG))]
8271   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8272   "#"
8273   [(set_attr "type" "multi")])
8274
8275 (define_insn "*divmoddi_noext_rex64"
8276   [(set (match_operand:DI 0 "register_operand" "=a")
8277         (div: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         (mod:DI (match_dup 1) (match_dup 2)))
8281    (use (match_operand:DI 4 "register_operand" "3"))
8282    (clobber (reg:CC FLAGS_REG))]
8283   "TARGET_64BIT"
8284   "idiv{q}\t%2"
8285   [(set_attr "type" "idiv")
8286    (set_attr "mode" "DI")])
8287
8288 (define_split
8289   [(set (match_operand:DI 0 "register_operand" "")
8290         (div:DI (match_operand:DI 1 "register_operand" "")
8291                 (match_operand:DI 2 "nonimmediate_operand" "")))
8292    (set (match_operand:DI 3 "register_operand" "")
8293         (mod:DI (match_dup 1) (match_dup 2)))
8294    (clobber (reg:CC FLAGS_REG))]
8295   "TARGET_64BIT && reload_completed"
8296   [(parallel [(set (match_dup 3)
8297                    (ashiftrt:DI (match_dup 4) (const_int 63)))
8298               (clobber (reg:CC FLAGS_REG))])
8299    (parallel [(set (match_dup 0)
8300                    (div:DI (reg:DI 0) (match_dup 2)))
8301               (set (match_dup 3)
8302                    (mod:DI (reg:DI 0) (match_dup 2)))
8303               (use (match_dup 3))
8304               (clobber (reg:CC FLAGS_REG))])]
8305 {
8306   /* Avoid use of cltd in favor of a mov+shift.  */
8307   if (!TARGET_USE_CLTD && !optimize_size)
8308     {
8309       if (true_regnum (operands[1]))
8310         emit_move_insn (operands[0], operands[1]);
8311       else
8312         emit_move_insn (operands[3], operands[1]);
8313       operands[4] = operands[3];
8314     }
8315   else
8316     {
8317       gcc_assert (!true_regnum (operands[1]));
8318       operands[4] = operands[1];
8319     }
8320 })
8321
8322
8323 (define_expand "divmodsi4"
8324   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8325                    (div:SI (match_operand:SI 1 "register_operand" "")
8326                            (match_operand:SI 2 "nonimmediate_operand" "")))
8327               (set (match_operand:SI 3 "register_operand" "")
8328                    (mod:SI (match_dup 1) (match_dup 2)))
8329               (clobber (reg:CC FLAGS_REG))])]
8330   ""
8331   "")
8332
8333 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8334 ;; Penalize eax case slightly because it results in worse scheduling
8335 ;; of code.
8336 (define_insn "*divmodsi4_nocltd"
8337   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8338         (div:SI (match_operand:SI 2 "register_operand" "1,0")
8339                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8340    (set (match_operand:SI 1 "register_operand" "=&d,&d")
8341         (mod:SI (match_dup 2) (match_dup 3)))
8342    (clobber (reg:CC FLAGS_REG))]
8343   "!optimize_size && !TARGET_USE_CLTD"
8344   "#"
8345   [(set_attr "type" "multi")])
8346
8347 (define_insn "*divmodsi4_cltd"
8348   [(set (match_operand:SI 0 "register_operand" "=a")
8349         (div:SI (match_operand:SI 2 "register_operand" "a")
8350                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8351    (set (match_operand:SI 1 "register_operand" "=&d")
8352         (mod:SI (match_dup 2) (match_dup 3)))
8353    (clobber (reg:CC FLAGS_REG))]
8354   "optimize_size || TARGET_USE_CLTD"
8355   "#"
8356   [(set_attr "type" "multi")])
8357
8358 (define_insn "*divmodsi_noext"
8359   [(set (match_operand:SI 0 "register_operand" "=a")
8360         (div:SI (match_operand:SI 1 "register_operand" "0")
8361                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8362    (set (match_operand:SI 3 "register_operand" "=d")
8363         (mod:SI (match_dup 1) (match_dup 2)))
8364    (use (match_operand:SI 4 "register_operand" "3"))
8365    (clobber (reg:CC FLAGS_REG))]
8366   ""
8367   "idiv{l}\t%2"
8368   [(set_attr "type" "idiv")
8369    (set_attr "mode" "SI")])
8370
8371 (define_split
8372   [(set (match_operand:SI 0 "register_operand" "")
8373         (div:SI (match_operand:SI 1 "register_operand" "")
8374                 (match_operand:SI 2 "nonimmediate_operand" "")))
8375    (set (match_operand:SI 3 "register_operand" "")
8376         (mod:SI (match_dup 1) (match_dup 2)))
8377    (clobber (reg:CC FLAGS_REG))]
8378   "reload_completed"
8379   [(parallel [(set (match_dup 3)
8380                    (ashiftrt:SI (match_dup 4) (const_int 31)))
8381               (clobber (reg:CC FLAGS_REG))])
8382    (parallel [(set (match_dup 0)
8383                    (div:SI (reg:SI 0) (match_dup 2)))
8384               (set (match_dup 3)
8385                    (mod:SI (reg:SI 0) (match_dup 2)))
8386               (use (match_dup 3))
8387               (clobber (reg:CC FLAGS_REG))])]
8388 {
8389   /* Avoid use of cltd in favor of a mov+shift.  */
8390   if (!TARGET_USE_CLTD && !optimize_size)
8391     {
8392       if (true_regnum (operands[1]))
8393         emit_move_insn (operands[0], operands[1]);
8394       else
8395         emit_move_insn (operands[3], operands[1]);
8396       operands[4] = operands[3];
8397     }
8398   else
8399     {
8400       gcc_assert (!true_regnum (operands[1]));
8401       operands[4] = operands[1];
8402     }
8403 })
8404 ;; %%% Split me.
8405 (define_insn "divmodhi4"
8406   [(set (match_operand:HI 0 "register_operand" "=a")
8407         (div:HI (match_operand:HI 1 "register_operand" "0")
8408                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8409    (set (match_operand:HI 3 "register_operand" "=&d")
8410         (mod:HI (match_dup 1) (match_dup 2)))
8411    (clobber (reg:CC FLAGS_REG))]
8412   "TARGET_HIMODE_MATH"
8413   "cwtd\;idiv{w}\t%2"
8414   [(set_attr "type" "multi")
8415    (set_attr "length_immediate" "0")
8416    (set_attr "mode" "SI")])
8417
8418 (define_insn "udivmoddi4"
8419   [(set (match_operand:DI 0 "register_operand" "=a")
8420         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8421                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8422    (set (match_operand:DI 3 "register_operand" "=&d")
8423         (umod:DI (match_dup 1) (match_dup 2)))
8424    (clobber (reg:CC FLAGS_REG))]
8425   "TARGET_64BIT"
8426   "xor{q}\t%3, %3\;div{q}\t%2"
8427   [(set_attr "type" "multi")
8428    (set_attr "length_immediate" "0")
8429    (set_attr "mode" "DI")])
8430
8431 (define_insn "*udivmoddi4_noext"
8432   [(set (match_operand:DI 0 "register_operand" "=a")
8433         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8434                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8435    (set (match_operand:DI 3 "register_operand" "=d")
8436         (umod:DI (match_dup 1) (match_dup 2)))
8437    (use (match_dup 3))
8438    (clobber (reg:CC FLAGS_REG))]
8439   "TARGET_64BIT"
8440   "div{q}\t%2"
8441   [(set_attr "type" "idiv")
8442    (set_attr "mode" "DI")])
8443
8444 (define_split
8445   [(set (match_operand:DI 0 "register_operand" "")
8446         (udiv:DI (match_operand:DI 1 "register_operand" "")
8447                  (match_operand:DI 2 "nonimmediate_operand" "")))
8448    (set (match_operand:DI 3 "register_operand" "")
8449         (umod:DI (match_dup 1) (match_dup 2)))
8450    (clobber (reg:CC FLAGS_REG))]
8451   "TARGET_64BIT && reload_completed"
8452   [(set (match_dup 3) (const_int 0))
8453    (parallel [(set (match_dup 0)
8454                    (udiv:DI (match_dup 1) (match_dup 2)))
8455               (set (match_dup 3)
8456                    (umod:DI (match_dup 1) (match_dup 2)))
8457               (use (match_dup 3))
8458               (clobber (reg:CC FLAGS_REG))])]
8459   "")
8460
8461 (define_insn "udivmodsi4"
8462   [(set (match_operand:SI 0 "register_operand" "=a")
8463         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8464                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8465    (set (match_operand:SI 3 "register_operand" "=&d")
8466         (umod:SI (match_dup 1) (match_dup 2)))
8467    (clobber (reg:CC FLAGS_REG))]
8468   ""
8469   "xor{l}\t%3, %3\;div{l}\t%2"
8470   [(set_attr "type" "multi")
8471    (set_attr "length_immediate" "0")
8472    (set_attr "mode" "SI")])
8473
8474 (define_insn "*udivmodsi4_noext"
8475   [(set (match_operand:SI 0 "register_operand" "=a")
8476         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8477                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8478    (set (match_operand:SI 3 "register_operand" "=d")
8479         (umod:SI (match_dup 1) (match_dup 2)))
8480    (use (match_dup 3))
8481    (clobber (reg:CC FLAGS_REG))]
8482   ""
8483   "div{l}\t%2"
8484   [(set_attr "type" "idiv")
8485    (set_attr "mode" "SI")])
8486
8487 (define_split
8488   [(set (match_operand:SI 0 "register_operand" "")
8489         (udiv:SI (match_operand:SI 1 "register_operand" "")
8490                  (match_operand:SI 2 "nonimmediate_operand" "")))
8491    (set (match_operand:SI 3 "register_operand" "")
8492         (umod:SI (match_dup 1) (match_dup 2)))
8493    (clobber (reg:CC FLAGS_REG))]
8494   "reload_completed"
8495   [(set (match_dup 3) (const_int 0))
8496    (parallel [(set (match_dup 0)
8497                    (udiv:SI (match_dup 1) (match_dup 2)))
8498               (set (match_dup 3)
8499                    (umod:SI (match_dup 1) (match_dup 2)))
8500               (use (match_dup 3))
8501               (clobber (reg:CC FLAGS_REG))])]
8502   "")
8503
8504 (define_expand "udivmodhi4"
8505   [(set (match_dup 4) (const_int 0))
8506    (parallel [(set (match_operand:HI 0 "register_operand" "")
8507                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8508                             (match_operand:HI 2 "nonimmediate_operand" "")))
8509               (set (match_operand:HI 3 "register_operand" "")
8510                    (umod:HI (match_dup 1) (match_dup 2)))
8511               (use (match_dup 4))
8512               (clobber (reg:CC FLAGS_REG))])]
8513   "TARGET_HIMODE_MATH"
8514   "operands[4] = gen_reg_rtx (HImode);")
8515
8516 (define_insn "*udivmodhi_noext"
8517   [(set (match_operand:HI 0 "register_operand" "=a")
8518         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8519                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8520    (set (match_operand:HI 3 "register_operand" "=d")
8521         (umod:HI (match_dup 1) (match_dup 2)))
8522    (use (match_operand:HI 4 "register_operand" "3"))
8523    (clobber (reg:CC FLAGS_REG))]
8524   ""
8525   "div{w}\t%2"
8526   [(set_attr "type" "idiv")
8527    (set_attr "mode" "HI")])
8528
8529 ;; We cannot use div/idiv for double division, because it causes
8530 ;; "division by zero" on the overflow and that's not what we expect
8531 ;; from truncate.  Because true (non truncating) double division is
8532 ;; never generated, we can't create this insn anyway.
8533 ;
8534 ;(define_insn ""
8535 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8536 ;       (truncate:SI
8537 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8538 ;                  (zero_extend:DI
8539 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8540 ;   (set (match_operand:SI 3 "register_operand" "=d")
8541 ;       (truncate:SI
8542 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8543 ;   (clobber (reg:CC FLAGS_REG))]
8544 ;  ""
8545 ;  "div{l}\t{%2, %0|%0, %2}"
8546 ;  [(set_attr "type" "idiv")])
8547 \f
8548 ;;- Logical AND instructions
8549
8550 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8551 ;; Note that this excludes ah.
8552
8553 (define_insn "*testdi_1_rex64"
8554   [(set (reg FLAGS_REG)
8555         (compare
8556           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8557                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8558           (const_int 0)))]
8559   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8560    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8561   "@
8562    test{l}\t{%k1, %k0|%k0, %k1}
8563    test{l}\t{%k1, %k0|%k0, %k1}
8564    test{q}\t{%1, %0|%0, %1}
8565    test{q}\t{%1, %0|%0, %1}
8566    test{q}\t{%1, %0|%0, %1}"
8567   [(set_attr "type" "test")
8568    (set_attr "modrm" "0,1,0,1,1")
8569    (set_attr "mode" "SI,SI,DI,DI,DI")
8570    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8571
8572 (define_insn "testsi_1"
8573   [(set (reg FLAGS_REG)
8574         (compare
8575           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8576                   (match_operand:SI 1 "general_operand" "in,in,rin"))
8577           (const_int 0)))]
8578   "ix86_match_ccmode (insn, CCNOmode)
8579    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8580   "test{l}\t{%1, %0|%0, %1}"
8581   [(set_attr "type" "test")
8582    (set_attr "modrm" "0,1,1")
8583    (set_attr "mode" "SI")
8584    (set_attr "pent_pair" "uv,np,uv")])
8585
8586 (define_expand "testsi_ccno_1"
8587   [(set (reg:CCNO FLAGS_REG)
8588         (compare:CCNO
8589           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8590                   (match_operand:SI 1 "nonmemory_operand" ""))
8591           (const_int 0)))]
8592   ""
8593   "")
8594
8595 (define_insn "*testhi_1"
8596   [(set (reg FLAGS_REG)
8597         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8598                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8599                  (const_int 0)))]
8600   "ix86_match_ccmode (insn, CCNOmode)
8601    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8602   "test{w}\t{%1, %0|%0, %1}"
8603   [(set_attr "type" "test")
8604    (set_attr "modrm" "0,1,1")
8605    (set_attr "mode" "HI")
8606    (set_attr "pent_pair" "uv,np,uv")])
8607
8608 (define_expand "testqi_ccz_1"
8609   [(set (reg:CCZ FLAGS_REG)
8610         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8611                              (match_operand:QI 1 "nonmemory_operand" ""))
8612                  (const_int 0)))]
8613   ""
8614   "")
8615
8616 (define_insn "*testqi_1_maybe_si"
8617   [(set (reg FLAGS_REG)
8618         (compare
8619           (and:QI
8620             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8621             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8622           (const_int 0)))]
8623    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8624     && ix86_match_ccmode (insn,
8625                          CONST_INT_P (operands[1])
8626                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8627 {
8628   if (which_alternative == 3)
8629     {
8630       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8631         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8632       return "test{l}\t{%1, %k0|%k0, %1}";
8633     }
8634   return "test{b}\t{%1, %0|%0, %1}";
8635 }
8636   [(set_attr "type" "test")
8637    (set_attr "modrm" "0,1,1,1")
8638    (set_attr "mode" "QI,QI,QI,SI")
8639    (set_attr "pent_pair" "uv,np,uv,np")])
8640
8641 (define_insn "*testqi_1"
8642   [(set (reg FLAGS_REG)
8643         (compare
8644           (and:QI
8645             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8646             (match_operand:QI 1 "general_operand" "n,n,qn"))
8647           (const_int 0)))]
8648   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8649    && ix86_match_ccmode (insn, CCNOmode)"
8650   "test{b}\t{%1, %0|%0, %1}"
8651   [(set_attr "type" "test")
8652    (set_attr "modrm" "0,1,1")
8653    (set_attr "mode" "QI")
8654    (set_attr "pent_pair" "uv,np,uv")])
8655
8656 (define_expand "testqi_ext_ccno_0"
8657   [(set (reg:CCNO FLAGS_REG)
8658         (compare:CCNO
8659           (and:SI
8660             (zero_extract:SI
8661               (match_operand 0 "ext_register_operand" "")
8662               (const_int 8)
8663               (const_int 8))
8664             (match_operand 1 "const_int_operand" ""))
8665           (const_int 0)))]
8666   ""
8667   "")
8668
8669 (define_insn "*testqi_ext_0"
8670   [(set (reg FLAGS_REG)
8671         (compare
8672           (and:SI
8673             (zero_extract:SI
8674               (match_operand 0 "ext_register_operand" "Q")
8675               (const_int 8)
8676               (const_int 8))
8677             (match_operand 1 "const_int_operand" "n"))
8678           (const_int 0)))]
8679   "ix86_match_ccmode (insn, CCNOmode)"
8680   "test{b}\t{%1, %h0|%h0, %1}"
8681   [(set_attr "type" "test")
8682    (set_attr "mode" "QI")
8683    (set_attr "length_immediate" "1")
8684    (set_attr "pent_pair" "np")])
8685
8686 (define_insn "*testqi_ext_1"
8687   [(set (reg FLAGS_REG)
8688         (compare
8689           (and:SI
8690             (zero_extract:SI
8691               (match_operand 0 "ext_register_operand" "Q")
8692               (const_int 8)
8693               (const_int 8))
8694             (zero_extend:SI
8695               (match_operand:QI 1 "general_operand" "Qm")))
8696           (const_int 0)))]
8697   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8698    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8699   "test{b}\t{%1, %h0|%h0, %1}"
8700   [(set_attr "type" "test")
8701    (set_attr "mode" "QI")])
8702
8703 (define_insn "*testqi_ext_1_rex64"
8704   [(set (reg FLAGS_REG)
8705         (compare
8706           (and:SI
8707             (zero_extract:SI
8708               (match_operand 0 "ext_register_operand" "Q")
8709               (const_int 8)
8710               (const_int 8))
8711             (zero_extend:SI
8712               (match_operand:QI 1 "register_operand" "Q")))
8713           (const_int 0)))]
8714   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8715   "test{b}\t{%1, %h0|%h0, %1}"
8716   [(set_attr "type" "test")
8717    (set_attr "mode" "QI")])
8718
8719 (define_insn "*testqi_ext_2"
8720   [(set (reg FLAGS_REG)
8721         (compare
8722           (and:SI
8723             (zero_extract:SI
8724               (match_operand 0 "ext_register_operand" "Q")
8725               (const_int 8)
8726               (const_int 8))
8727             (zero_extract:SI
8728               (match_operand 1 "ext_register_operand" "Q")
8729               (const_int 8)
8730               (const_int 8)))
8731           (const_int 0)))]
8732   "ix86_match_ccmode (insn, CCNOmode)"
8733   "test{b}\t{%h1, %h0|%h0, %h1}"
8734   [(set_attr "type" "test")
8735    (set_attr "mode" "QI")])
8736
8737 ;; Combine likes to form bit extractions for some tests.  Humor it.
8738 (define_insn "*testqi_ext_3"
8739   [(set (reg FLAGS_REG)
8740         (compare (zero_extract:SI
8741                    (match_operand 0 "nonimmediate_operand" "rm")
8742                    (match_operand:SI 1 "const_int_operand" "")
8743                    (match_operand:SI 2 "const_int_operand" ""))
8744                  (const_int 0)))]
8745   "ix86_match_ccmode (insn, CCNOmode)
8746    && INTVAL (operands[1]) > 0
8747    && INTVAL (operands[2]) >= 0
8748    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8749    && (GET_MODE (operands[0]) == SImode
8750        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8751        || GET_MODE (operands[0]) == HImode
8752        || GET_MODE (operands[0]) == QImode)"
8753   "#")
8754
8755 (define_insn "*testqi_ext_3_rex64"
8756   [(set (reg FLAGS_REG)
8757         (compare (zero_extract:DI
8758                    (match_operand 0 "nonimmediate_operand" "rm")
8759                    (match_operand:DI 1 "const_int_operand" "")
8760                    (match_operand:DI 2 "const_int_operand" ""))
8761                  (const_int 0)))]
8762   "TARGET_64BIT
8763    && ix86_match_ccmode (insn, CCNOmode)
8764    && INTVAL (operands[1]) > 0
8765    && INTVAL (operands[2]) >= 0
8766    /* Ensure that resulting mask is zero or sign extended operand.  */
8767    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8768        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8769            && INTVAL (operands[1]) > 32))
8770    && (GET_MODE (operands[0]) == SImode
8771        || GET_MODE (operands[0]) == DImode
8772        || GET_MODE (operands[0]) == HImode
8773        || GET_MODE (operands[0]) == QImode)"
8774   "#")
8775
8776 (define_split
8777   [(set (match_operand 0 "flags_reg_operand" "")
8778         (match_operator 1 "compare_operator"
8779           [(zero_extract
8780              (match_operand 2 "nonimmediate_operand" "")
8781              (match_operand 3 "const_int_operand" "")
8782              (match_operand 4 "const_int_operand" ""))
8783            (const_int 0)]))]
8784   "ix86_match_ccmode (insn, CCNOmode)"
8785   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8786 {
8787   rtx val = operands[2];
8788   HOST_WIDE_INT len = INTVAL (operands[3]);
8789   HOST_WIDE_INT pos = INTVAL (operands[4]);
8790   HOST_WIDE_INT mask;
8791   enum machine_mode mode, submode;
8792
8793   mode = GET_MODE (val);
8794   if (MEM_P (val))
8795     {
8796       /* ??? Combine likes to put non-volatile mem extractions in QImode
8797          no matter the size of the test.  So find a mode that works.  */
8798       if (! MEM_VOLATILE_P (val))
8799         {
8800           mode = smallest_mode_for_size (pos + len, MODE_INT);
8801           val = adjust_address (val, mode, 0);
8802         }
8803     }
8804   else if (GET_CODE (val) == SUBREG
8805            && (submode = GET_MODE (SUBREG_REG (val)),
8806                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8807            && pos + len <= GET_MODE_BITSIZE (submode))
8808     {
8809       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8810       mode = submode;
8811       val = SUBREG_REG (val);
8812     }
8813   else if (mode == HImode && pos + len <= 8)
8814     {
8815       /* Small HImode tests can be converted to QImode.  */
8816       mode = QImode;
8817       val = gen_lowpart (QImode, val);
8818     }
8819
8820   if (len == HOST_BITS_PER_WIDE_INT)
8821     mask = -1;
8822   else
8823     mask = ((HOST_WIDE_INT)1 << len) - 1;
8824   mask <<= pos;
8825
8826   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8827 })
8828
8829 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8830 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8831 ;; this is relatively important trick.
8832 ;; Do the conversion only post-reload to avoid limiting of the register class
8833 ;; to QI regs.
8834 (define_split
8835   [(set (match_operand 0 "flags_reg_operand" "")
8836         (match_operator 1 "compare_operator"
8837           [(and (match_operand 2 "register_operand" "")
8838                 (match_operand 3 "const_int_operand" ""))
8839            (const_int 0)]))]
8840    "reload_completed
8841     && QI_REG_P (operands[2])
8842     && GET_MODE (operands[2]) != QImode
8843     && ((ix86_match_ccmode (insn, CCZmode)
8844          && !(INTVAL (operands[3]) & ~(255 << 8)))
8845         || (ix86_match_ccmode (insn, CCNOmode)
8846             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8847   [(set (match_dup 0)
8848         (match_op_dup 1
8849           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8850                    (match_dup 3))
8851            (const_int 0)]))]
8852   "operands[2] = gen_lowpart (SImode, operands[2]);
8853    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8854
8855 (define_split
8856   [(set (match_operand 0 "flags_reg_operand" "")
8857         (match_operator 1 "compare_operator"
8858           [(and (match_operand 2 "nonimmediate_operand" "")
8859                 (match_operand 3 "const_int_operand" ""))
8860            (const_int 0)]))]
8861    "reload_completed
8862     && GET_MODE (operands[2]) != QImode
8863     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8864     && ((ix86_match_ccmode (insn, CCZmode)
8865          && !(INTVAL (operands[3]) & ~255))
8866         || (ix86_match_ccmode (insn, CCNOmode)
8867             && !(INTVAL (operands[3]) & ~127)))"
8868   [(set (match_dup 0)
8869         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8870                          (const_int 0)]))]
8871   "operands[2] = gen_lowpart (QImode, operands[2]);
8872    operands[3] = gen_lowpart (QImode, operands[3]);")
8873
8874
8875 ;; %%% This used to optimize known byte-wide and operations to memory,
8876 ;; and sometimes to QImode registers.  If this is considered useful,
8877 ;; it should be done with splitters.
8878
8879 (define_expand "anddi3"
8880   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8881         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8882                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8883    (clobber (reg:CC FLAGS_REG))]
8884   "TARGET_64BIT"
8885   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8886
8887 (define_insn "*anddi_1_rex64"
8888   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8889         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8890                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8891    (clobber (reg:CC FLAGS_REG))]
8892   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8893 {
8894   switch (get_attr_type (insn))
8895     {
8896     case TYPE_IMOVX:
8897       {
8898         enum machine_mode mode;
8899
8900         gcc_assert (CONST_INT_P (operands[2]));
8901         if (INTVAL (operands[2]) == 0xff)
8902           mode = QImode;
8903         else
8904           {
8905             gcc_assert (INTVAL (operands[2]) == 0xffff);
8906             mode = HImode;
8907           }
8908
8909         operands[1] = gen_lowpart (mode, operands[1]);
8910         if (mode == QImode)
8911           return "movz{bq|x}\t{%1,%0|%0, %1}";
8912         else
8913           return "movz{wq|x}\t{%1,%0|%0, %1}";
8914       }
8915
8916     default:
8917       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8918       if (get_attr_mode (insn) == MODE_SI)
8919         return "and{l}\t{%k2, %k0|%k0, %k2}";
8920       else
8921         return "and{q}\t{%2, %0|%0, %2}";
8922     }
8923 }
8924   [(set_attr "type" "alu,alu,alu,imovx")
8925    (set_attr "length_immediate" "*,*,*,0")
8926    (set_attr "mode" "SI,DI,DI,DI")])
8927
8928 (define_insn "*anddi_2"
8929   [(set (reg FLAGS_REG)
8930         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8931                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8932                  (const_int 0)))
8933    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8934         (and:DI (match_dup 1) (match_dup 2)))]
8935   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8936    && ix86_binary_operator_ok (AND, DImode, operands)"
8937   "@
8938    and{l}\t{%k2, %k0|%k0, %k2}
8939    and{q}\t{%2, %0|%0, %2}
8940    and{q}\t{%2, %0|%0, %2}"
8941   [(set_attr "type" "alu")
8942    (set_attr "mode" "SI,DI,DI")])
8943
8944 (define_expand "andsi3"
8945   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8946         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8947                 (match_operand:SI 2 "general_operand" "")))
8948    (clobber (reg:CC FLAGS_REG))]
8949   ""
8950   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8951
8952 (define_insn "*andsi_1"
8953   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8954         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8955                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8956    (clobber (reg:CC FLAGS_REG))]
8957   "ix86_binary_operator_ok (AND, SImode, operands)"
8958 {
8959   switch (get_attr_type (insn))
8960     {
8961     case TYPE_IMOVX:
8962       {
8963         enum machine_mode mode;
8964
8965         gcc_assert (CONST_INT_P (operands[2]));
8966         if (INTVAL (operands[2]) == 0xff)
8967           mode = QImode;
8968         else
8969           {
8970             gcc_assert (INTVAL (operands[2]) == 0xffff);
8971             mode = HImode;
8972           }
8973
8974         operands[1] = gen_lowpart (mode, operands[1]);
8975         if (mode == QImode)
8976           return "movz{bl|x}\t{%1,%0|%0, %1}";
8977         else
8978           return "movz{wl|x}\t{%1,%0|%0, %1}";
8979       }
8980
8981     default:
8982       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8983       return "and{l}\t{%2, %0|%0, %2}";
8984     }
8985 }
8986   [(set_attr "type" "alu,alu,imovx")
8987    (set_attr "length_immediate" "*,*,0")
8988    (set_attr "mode" "SI")])
8989
8990 (define_split
8991   [(set (match_operand 0 "register_operand" "")
8992         (and (match_dup 0)
8993              (const_int -65536)))
8994    (clobber (reg:CC FLAGS_REG))]
8995   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8996   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8997   "operands[1] = gen_lowpart (HImode, operands[0]);")
8998
8999 (define_split
9000   [(set (match_operand 0 "ext_register_operand" "")
9001         (and (match_dup 0)
9002              (const_int -256)))
9003    (clobber (reg:CC FLAGS_REG))]
9004   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9005   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9006   "operands[1] = gen_lowpart (QImode, operands[0]);")
9007
9008 (define_split
9009   [(set (match_operand 0 "ext_register_operand" "")
9010         (and (match_dup 0)
9011              (const_int -65281)))
9012    (clobber (reg:CC FLAGS_REG))]
9013   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9014   [(parallel [(set (zero_extract:SI (match_dup 0)
9015                                     (const_int 8)
9016                                     (const_int 8))
9017                    (xor:SI
9018                      (zero_extract:SI (match_dup 0)
9019                                       (const_int 8)
9020                                       (const_int 8))
9021                      (zero_extract:SI (match_dup 0)
9022                                       (const_int 8)
9023                                       (const_int 8))))
9024               (clobber (reg:CC FLAGS_REG))])]
9025   "operands[0] = gen_lowpart (SImode, operands[0]);")
9026
9027 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9028 (define_insn "*andsi_1_zext"
9029   [(set (match_operand:DI 0 "register_operand" "=r")
9030         (zero_extend:DI
9031           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9032                   (match_operand:SI 2 "general_operand" "g"))))
9033    (clobber (reg:CC FLAGS_REG))]
9034   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9035   "and{l}\t{%2, %k0|%k0, %2}"
9036   [(set_attr "type" "alu")
9037    (set_attr "mode" "SI")])
9038
9039 (define_insn "*andsi_2"
9040   [(set (reg FLAGS_REG)
9041         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9042                          (match_operand:SI 2 "general_operand" "g,ri"))
9043                  (const_int 0)))
9044    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9045         (and:SI (match_dup 1) (match_dup 2)))]
9046   "ix86_match_ccmode (insn, CCNOmode)
9047    && ix86_binary_operator_ok (AND, SImode, operands)"
9048   "and{l}\t{%2, %0|%0, %2}"
9049   [(set_attr "type" "alu")
9050    (set_attr "mode" "SI")])
9051
9052 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9053 (define_insn "*andsi_2_zext"
9054   [(set (reg FLAGS_REG)
9055         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9056                          (match_operand:SI 2 "general_operand" "g"))
9057                  (const_int 0)))
9058    (set (match_operand:DI 0 "register_operand" "=r")
9059         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9060   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9061    && ix86_binary_operator_ok (AND, SImode, operands)"
9062   "and{l}\t{%2, %k0|%k0, %2}"
9063   [(set_attr "type" "alu")
9064    (set_attr "mode" "SI")])
9065
9066 (define_expand "andhi3"
9067   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9068         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9069                 (match_operand:HI 2 "general_operand" "")))
9070    (clobber (reg:CC FLAGS_REG))]
9071   "TARGET_HIMODE_MATH"
9072   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9073
9074 (define_insn "*andhi_1"
9075   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9076         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9077                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
9078    (clobber (reg:CC FLAGS_REG))]
9079   "ix86_binary_operator_ok (AND, HImode, operands)"
9080 {
9081   switch (get_attr_type (insn))
9082     {
9083     case TYPE_IMOVX:
9084       gcc_assert (CONST_INT_P (operands[2]));
9085       gcc_assert (INTVAL (operands[2]) == 0xff);
9086       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9087
9088     default:
9089       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9090
9091       return "and{w}\t{%2, %0|%0, %2}";
9092     }
9093 }
9094   [(set_attr "type" "alu,alu,imovx")
9095    (set_attr "length_immediate" "*,*,0")
9096    (set_attr "mode" "HI,HI,SI")])
9097
9098 (define_insn "*andhi_2"
9099   [(set (reg FLAGS_REG)
9100         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9101                          (match_operand:HI 2 "general_operand" "g,ri"))
9102                  (const_int 0)))
9103    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9104         (and:HI (match_dup 1) (match_dup 2)))]
9105   "ix86_match_ccmode (insn, CCNOmode)
9106    && ix86_binary_operator_ok (AND, HImode, operands)"
9107   "and{w}\t{%2, %0|%0, %2}"
9108   [(set_attr "type" "alu")
9109    (set_attr "mode" "HI")])
9110
9111 (define_expand "andqi3"
9112   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9113         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9114                 (match_operand:QI 2 "general_operand" "")))
9115    (clobber (reg:CC FLAGS_REG))]
9116   "TARGET_QIMODE_MATH"
9117   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9118
9119 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9120 (define_insn "*andqi_1"
9121   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9122         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9123                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
9124    (clobber (reg:CC FLAGS_REG))]
9125   "ix86_binary_operator_ok (AND, QImode, operands)"
9126   "@
9127    and{b}\t{%2, %0|%0, %2}
9128    and{b}\t{%2, %0|%0, %2}
9129    and{l}\t{%k2, %k0|%k0, %k2}"
9130   [(set_attr "type" "alu")
9131    (set_attr "mode" "QI,QI,SI")])
9132
9133 (define_insn "*andqi_1_slp"
9134   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9135         (and:QI (match_dup 0)
9136                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9137    (clobber (reg:CC FLAGS_REG))]
9138   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9139    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9140   "and{b}\t{%1, %0|%0, %1}"
9141   [(set_attr "type" "alu1")
9142    (set_attr "mode" "QI")])
9143
9144 (define_insn "*andqi_2_maybe_si"
9145   [(set (reg FLAGS_REG)
9146         (compare (and:QI
9147                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9148                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
9149                  (const_int 0)))
9150    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9151         (and:QI (match_dup 1) (match_dup 2)))]
9152   "ix86_binary_operator_ok (AND, QImode, operands)
9153    && ix86_match_ccmode (insn,
9154                          CONST_INT_P (operands[2])
9155                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9156 {
9157   if (which_alternative == 2)
9158     {
9159       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9160         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9161       return "and{l}\t{%2, %k0|%k0, %2}";
9162     }
9163   return "and{b}\t{%2, %0|%0, %2}";
9164 }
9165   [(set_attr "type" "alu")
9166    (set_attr "mode" "QI,QI,SI")])
9167
9168 (define_insn "*andqi_2"
9169   [(set (reg FLAGS_REG)
9170         (compare (and:QI
9171                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9172                    (match_operand:QI 2 "general_operand" "qim,qi"))
9173                  (const_int 0)))
9174    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9175         (and:QI (match_dup 1) (match_dup 2)))]
9176   "ix86_match_ccmode (insn, CCNOmode)
9177    && ix86_binary_operator_ok (AND, QImode, operands)"
9178   "and{b}\t{%2, %0|%0, %2}"
9179   [(set_attr "type" "alu")
9180    (set_attr "mode" "QI")])
9181
9182 (define_insn "*andqi_2_slp"
9183   [(set (reg FLAGS_REG)
9184         (compare (and:QI
9185                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9186                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
9187                  (const_int 0)))
9188    (set (strict_low_part (match_dup 0))
9189         (and:QI (match_dup 0) (match_dup 1)))]
9190   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9191    && ix86_match_ccmode (insn, CCNOmode)
9192    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9193   "and{b}\t{%1, %0|%0, %1}"
9194   [(set_attr "type" "alu1")
9195    (set_attr "mode" "QI")])
9196
9197 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9198 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
9199 ;; for a QImode operand, which of course failed.
9200
9201 (define_insn "andqi_ext_0"
9202   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9203                          (const_int 8)
9204                          (const_int 8))
9205         (and:SI
9206           (zero_extract:SI
9207             (match_operand 1 "ext_register_operand" "0")
9208             (const_int 8)
9209             (const_int 8))
9210           (match_operand 2 "const_int_operand" "n")))
9211    (clobber (reg:CC FLAGS_REG))]
9212   ""
9213   "and{b}\t{%2, %h0|%h0, %2}"
9214   [(set_attr "type" "alu")
9215    (set_attr "length_immediate" "1")
9216    (set_attr "mode" "QI")])
9217
9218 ;; Generated by peephole translating test to and.  This shows up
9219 ;; often in fp comparisons.
9220
9221 (define_insn "*andqi_ext_0_cc"
9222   [(set (reg FLAGS_REG)
9223         (compare
9224           (and:SI
9225             (zero_extract:SI
9226               (match_operand 1 "ext_register_operand" "0")
9227               (const_int 8)
9228               (const_int 8))
9229             (match_operand 2 "const_int_operand" "n"))
9230           (const_int 0)))
9231    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9232                          (const_int 8)
9233                          (const_int 8))
9234         (and:SI
9235           (zero_extract:SI
9236             (match_dup 1)
9237             (const_int 8)
9238             (const_int 8))
9239           (match_dup 2)))]
9240   "ix86_match_ccmode (insn, CCNOmode)"
9241   "and{b}\t{%2, %h0|%h0, %2}"
9242   [(set_attr "type" "alu")
9243    (set_attr "length_immediate" "1")
9244    (set_attr "mode" "QI")])
9245
9246 (define_insn "*andqi_ext_1"
9247   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9248                          (const_int 8)
9249                          (const_int 8))
9250         (and:SI
9251           (zero_extract:SI
9252             (match_operand 1 "ext_register_operand" "0")
9253             (const_int 8)
9254             (const_int 8))
9255           (zero_extend:SI
9256             (match_operand:QI 2 "general_operand" "Qm"))))
9257    (clobber (reg:CC FLAGS_REG))]
9258   "!TARGET_64BIT"
9259   "and{b}\t{%2, %h0|%h0, %2}"
9260   [(set_attr "type" "alu")
9261    (set_attr "length_immediate" "0")
9262    (set_attr "mode" "QI")])
9263
9264 (define_insn "*andqi_ext_1_rex64"
9265   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9266                          (const_int 8)
9267                          (const_int 8))
9268         (and:SI
9269           (zero_extract:SI
9270             (match_operand 1 "ext_register_operand" "0")
9271             (const_int 8)
9272             (const_int 8))
9273           (zero_extend:SI
9274             (match_operand 2 "ext_register_operand" "Q"))))
9275    (clobber (reg:CC FLAGS_REG))]
9276   "TARGET_64BIT"
9277   "and{b}\t{%2, %h0|%h0, %2}"
9278   [(set_attr "type" "alu")
9279    (set_attr "length_immediate" "0")
9280    (set_attr "mode" "QI")])
9281
9282 (define_insn "*andqi_ext_2"
9283   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9284                          (const_int 8)
9285                          (const_int 8))
9286         (and:SI
9287           (zero_extract:SI
9288             (match_operand 1 "ext_register_operand" "%0")
9289             (const_int 8)
9290             (const_int 8))
9291           (zero_extract:SI
9292             (match_operand 2 "ext_register_operand" "Q")
9293             (const_int 8)
9294             (const_int 8))))
9295    (clobber (reg:CC FLAGS_REG))]
9296   ""
9297   "and{b}\t{%h2, %h0|%h0, %h2}"
9298   [(set_attr "type" "alu")
9299    (set_attr "length_immediate" "0")
9300    (set_attr "mode" "QI")])
9301
9302 ;; Convert wide AND instructions with immediate operand to shorter QImode
9303 ;; equivalents when possible.
9304 ;; Don't do the splitting with memory operands, since it introduces risk
9305 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9306 ;; for size, but that can (should?) be handled by generic code instead.
9307 (define_split
9308   [(set (match_operand 0 "register_operand" "")
9309         (and (match_operand 1 "register_operand" "")
9310              (match_operand 2 "const_int_operand" "")))
9311    (clobber (reg:CC FLAGS_REG))]
9312    "reload_completed
9313     && QI_REG_P (operands[0])
9314     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9315     && !(~INTVAL (operands[2]) & ~(255 << 8))
9316     && GET_MODE (operands[0]) != QImode"
9317   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9318                    (and:SI (zero_extract:SI (match_dup 1)
9319                                             (const_int 8) (const_int 8))
9320                            (match_dup 2)))
9321               (clobber (reg:CC FLAGS_REG))])]
9322   "operands[0] = gen_lowpart (SImode, operands[0]);
9323    operands[1] = gen_lowpart (SImode, operands[1]);
9324    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9325
9326 ;; Since AND can be encoded with sign extended immediate, this is only
9327 ;; profitable when 7th bit is not set.
9328 (define_split
9329   [(set (match_operand 0 "register_operand" "")
9330         (and (match_operand 1 "general_operand" "")
9331              (match_operand 2 "const_int_operand" "")))
9332    (clobber (reg:CC FLAGS_REG))]
9333    "reload_completed
9334     && ANY_QI_REG_P (operands[0])
9335     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9336     && !(~INTVAL (operands[2]) & ~255)
9337     && !(INTVAL (operands[2]) & 128)
9338     && GET_MODE (operands[0]) != QImode"
9339   [(parallel [(set (strict_low_part (match_dup 0))
9340                    (and:QI (match_dup 1)
9341                            (match_dup 2)))
9342               (clobber (reg:CC FLAGS_REG))])]
9343   "operands[0] = gen_lowpart (QImode, operands[0]);
9344    operands[1] = gen_lowpart (QImode, operands[1]);
9345    operands[2] = gen_lowpart (QImode, operands[2]);")
9346 \f
9347 ;; Logical inclusive OR instructions
9348
9349 ;; %%% This used to optimize known byte-wide and operations to memory.
9350 ;; If this is considered useful, it should be done with splitters.
9351
9352 (define_expand "iordi3"
9353   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9354         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9355                 (match_operand:DI 2 "x86_64_general_operand" "")))
9356    (clobber (reg:CC FLAGS_REG))]
9357   "TARGET_64BIT"
9358   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9359
9360 (define_insn "*iordi_1_rex64"
9361   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9362         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9363                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9364    (clobber (reg:CC FLAGS_REG))]
9365   "TARGET_64BIT
9366    && ix86_binary_operator_ok (IOR, DImode, operands)"
9367   "or{q}\t{%2, %0|%0, %2}"
9368   [(set_attr "type" "alu")
9369    (set_attr "mode" "DI")])
9370
9371 (define_insn "*iordi_2_rex64"
9372   [(set (reg FLAGS_REG)
9373         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9374                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9375                  (const_int 0)))
9376    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9377         (ior:DI (match_dup 1) (match_dup 2)))]
9378   "TARGET_64BIT
9379    && ix86_match_ccmode (insn, CCNOmode)
9380    && ix86_binary_operator_ok (IOR, DImode, operands)"
9381   "or{q}\t{%2, %0|%0, %2}"
9382   [(set_attr "type" "alu")
9383    (set_attr "mode" "DI")])
9384
9385 (define_insn "*iordi_3_rex64"
9386   [(set (reg FLAGS_REG)
9387         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9388                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9389                  (const_int 0)))
9390    (clobber (match_scratch:DI 0 "=r"))]
9391   "TARGET_64BIT
9392    && ix86_match_ccmode (insn, CCNOmode)
9393    && ix86_binary_operator_ok (IOR, DImode, operands)"
9394   "or{q}\t{%2, %0|%0, %2}"
9395   [(set_attr "type" "alu")
9396    (set_attr "mode" "DI")])
9397
9398
9399 (define_expand "iorsi3"
9400   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9401         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9402                 (match_operand:SI 2 "general_operand" "")))
9403    (clobber (reg:CC FLAGS_REG))]
9404   ""
9405   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9406
9407 (define_insn "*iorsi_1"
9408   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9409         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9410                 (match_operand:SI 2 "general_operand" "ri,g")))
9411    (clobber (reg:CC FLAGS_REG))]
9412   "ix86_binary_operator_ok (IOR, SImode, operands)"
9413   "or{l}\t{%2, %0|%0, %2}"
9414   [(set_attr "type" "alu")
9415    (set_attr "mode" "SI")])
9416
9417 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9418 (define_insn "*iorsi_1_zext"
9419   [(set (match_operand:DI 0 "register_operand" "=r")
9420         (zero_extend:DI
9421           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9422                   (match_operand:SI 2 "general_operand" "g"))))
9423    (clobber (reg:CC FLAGS_REG))]
9424   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9425   "or{l}\t{%2, %k0|%k0, %2}"
9426   [(set_attr "type" "alu")
9427    (set_attr "mode" "SI")])
9428
9429 (define_insn "*iorsi_1_zext_imm"
9430   [(set (match_operand:DI 0 "register_operand" "=r")
9431         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9432                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9433    (clobber (reg:CC FLAGS_REG))]
9434   "TARGET_64BIT"
9435   "or{l}\t{%2, %k0|%k0, %2}"
9436   [(set_attr "type" "alu")
9437    (set_attr "mode" "SI")])
9438
9439 (define_insn "*iorsi_2"
9440   [(set (reg FLAGS_REG)
9441         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9442                          (match_operand:SI 2 "general_operand" "g,ri"))
9443                  (const_int 0)))
9444    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9445         (ior:SI (match_dup 1) (match_dup 2)))]
9446   "ix86_match_ccmode (insn, CCNOmode)
9447    && ix86_binary_operator_ok (IOR, SImode, operands)"
9448   "or{l}\t{%2, %0|%0, %2}"
9449   [(set_attr "type" "alu")
9450    (set_attr "mode" "SI")])
9451
9452 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9453 ;; ??? Special case for immediate operand is missing - it is tricky.
9454 (define_insn "*iorsi_2_zext"
9455   [(set (reg FLAGS_REG)
9456         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9457                          (match_operand:SI 2 "general_operand" "g"))
9458                  (const_int 0)))
9459    (set (match_operand:DI 0 "register_operand" "=r")
9460         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9461   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9462    && ix86_binary_operator_ok (IOR, SImode, operands)"
9463   "or{l}\t{%2, %k0|%k0, %2}"
9464   [(set_attr "type" "alu")
9465    (set_attr "mode" "SI")])
9466
9467 (define_insn "*iorsi_2_zext_imm"
9468   [(set (reg FLAGS_REG)
9469         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9470                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9471                  (const_int 0)))
9472    (set (match_operand:DI 0 "register_operand" "=r")
9473         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9474   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9475    && ix86_binary_operator_ok (IOR, SImode, operands)"
9476   "or{l}\t{%2, %k0|%k0, %2}"
9477   [(set_attr "type" "alu")
9478    (set_attr "mode" "SI")])
9479
9480 (define_insn "*iorsi_3"
9481   [(set (reg FLAGS_REG)
9482         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9483                          (match_operand:SI 2 "general_operand" "g"))
9484                  (const_int 0)))
9485    (clobber (match_scratch:SI 0 "=r"))]
9486   "ix86_match_ccmode (insn, CCNOmode)
9487    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9488   "or{l}\t{%2, %0|%0, %2}"
9489   [(set_attr "type" "alu")
9490    (set_attr "mode" "SI")])
9491
9492 (define_expand "iorhi3"
9493   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9494         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9495                 (match_operand:HI 2 "general_operand" "")))
9496    (clobber (reg:CC FLAGS_REG))]
9497   "TARGET_HIMODE_MATH"
9498   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9499
9500 (define_insn "*iorhi_1"
9501   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9502         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9503                 (match_operand:HI 2 "general_operand" "g,ri")))
9504    (clobber (reg:CC FLAGS_REG))]
9505   "ix86_binary_operator_ok (IOR, HImode, operands)"
9506   "or{w}\t{%2, %0|%0, %2}"
9507   [(set_attr "type" "alu")
9508    (set_attr "mode" "HI")])
9509
9510 (define_insn "*iorhi_2"
9511   [(set (reg FLAGS_REG)
9512         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9513                          (match_operand:HI 2 "general_operand" "g,ri"))
9514                  (const_int 0)))
9515    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9516         (ior:HI (match_dup 1) (match_dup 2)))]
9517   "ix86_match_ccmode (insn, CCNOmode)
9518    && ix86_binary_operator_ok (IOR, HImode, operands)"
9519   "or{w}\t{%2, %0|%0, %2}"
9520   [(set_attr "type" "alu")
9521    (set_attr "mode" "HI")])
9522
9523 (define_insn "*iorhi_3"
9524   [(set (reg FLAGS_REG)
9525         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9526                          (match_operand:HI 2 "general_operand" "g"))
9527                  (const_int 0)))
9528    (clobber (match_scratch:HI 0 "=r"))]
9529   "ix86_match_ccmode (insn, CCNOmode)
9530    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9531   "or{w}\t{%2, %0|%0, %2}"
9532   [(set_attr "type" "alu")
9533    (set_attr "mode" "HI")])
9534
9535 (define_expand "iorqi3"
9536   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9537         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9538                 (match_operand:QI 2 "general_operand" "")))
9539    (clobber (reg:CC FLAGS_REG))]
9540   "TARGET_QIMODE_MATH"
9541   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9542
9543 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9544 (define_insn "*iorqi_1"
9545   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9546         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9547                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9548    (clobber (reg:CC FLAGS_REG))]
9549   "ix86_binary_operator_ok (IOR, QImode, operands)"
9550   "@
9551    or{b}\t{%2, %0|%0, %2}
9552    or{b}\t{%2, %0|%0, %2}
9553    or{l}\t{%k2, %k0|%k0, %k2}"
9554   [(set_attr "type" "alu")
9555    (set_attr "mode" "QI,QI,SI")])
9556
9557 (define_insn "*iorqi_1_slp"
9558   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9559         (ior:QI (match_dup 0)
9560                 (match_operand:QI 1 "general_operand" "qmi,qi")))
9561    (clobber (reg:CC FLAGS_REG))]
9562   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9563    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9564   "or{b}\t{%1, %0|%0, %1}"
9565   [(set_attr "type" "alu1")
9566    (set_attr "mode" "QI")])
9567
9568 (define_insn "*iorqi_2"
9569   [(set (reg FLAGS_REG)
9570         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9571                          (match_operand:QI 2 "general_operand" "qim,qi"))
9572                  (const_int 0)))
9573    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9574         (ior:QI (match_dup 1) (match_dup 2)))]
9575   "ix86_match_ccmode (insn, CCNOmode)
9576    && ix86_binary_operator_ok (IOR, QImode, operands)"
9577   "or{b}\t{%2, %0|%0, %2}"
9578   [(set_attr "type" "alu")
9579    (set_attr "mode" "QI")])
9580
9581 (define_insn "*iorqi_2_slp"
9582   [(set (reg FLAGS_REG)
9583         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9584                          (match_operand:QI 1 "general_operand" "qim,qi"))
9585                  (const_int 0)))
9586    (set (strict_low_part (match_dup 0))
9587         (ior:QI (match_dup 0) (match_dup 1)))]
9588   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9589    && ix86_match_ccmode (insn, CCNOmode)
9590    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9591   "or{b}\t{%1, %0|%0, %1}"
9592   [(set_attr "type" "alu1")
9593    (set_attr "mode" "QI")])
9594
9595 (define_insn "*iorqi_3"
9596   [(set (reg FLAGS_REG)
9597         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9598                          (match_operand:QI 2 "general_operand" "qim"))
9599                  (const_int 0)))
9600    (clobber (match_scratch:QI 0 "=q"))]
9601   "ix86_match_ccmode (insn, CCNOmode)
9602    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9603   "or{b}\t{%2, %0|%0, %2}"
9604   [(set_attr "type" "alu")
9605    (set_attr "mode" "QI")])
9606
9607 (define_insn "iorqi_ext_0"
9608   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9609                          (const_int 8)
9610                          (const_int 8))
9611         (ior:SI
9612           (zero_extract:SI
9613             (match_operand 1 "ext_register_operand" "0")
9614             (const_int 8)
9615             (const_int 8))
9616           (match_operand 2 "const_int_operand" "n")))
9617    (clobber (reg:CC FLAGS_REG))]
9618   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9619   "or{b}\t{%2, %h0|%h0, %2}"
9620   [(set_attr "type" "alu")
9621    (set_attr "length_immediate" "1")
9622    (set_attr "mode" "QI")])
9623
9624 (define_insn "*iorqi_ext_1"
9625   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9626                          (const_int 8)
9627                          (const_int 8))
9628         (ior:SI
9629           (zero_extract:SI
9630             (match_operand 1 "ext_register_operand" "0")
9631             (const_int 8)
9632             (const_int 8))
9633           (zero_extend:SI
9634             (match_operand:QI 2 "general_operand" "Qm"))))
9635    (clobber (reg:CC FLAGS_REG))]
9636   "!TARGET_64BIT
9637    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9638   "or{b}\t{%2, %h0|%h0, %2}"
9639   [(set_attr "type" "alu")
9640    (set_attr "length_immediate" "0")
9641    (set_attr "mode" "QI")])
9642
9643 (define_insn "*iorqi_ext_1_rex64"
9644   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9645                          (const_int 8)
9646                          (const_int 8))
9647         (ior:SI
9648           (zero_extract:SI
9649             (match_operand 1 "ext_register_operand" "0")
9650             (const_int 8)
9651             (const_int 8))
9652           (zero_extend:SI
9653             (match_operand 2 "ext_register_operand" "Q"))))
9654    (clobber (reg:CC FLAGS_REG))]
9655   "TARGET_64BIT
9656    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9657   "or{b}\t{%2, %h0|%h0, %2}"
9658   [(set_attr "type" "alu")
9659    (set_attr "length_immediate" "0")
9660    (set_attr "mode" "QI")])
9661
9662 (define_insn "*iorqi_ext_2"
9663   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9664                          (const_int 8)
9665                          (const_int 8))
9666         (ior:SI
9667           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9668                            (const_int 8)
9669                            (const_int 8))
9670           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9671                            (const_int 8)
9672                            (const_int 8))))
9673    (clobber (reg:CC FLAGS_REG))]
9674   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9675   "ior{b}\t{%h2, %h0|%h0, %h2}"
9676   [(set_attr "type" "alu")
9677    (set_attr "length_immediate" "0")
9678    (set_attr "mode" "QI")])
9679
9680 (define_split
9681   [(set (match_operand 0 "register_operand" "")
9682         (ior (match_operand 1 "register_operand" "")
9683              (match_operand 2 "const_int_operand" "")))
9684    (clobber (reg:CC FLAGS_REG))]
9685    "reload_completed
9686     && QI_REG_P (operands[0])
9687     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9688     && !(INTVAL (operands[2]) & ~(255 << 8))
9689     && GET_MODE (operands[0]) != QImode"
9690   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9691                    (ior:SI (zero_extract:SI (match_dup 1)
9692                                             (const_int 8) (const_int 8))
9693                            (match_dup 2)))
9694               (clobber (reg:CC FLAGS_REG))])]
9695   "operands[0] = gen_lowpart (SImode, operands[0]);
9696    operands[1] = gen_lowpart (SImode, operands[1]);
9697    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9698
9699 ;; Since OR can be encoded with sign extended immediate, this is only
9700 ;; profitable when 7th bit is set.
9701 (define_split
9702   [(set (match_operand 0 "register_operand" "")
9703         (ior (match_operand 1 "general_operand" "")
9704              (match_operand 2 "const_int_operand" "")))
9705    (clobber (reg:CC FLAGS_REG))]
9706    "reload_completed
9707     && ANY_QI_REG_P (operands[0])
9708     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9709     && !(INTVAL (operands[2]) & ~255)
9710     && (INTVAL (operands[2]) & 128)
9711     && GET_MODE (operands[0]) != QImode"
9712   [(parallel [(set (strict_low_part (match_dup 0))
9713                    (ior:QI (match_dup 1)
9714                            (match_dup 2)))
9715               (clobber (reg:CC FLAGS_REG))])]
9716   "operands[0] = gen_lowpart (QImode, operands[0]);
9717    operands[1] = gen_lowpart (QImode, operands[1]);
9718    operands[2] = gen_lowpart (QImode, operands[2]);")
9719 \f
9720 ;; Logical XOR instructions
9721
9722 ;; %%% This used to optimize known byte-wide and operations to memory.
9723 ;; If this is considered useful, it should be done with splitters.
9724
9725 (define_expand "xordi3"
9726   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9727         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9728                 (match_operand:DI 2 "x86_64_general_operand" "")))
9729    (clobber (reg:CC FLAGS_REG))]
9730   "TARGET_64BIT"
9731   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9732
9733 (define_insn "*xordi_1_rex64"
9734   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9735         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9736                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9737    (clobber (reg:CC FLAGS_REG))]
9738   "TARGET_64BIT
9739    && ix86_binary_operator_ok (XOR, DImode, operands)"
9740   "xor{q}\t{%2, %0|%0, %2}"
9741   [(set_attr "type" "alu")
9742    (set_attr "mode" "DI")])
9743
9744 (define_insn "*xordi_2_rex64"
9745   [(set (reg FLAGS_REG)
9746         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9747                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9748                  (const_int 0)))
9749    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9750         (xor:DI (match_dup 1) (match_dup 2)))]
9751   "TARGET_64BIT
9752    && ix86_match_ccmode (insn, CCNOmode)
9753    && ix86_binary_operator_ok (XOR, DImode, operands)"
9754   "xor{q}\t{%2, %0|%0, %2}"
9755   [(set_attr "type" "alu")
9756    (set_attr "mode" "DI")])
9757
9758 (define_insn "*xordi_3_rex64"
9759   [(set (reg FLAGS_REG)
9760         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9761                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9762                  (const_int 0)))
9763    (clobber (match_scratch:DI 0 "=r"))]
9764   "TARGET_64BIT
9765    && ix86_match_ccmode (insn, CCNOmode)
9766    && ix86_binary_operator_ok (XOR, DImode, operands)"
9767   "xor{q}\t{%2, %0|%0, %2}"
9768   [(set_attr "type" "alu")
9769    (set_attr "mode" "DI")])
9770
9771 (define_expand "xorsi3"
9772   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9773         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9774                 (match_operand:SI 2 "general_operand" "")))
9775    (clobber (reg:CC FLAGS_REG))]
9776   ""
9777   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9778
9779 (define_insn "*xorsi_1"
9780   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9781         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9782                 (match_operand:SI 2 "general_operand" "ri,rm")))
9783    (clobber (reg:CC FLAGS_REG))]
9784   "ix86_binary_operator_ok (XOR, SImode, operands)"
9785   "xor{l}\t{%2, %0|%0, %2}"
9786   [(set_attr "type" "alu")
9787    (set_attr "mode" "SI")])
9788
9789 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9790 ;; Add speccase for immediates
9791 (define_insn "*xorsi_1_zext"
9792   [(set (match_operand:DI 0 "register_operand" "=r")
9793         (zero_extend:DI
9794           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9795                   (match_operand:SI 2 "general_operand" "g"))))
9796    (clobber (reg:CC FLAGS_REG))]
9797   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9798   "xor{l}\t{%2, %k0|%k0, %2}"
9799   [(set_attr "type" "alu")
9800    (set_attr "mode" "SI")])
9801
9802 (define_insn "*xorsi_1_zext_imm"
9803   [(set (match_operand:DI 0 "register_operand" "=r")
9804         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9805                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9806    (clobber (reg:CC FLAGS_REG))]
9807   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9808   "xor{l}\t{%2, %k0|%k0, %2}"
9809   [(set_attr "type" "alu")
9810    (set_attr "mode" "SI")])
9811
9812 (define_insn "*xorsi_2"
9813   [(set (reg FLAGS_REG)
9814         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9815                          (match_operand:SI 2 "general_operand" "g,ri"))
9816                  (const_int 0)))
9817    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9818         (xor:SI (match_dup 1) (match_dup 2)))]
9819   "ix86_match_ccmode (insn, CCNOmode)
9820    && ix86_binary_operator_ok (XOR, SImode, operands)"
9821   "xor{l}\t{%2, %0|%0, %2}"
9822   [(set_attr "type" "alu")
9823    (set_attr "mode" "SI")])
9824
9825 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9826 ;; ??? Special case for immediate operand is missing - it is tricky.
9827 (define_insn "*xorsi_2_zext"
9828   [(set (reg FLAGS_REG)
9829         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9830                          (match_operand:SI 2 "general_operand" "g"))
9831                  (const_int 0)))
9832    (set (match_operand:DI 0 "register_operand" "=r")
9833         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9834   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9835    && ix86_binary_operator_ok (XOR, SImode, operands)"
9836   "xor{l}\t{%2, %k0|%k0, %2}"
9837   [(set_attr "type" "alu")
9838    (set_attr "mode" "SI")])
9839
9840 (define_insn "*xorsi_2_zext_imm"
9841   [(set (reg FLAGS_REG)
9842         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9843                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9844                  (const_int 0)))
9845    (set (match_operand:DI 0 "register_operand" "=r")
9846         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9847   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9848    && ix86_binary_operator_ok (XOR, SImode, operands)"
9849   "xor{l}\t{%2, %k0|%k0, %2}"
9850   [(set_attr "type" "alu")
9851    (set_attr "mode" "SI")])
9852
9853 (define_insn "*xorsi_3"
9854   [(set (reg FLAGS_REG)
9855         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9856                          (match_operand:SI 2 "general_operand" "g"))
9857                  (const_int 0)))
9858    (clobber (match_scratch:SI 0 "=r"))]
9859   "ix86_match_ccmode (insn, CCNOmode)
9860    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9861   "xor{l}\t{%2, %0|%0, %2}"
9862   [(set_attr "type" "alu")
9863    (set_attr "mode" "SI")])
9864
9865 (define_expand "xorhi3"
9866   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9867         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9868                 (match_operand:HI 2 "general_operand" "")))
9869    (clobber (reg:CC FLAGS_REG))]
9870   "TARGET_HIMODE_MATH"
9871   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9872
9873 (define_insn "*xorhi_1"
9874   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9875         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9876                 (match_operand:HI 2 "general_operand" "g,ri")))
9877    (clobber (reg:CC FLAGS_REG))]
9878   "ix86_binary_operator_ok (XOR, HImode, operands)"
9879   "xor{w}\t{%2, %0|%0, %2}"
9880   [(set_attr "type" "alu")
9881    (set_attr "mode" "HI")])
9882
9883 (define_insn "*xorhi_2"
9884   [(set (reg FLAGS_REG)
9885         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9886                          (match_operand:HI 2 "general_operand" "g,ri"))
9887                  (const_int 0)))
9888    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9889         (xor:HI (match_dup 1) (match_dup 2)))]
9890   "ix86_match_ccmode (insn, CCNOmode)
9891    && ix86_binary_operator_ok (XOR, HImode, operands)"
9892   "xor{w}\t{%2, %0|%0, %2}"
9893   [(set_attr "type" "alu")
9894    (set_attr "mode" "HI")])
9895
9896 (define_insn "*xorhi_3"
9897   [(set (reg FLAGS_REG)
9898         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9899                          (match_operand:HI 2 "general_operand" "g"))
9900                  (const_int 0)))
9901    (clobber (match_scratch:HI 0 "=r"))]
9902   "ix86_match_ccmode (insn, CCNOmode)
9903    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9904   "xor{w}\t{%2, %0|%0, %2}"
9905   [(set_attr "type" "alu")
9906    (set_attr "mode" "HI")])
9907
9908 (define_expand "xorqi3"
9909   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9910         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9911                 (match_operand:QI 2 "general_operand" "")))
9912    (clobber (reg:CC FLAGS_REG))]
9913   "TARGET_QIMODE_MATH"
9914   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9915
9916 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9917 (define_insn "*xorqi_1"
9918   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9919         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9920                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9921    (clobber (reg:CC FLAGS_REG))]
9922   "ix86_binary_operator_ok (XOR, QImode, operands)"
9923   "@
9924    xor{b}\t{%2, %0|%0, %2}
9925    xor{b}\t{%2, %0|%0, %2}
9926    xor{l}\t{%k2, %k0|%k0, %k2}"
9927   [(set_attr "type" "alu")
9928    (set_attr "mode" "QI,QI,SI")])
9929
9930 (define_insn "*xorqi_1_slp"
9931   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9932         (xor:QI (match_dup 0)
9933                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9934    (clobber (reg:CC FLAGS_REG))]
9935   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9936    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9937   "xor{b}\t{%1, %0|%0, %1}"
9938   [(set_attr "type" "alu1")
9939    (set_attr "mode" "QI")])
9940
9941 (define_insn "xorqi_ext_0"
9942   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9943                          (const_int 8)
9944                          (const_int 8))
9945         (xor:SI
9946           (zero_extract:SI
9947             (match_operand 1 "ext_register_operand" "0")
9948             (const_int 8)
9949             (const_int 8))
9950           (match_operand 2 "const_int_operand" "n")))
9951    (clobber (reg:CC FLAGS_REG))]
9952   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9953   "xor{b}\t{%2, %h0|%h0, %2}"
9954   [(set_attr "type" "alu")
9955    (set_attr "length_immediate" "1")
9956    (set_attr "mode" "QI")])
9957
9958 (define_insn "*xorqi_ext_1"
9959   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9960                          (const_int 8)
9961                          (const_int 8))
9962         (xor:SI
9963           (zero_extract:SI
9964             (match_operand 1 "ext_register_operand" "0")
9965             (const_int 8)
9966             (const_int 8))
9967           (zero_extend:SI
9968             (match_operand:QI 2 "general_operand" "Qm"))))
9969    (clobber (reg:CC FLAGS_REG))]
9970   "!TARGET_64BIT
9971    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9972   "xor{b}\t{%2, %h0|%h0, %2}"
9973   [(set_attr "type" "alu")
9974    (set_attr "length_immediate" "0")
9975    (set_attr "mode" "QI")])
9976
9977 (define_insn "*xorqi_ext_1_rex64"
9978   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9979                          (const_int 8)
9980                          (const_int 8))
9981         (xor:SI
9982           (zero_extract:SI
9983             (match_operand 1 "ext_register_operand" "0")
9984             (const_int 8)
9985             (const_int 8))
9986           (zero_extend:SI
9987             (match_operand 2 "ext_register_operand" "Q"))))
9988    (clobber (reg:CC FLAGS_REG))]
9989   "TARGET_64BIT
9990    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9991   "xor{b}\t{%2, %h0|%h0, %2}"
9992   [(set_attr "type" "alu")
9993    (set_attr "length_immediate" "0")
9994    (set_attr "mode" "QI")])
9995
9996 (define_insn "*xorqi_ext_2"
9997   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9998                          (const_int 8)
9999                          (const_int 8))
10000         (xor:SI
10001           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10002                            (const_int 8)
10003                            (const_int 8))
10004           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10005                            (const_int 8)
10006                            (const_int 8))))
10007    (clobber (reg:CC FLAGS_REG))]
10008   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
10009   "xor{b}\t{%h2, %h0|%h0, %h2}"
10010   [(set_attr "type" "alu")
10011    (set_attr "length_immediate" "0")
10012    (set_attr "mode" "QI")])
10013
10014 (define_insn "*xorqi_cc_1"
10015   [(set (reg FLAGS_REG)
10016         (compare
10017           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10018                   (match_operand:QI 2 "general_operand" "qim,qi"))
10019           (const_int 0)))
10020    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10021         (xor:QI (match_dup 1) (match_dup 2)))]
10022   "ix86_match_ccmode (insn, CCNOmode)
10023    && ix86_binary_operator_ok (XOR, QImode, operands)"
10024   "xor{b}\t{%2, %0|%0, %2}"
10025   [(set_attr "type" "alu")
10026    (set_attr "mode" "QI")])
10027
10028 (define_insn "*xorqi_2_slp"
10029   [(set (reg FLAGS_REG)
10030         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10031                          (match_operand:QI 1 "general_operand" "qim,qi"))
10032                  (const_int 0)))
10033    (set (strict_low_part (match_dup 0))
10034         (xor:QI (match_dup 0) (match_dup 1)))]
10035   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
10036    && ix86_match_ccmode (insn, CCNOmode)
10037    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10038   "xor{b}\t{%1, %0|%0, %1}"
10039   [(set_attr "type" "alu1")
10040    (set_attr "mode" "QI")])
10041
10042 (define_insn "*xorqi_cc_2"
10043   [(set (reg FLAGS_REG)
10044         (compare
10045           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10046                   (match_operand:QI 2 "general_operand" "qim"))
10047           (const_int 0)))
10048    (clobber (match_scratch:QI 0 "=q"))]
10049   "ix86_match_ccmode (insn, CCNOmode)
10050    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10051   "xor{b}\t{%2, %0|%0, %2}"
10052   [(set_attr "type" "alu")
10053    (set_attr "mode" "QI")])
10054
10055 (define_insn "*xorqi_cc_ext_1"
10056   [(set (reg FLAGS_REG)
10057         (compare
10058           (xor:SI
10059             (zero_extract:SI
10060               (match_operand 1 "ext_register_operand" "0")
10061               (const_int 8)
10062               (const_int 8))
10063             (match_operand:QI 2 "general_operand" "qmn"))
10064           (const_int 0)))
10065    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10066                          (const_int 8)
10067                          (const_int 8))
10068         (xor:SI
10069           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10070           (match_dup 2)))]
10071   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10072   "xor{b}\t{%2, %h0|%h0, %2}"
10073   [(set_attr "type" "alu")
10074    (set_attr "mode" "QI")])
10075
10076 (define_insn "*xorqi_cc_ext_1_rex64"
10077   [(set (reg FLAGS_REG)
10078         (compare
10079           (xor:SI
10080             (zero_extract:SI
10081               (match_operand 1 "ext_register_operand" "0")
10082               (const_int 8)
10083               (const_int 8))
10084             (match_operand:QI 2 "nonmemory_operand" "Qn"))
10085           (const_int 0)))
10086    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10087                          (const_int 8)
10088                          (const_int 8))
10089         (xor:SI
10090           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10091           (match_dup 2)))]
10092   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10093   "xor{b}\t{%2, %h0|%h0, %2}"
10094   [(set_attr "type" "alu")
10095    (set_attr "mode" "QI")])
10096
10097 (define_expand "xorqi_cc_ext_1"
10098   [(parallel [
10099      (set (reg:CCNO FLAGS_REG)
10100           (compare:CCNO
10101             (xor:SI
10102               (zero_extract:SI
10103                 (match_operand 1 "ext_register_operand" "")
10104                 (const_int 8)
10105                 (const_int 8))
10106               (match_operand:QI 2 "general_operand" ""))
10107             (const_int 0)))
10108      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10109                            (const_int 8)
10110                            (const_int 8))
10111           (xor:SI
10112             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10113             (match_dup 2)))])]
10114   ""
10115   "")
10116
10117 (define_split
10118   [(set (match_operand 0 "register_operand" "")
10119         (xor (match_operand 1 "register_operand" "")
10120              (match_operand 2 "const_int_operand" "")))
10121    (clobber (reg:CC FLAGS_REG))]
10122    "reload_completed
10123     && QI_REG_P (operands[0])
10124     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10125     && !(INTVAL (operands[2]) & ~(255 << 8))
10126     && GET_MODE (operands[0]) != QImode"
10127   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10128                    (xor:SI (zero_extract:SI (match_dup 1)
10129                                             (const_int 8) (const_int 8))
10130                            (match_dup 2)))
10131               (clobber (reg:CC FLAGS_REG))])]
10132   "operands[0] = gen_lowpart (SImode, operands[0]);
10133    operands[1] = gen_lowpart (SImode, operands[1]);
10134    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10135
10136 ;; Since XOR can be encoded with sign extended immediate, this is only
10137 ;; profitable when 7th bit is set.
10138 (define_split
10139   [(set (match_operand 0 "register_operand" "")
10140         (xor (match_operand 1 "general_operand" "")
10141              (match_operand 2 "const_int_operand" "")))
10142    (clobber (reg:CC FLAGS_REG))]
10143    "reload_completed
10144     && ANY_QI_REG_P (operands[0])
10145     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10146     && !(INTVAL (operands[2]) & ~255)
10147     && (INTVAL (operands[2]) & 128)
10148     && GET_MODE (operands[0]) != QImode"
10149   [(parallel [(set (strict_low_part (match_dup 0))
10150                    (xor:QI (match_dup 1)
10151                            (match_dup 2)))
10152               (clobber (reg:CC FLAGS_REG))])]
10153   "operands[0] = gen_lowpart (QImode, operands[0]);
10154    operands[1] = gen_lowpart (QImode, operands[1]);
10155    operands[2] = gen_lowpart (QImode, operands[2]);")
10156 \f
10157 ;; Negation instructions
10158
10159 (define_expand "negti2"
10160   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
10161                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10162               (clobber (reg:CC FLAGS_REG))])]
10163   "TARGET_64BIT"
10164   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10165
10166 (define_insn "*negti2_1"
10167   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10168         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10169    (clobber (reg:CC FLAGS_REG))]
10170   "TARGET_64BIT
10171    && ix86_unary_operator_ok (NEG, TImode, operands)"
10172   "#")
10173
10174 (define_split
10175   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10176         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10177    (clobber (reg:CC FLAGS_REG))]
10178   "TARGET_64BIT && reload_completed"
10179   [(parallel
10180     [(set (reg:CCZ FLAGS_REG)
10181           (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10182      (set (match_dup 0) (neg:DI (match_dup 1)))])
10183    (parallel
10184     [(set (match_dup 2)
10185           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10186                             (match_dup 3))
10187                    (const_int 0)))
10188      (clobber (reg:CC FLAGS_REG))])
10189    (parallel
10190     [(set (match_dup 2)
10191           (neg:DI (match_dup 2)))
10192      (clobber (reg:CC FLAGS_REG))])]
10193   "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10194
10195 (define_expand "negdi2"
10196   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
10197                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
10198               (clobber (reg:CC FLAGS_REG))])]
10199   ""
10200   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10201
10202 (define_insn "*negdi2_1"
10203   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10204         (neg:DI (match_operand:DI 1 "general_operand" "0")))
10205    (clobber (reg:CC FLAGS_REG))]
10206   "!TARGET_64BIT
10207    && ix86_unary_operator_ok (NEG, DImode, operands)"
10208   "#")
10209
10210 (define_split
10211   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10212         (neg:DI (match_operand:DI 1 "general_operand" "")))
10213    (clobber (reg:CC FLAGS_REG))]
10214   "!TARGET_64BIT && reload_completed"
10215   [(parallel
10216     [(set (reg:CCZ FLAGS_REG)
10217           (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10218      (set (match_dup 0) (neg:SI (match_dup 1)))])
10219    (parallel
10220     [(set (match_dup 2)
10221           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10222                             (match_dup 3))
10223                    (const_int 0)))
10224      (clobber (reg:CC FLAGS_REG))])
10225    (parallel
10226     [(set (match_dup 2)
10227           (neg:SI (match_dup 2)))
10228      (clobber (reg:CC FLAGS_REG))])]
10229   "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10230
10231 (define_insn "*negdi2_1_rex64"
10232   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10233         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10234    (clobber (reg:CC FLAGS_REG))]
10235   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10236   "neg{q}\t%0"
10237   [(set_attr "type" "negnot")
10238    (set_attr "mode" "DI")])
10239
10240 ;; The problem with neg is that it does not perform (compare x 0),
10241 ;; it really performs (compare 0 x), which leaves us with the zero
10242 ;; flag being the only useful item.
10243
10244 (define_insn "*negdi2_cmpz_rex64"
10245   [(set (reg:CCZ FLAGS_REG)
10246         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10247                      (const_int 0)))
10248    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10249         (neg:DI (match_dup 1)))]
10250   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10251   "neg{q}\t%0"
10252   [(set_attr "type" "negnot")
10253    (set_attr "mode" "DI")])
10254
10255
10256 (define_expand "negsi2"
10257   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
10258                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
10259               (clobber (reg:CC FLAGS_REG))])]
10260   ""
10261   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10262
10263 (define_insn "*negsi2_1"
10264   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10265         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10266    (clobber (reg:CC FLAGS_REG))]
10267   "ix86_unary_operator_ok (NEG, SImode, operands)"
10268   "neg{l}\t%0"
10269   [(set_attr "type" "negnot")
10270    (set_attr "mode" "SI")])
10271
10272 ;; Combine is quite creative about this pattern.
10273 (define_insn "*negsi2_1_zext"
10274   [(set (match_operand:DI 0 "register_operand" "=r")
10275         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10276                                         (const_int 32)))
10277                      (const_int 32)))
10278    (clobber (reg:CC FLAGS_REG))]
10279   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10280   "neg{l}\t%k0"
10281   [(set_attr "type" "negnot")
10282    (set_attr "mode" "SI")])
10283
10284 ;; The problem with neg is that it does not perform (compare x 0),
10285 ;; it really performs (compare 0 x), which leaves us with the zero
10286 ;; flag being the only useful item.
10287
10288 (define_insn "*negsi2_cmpz"
10289   [(set (reg:CCZ FLAGS_REG)
10290         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10291                      (const_int 0)))
10292    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10293         (neg:SI (match_dup 1)))]
10294   "ix86_unary_operator_ok (NEG, SImode, operands)"
10295   "neg{l}\t%0"
10296   [(set_attr "type" "negnot")
10297    (set_attr "mode" "SI")])
10298
10299 (define_insn "*negsi2_cmpz_zext"
10300   [(set (reg:CCZ FLAGS_REG)
10301         (compare:CCZ (lshiftrt:DI
10302                        (neg:DI (ashift:DI
10303                                  (match_operand:DI 1 "register_operand" "0")
10304                                  (const_int 32)))
10305                        (const_int 32))
10306                      (const_int 0)))
10307    (set (match_operand:DI 0 "register_operand" "=r")
10308         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10309                                         (const_int 32)))
10310                      (const_int 32)))]
10311   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10312   "neg{l}\t%k0"
10313   [(set_attr "type" "negnot")
10314    (set_attr "mode" "SI")])
10315
10316 (define_expand "neghi2"
10317   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
10318                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10319               (clobber (reg:CC FLAGS_REG))])]
10320   "TARGET_HIMODE_MATH"
10321   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10322
10323 (define_insn "*neghi2_1"
10324   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10325         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10326    (clobber (reg:CC FLAGS_REG))]
10327   "ix86_unary_operator_ok (NEG, HImode, operands)"
10328   "neg{w}\t%0"
10329   [(set_attr "type" "negnot")
10330    (set_attr "mode" "HI")])
10331
10332 (define_insn "*neghi2_cmpz"
10333   [(set (reg:CCZ FLAGS_REG)
10334         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10335                      (const_int 0)))
10336    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10337         (neg:HI (match_dup 1)))]
10338   "ix86_unary_operator_ok (NEG, HImode, operands)"
10339   "neg{w}\t%0"
10340   [(set_attr "type" "negnot")
10341    (set_attr "mode" "HI")])
10342
10343 (define_expand "negqi2"
10344   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10345                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10346               (clobber (reg:CC FLAGS_REG))])]
10347   "TARGET_QIMODE_MATH"
10348   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10349
10350 (define_insn "*negqi2_1"
10351   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10352         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10353    (clobber (reg:CC FLAGS_REG))]
10354   "ix86_unary_operator_ok (NEG, QImode, operands)"
10355   "neg{b}\t%0"
10356   [(set_attr "type" "negnot")
10357    (set_attr "mode" "QI")])
10358
10359 (define_insn "*negqi2_cmpz"
10360   [(set (reg:CCZ FLAGS_REG)
10361         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10362                      (const_int 0)))
10363    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10364         (neg:QI (match_dup 1)))]
10365   "ix86_unary_operator_ok (NEG, QImode, operands)"
10366   "neg{b}\t%0"
10367   [(set_attr "type" "negnot")
10368    (set_attr "mode" "QI")])
10369
10370 ;; Changing of sign for FP values is doable using integer unit too.
10371
10372 (define_expand "<code><mode>2"
10373   [(set (match_operand:X87MODEF 0 "register_operand" "")
10374         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10375   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10376   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10377
10378 (define_insn "*absneg<mode>2_mixed"
10379   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10380         (match_operator:MODEF 3 "absneg_operator"
10381           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10382    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10383    (clobber (reg:CC FLAGS_REG))]
10384   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10385   "#")
10386
10387 (define_insn "*absneg<mode>2_sse"
10388   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10389         (match_operator:MODEF 3 "absneg_operator"
10390           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10391    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10392    (clobber (reg:CC FLAGS_REG))]
10393   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10394   "#")
10395
10396 (define_insn "*absneg<mode>2_i387"
10397   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10398         (match_operator:X87MODEF 3 "absneg_operator"
10399           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10400    (use (match_operand 2 "" ""))
10401    (clobber (reg:CC FLAGS_REG))]
10402   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10403   "#")
10404
10405 (define_expand "<code>tf2"
10406   [(set (match_operand:TF 0 "register_operand" "")
10407         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10408   "TARGET_64BIT"
10409   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10410
10411 (define_insn "*absnegtf2_sse"
10412   [(set (match_operand:TF 0 "register_operand" "=x,x")
10413         (match_operator:TF 3 "absneg_operator"
10414           [(match_operand:TF 1 "register_operand" "0,x")]))
10415    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10416    (clobber (reg:CC FLAGS_REG))]
10417   "TARGET_64BIT"
10418   "#")
10419
10420 ;; Splitters for fp abs and neg.
10421
10422 (define_split
10423   [(set (match_operand 0 "fp_register_operand" "")
10424         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10425    (use (match_operand 2 "" ""))
10426    (clobber (reg:CC FLAGS_REG))]
10427   "reload_completed"
10428   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10429
10430 (define_split
10431   [(set (match_operand 0 "register_operand" "")
10432         (match_operator 3 "absneg_operator"
10433           [(match_operand 1 "register_operand" "")]))
10434    (use (match_operand 2 "nonimmediate_operand" ""))
10435    (clobber (reg:CC FLAGS_REG))]
10436   "reload_completed && SSE_REG_P (operands[0])"
10437   [(set (match_dup 0) (match_dup 3))]
10438 {
10439   enum machine_mode mode = GET_MODE (operands[0]);
10440   enum machine_mode vmode = GET_MODE (operands[2]);
10441   rtx tmp;
10442
10443   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10444   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10445   if (operands_match_p (operands[0], operands[2]))
10446     {
10447       tmp = operands[1];
10448       operands[1] = operands[2];
10449       operands[2] = tmp;
10450     }
10451   if (GET_CODE (operands[3]) == ABS)
10452     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10453   else
10454     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10455   operands[3] = tmp;
10456 })
10457
10458 (define_split
10459   [(set (match_operand:SF 0 "register_operand" "")
10460         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10461    (use (match_operand:V4SF 2 "" ""))
10462    (clobber (reg:CC FLAGS_REG))]
10463   "reload_completed"
10464   [(parallel [(set (match_dup 0) (match_dup 1))
10465               (clobber (reg:CC FLAGS_REG))])]
10466 {
10467   rtx tmp;
10468   operands[0] = gen_lowpart (SImode, operands[0]);
10469   if (GET_CODE (operands[1]) == ABS)
10470     {
10471       tmp = gen_int_mode (0x7fffffff, SImode);
10472       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10473     }
10474   else
10475     {
10476       tmp = gen_int_mode (0x80000000, SImode);
10477       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10478     }
10479   operands[1] = tmp;
10480 })
10481
10482 (define_split
10483   [(set (match_operand:DF 0 "register_operand" "")
10484         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10485    (use (match_operand 2 "" ""))
10486    (clobber (reg:CC FLAGS_REG))]
10487   "reload_completed"
10488   [(parallel [(set (match_dup 0) (match_dup 1))
10489               (clobber (reg:CC FLAGS_REG))])]
10490 {
10491   rtx tmp;
10492   if (TARGET_64BIT)
10493     {
10494       tmp = gen_lowpart (DImode, operands[0]);
10495       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10496       operands[0] = tmp;
10497
10498       if (GET_CODE (operands[1]) == ABS)
10499         tmp = const0_rtx;
10500       else
10501         tmp = gen_rtx_NOT (DImode, tmp);
10502     }
10503   else
10504     {
10505       operands[0] = gen_highpart (SImode, operands[0]);
10506       if (GET_CODE (operands[1]) == ABS)
10507         {
10508           tmp = gen_int_mode (0x7fffffff, SImode);
10509           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10510         }
10511       else
10512         {
10513           tmp = gen_int_mode (0x80000000, SImode);
10514           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10515         }
10516     }
10517   operands[1] = tmp;
10518 })
10519
10520 (define_split
10521   [(set (match_operand:XF 0 "register_operand" "")
10522         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10523    (use (match_operand 2 "" ""))
10524    (clobber (reg:CC FLAGS_REG))]
10525   "reload_completed"
10526   [(parallel [(set (match_dup 0) (match_dup 1))
10527               (clobber (reg:CC FLAGS_REG))])]
10528 {
10529   rtx tmp;
10530   operands[0] = gen_rtx_REG (SImode,
10531                              true_regnum (operands[0])
10532                              + (TARGET_64BIT ? 1 : 2));
10533   if (GET_CODE (operands[1]) == ABS)
10534     {
10535       tmp = GEN_INT (0x7fff);
10536       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10537     }
10538   else
10539     {
10540       tmp = GEN_INT (0x8000);
10541       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10542     }
10543   operands[1] = tmp;
10544 })
10545
10546 ;; Conditionalize these after reload. If they match before reload, we
10547 ;; lose the clobber and ability to use integer instructions.
10548
10549 (define_insn "*<code><mode>2_1"
10550   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10551         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10552   "TARGET_80387
10553    && (reload_completed
10554        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10555   "f<absnegprefix>"
10556   [(set_attr "type" "fsgn")
10557    (set_attr "mode" "<MODE>")])
10558
10559 (define_insn "*<code>extendsfdf2"
10560   [(set (match_operand:DF 0 "register_operand" "=f")
10561         (absneg:DF (float_extend:DF
10562                      (match_operand:SF 1 "register_operand" "0"))))]
10563   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10564   "f<absnegprefix>"
10565   [(set_attr "type" "fsgn")
10566    (set_attr "mode" "DF")])
10567
10568 (define_insn "*<code>extendsfxf2"
10569   [(set (match_operand:XF 0 "register_operand" "=f")
10570         (absneg:XF (float_extend:XF
10571                      (match_operand:SF 1 "register_operand" "0"))))]
10572   "TARGET_80387"
10573   "f<absnegprefix>"
10574   [(set_attr "type" "fsgn")
10575    (set_attr "mode" "XF")])
10576
10577 (define_insn "*<code>extenddfxf2"
10578   [(set (match_operand:XF 0 "register_operand" "=f")
10579         (absneg:XF (float_extend:XF
10580                       (match_operand:DF 1 "register_operand" "0"))))]
10581   "TARGET_80387"
10582   "f<absnegprefix>"
10583   [(set_attr "type" "fsgn")
10584    (set_attr "mode" "XF")])
10585
10586 ;; Copysign instructions
10587
10588 (define_mode_iterator CSGNMODE [SF DF TF])
10589 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10590
10591 (define_expand "copysign<mode>3"
10592   [(match_operand:CSGNMODE 0 "register_operand" "")
10593    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10594    (match_operand:CSGNMODE 2 "register_operand" "")]
10595   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10596    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10597 {
10598   ix86_expand_copysign (operands);
10599   DONE;
10600 })
10601
10602 (define_insn_and_split "copysign<mode>3_const"
10603   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10604         (unspec:CSGNMODE
10605           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10606            (match_operand:CSGNMODE 2 "register_operand" "0")
10607            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10608           UNSPEC_COPYSIGN))]
10609   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10610    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10611   "#"
10612   "&& reload_completed"
10613   [(const_int 0)]
10614 {
10615   ix86_split_copysign_const (operands);
10616   DONE;
10617 })
10618
10619 (define_insn "copysign<mode>3_var"
10620   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10621         (unspec:CSGNMODE
10622           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10623            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10624            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10625            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10626           UNSPEC_COPYSIGN))
10627    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10628   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10629    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10630   "#")
10631
10632 (define_split
10633   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10634         (unspec:CSGNMODE
10635           [(match_operand:CSGNMODE 2 "register_operand" "")
10636            (match_operand:CSGNMODE 3 "register_operand" "")
10637            (match_operand:<CSGNVMODE> 4 "" "")
10638            (match_operand:<CSGNVMODE> 5 "" "")]
10639           UNSPEC_COPYSIGN))
10640    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10641   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10642     || (TARGET_64BIT && (<MODE>mode == TFmode)))
10643    && reload_completed"
10644   [(const_int 0)]
10645 {
10646   ix86_split_copysign_var (operands);
10647   DONE;
10648 })
10649 \f
10650 ;; One complement instructions
10651
10652 (define_expand "one_cmpldi2"
10653   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10654         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10655   "TARGET_64BIT"
10656   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10657
10658 (define_insn "*one_cmpldi2_1_rex64"
10659   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10660         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10661   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10662   "not{q}\t%0"
10663   [(set_attr "type" "negnot")
10664    (set_attr "mode" "DI")])
10665
10666 (define_insn "*one_cmpldi2_2_rex64"
10667   [(set (reg FLAGS_REG)
10668         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10669                  (const_int 0)))
10670    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10671         (not:DI (match_dup 1)))]
10672   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10673    && ix86_unary_operator_ok (NOT, DImode, operands)"
10674   "#"
10675   [(set_attr "type" "alu1")
10676    (set_attr "mode" "DI")])
10677
10678 (define_split
10679   [(set (match_operand 0 "flags_reg_operand" "")
10680         (match_operator 2 "compare_operator"
10681           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10682            (const_int 0)]))
10683    (set (match_operand:DI 1 "nonimmediate_operand" "")
10684         (not:DI (match_dup 3)))]
10685   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10686   [(parallel [(set (match_dup 0)
10687                    (match_op_dup 2
10688                      [(xor:DI (match_dup 3) (const_int -1))
10689                       (const_int 0)]))
10690               (set (match_dup 1)
10691                    (xor:DI (match_dup 3) (const_int -1)))])]
10692   "")
10693
10694 (define_expand "one_cmplsi2"
10695   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10696         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10697   ""
10698   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10699
10700 (define_insn "*one_cmplsi2_1"
10701   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10702         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10703   "ix86_unary_operator_ok (NOT, SImode, operands)"
10704   "not{l}\t%0"
10705   [(set_attr "type" "negnot")
10706    (set_attr "mode" "SI")])
10707
10708 ;; ??? Currently never generated - xor is used instead.
10709 (define_insn "*one_cmplsi2_1_zext"
10710   [(set (match_operand:DI 0 "register_operand" "=r")
10711         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10712   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10713   "not{l}\t%k0"
10714   [(set_attr "type" "negnot")
10715    (set_attr "mode" "SI")])
10716
10717 (define_insn "*one_cmplsi2_2"
10718   [(set (reg FLAGS_REG)
10719         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10720                  (const_int 0)))
10721    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10722         (not:SI (match_dup 1)))]
10723   "ix86_match_ccmode (insn, CCNOmode)
10724    && ix86_unary_operator_ok (NOT, SImode, operands)"
10725   "#"
10726   [(set_attr "type" "alu1")
10727    (set_attr "mode" "SI")])
10728
10729 (define_split
10730   [(set (match_operand 0 "flags_reg_operand" "")
10731         (match_operator 2 "compare_operator"
10732           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10733            (const_int 0)]))
10734    (set (match_operand:SI 1 "nonimmediate_operand" "")
10735         (not:SI (match_dup 3)))]
10736   "ix86_match_ccmode (insn, CCNOmode)"
10737   [(parallel [(set (match_dup 0)
10738                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10739                                     (const_int 0)]))
10740               (set (match_dup 1)
10741                    (xor:SI (match_dup 3) (const_int -1)))])]
10742   "")
10743
10744 ;; ??? Currently never generated - xor is used instead.
10745 (define_insn "*one_cmplsi2_2_zext"
10746   [(set (reg FLAGS_REG)
10747         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10748                  (const_int 0)))
10749    (set (match_operand:DI 0 "register_operand" "=r")
10750         (zero_extend:DI (not:SI (match_dup 1))))]
10751   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10752    && ix86_unary_operator_ok (NOT, SImode, operands)"
10753   "#"
10754   [(set_attr "type" "alu1")
10755    (set_attr "mode" "SI")])
10756
10757 (define_split
10758   [(set (match_operand 0 "flags_reg_operand" "")
10759         (match_operator 2 "compare_operator"
10760           [(not:SI (match_operand:SI 3 "register_operand" ""))
10761            (const_int 0)]))
10762    (set (match_operand:DI 1 "register_operand" "")
10763         (zero_extend:DI (not:SI (match_dup 3))))]
10764   "ix86_match_ccmode (insn, CCNOmode)"
10765   [(parallel [(set (match_dup 0)
10766                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10767                                     (const_int 0)]))
10768               (set (match_dup 1)
10769                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10770   "")
10771
10772 (define_expand "one_cmplhi2"
10773   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10774         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10775   "TARGET_HIMODE_MATH"
10776   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10777
10778 (define_insn "*one_cmplhi2_1"
10779   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10780         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10781   "ix86_unary_operator_ok (NOT, HImode, operands)"
10782   "not{w}\t%0"
10783   [(set_attr "type" "negnot")
10784    (set_attr "mode" "HI")])
10785
10786 (define_insn "*one_cmplhi2_2"
10787   [(set (reg FLAGS_REG)
10788         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10789                  (const_int 0)))
10790    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10791         (not:HI (match_dup 1)))]
10792   "ix86_match_ccmode (insn, CCNOmode)
10793    && ix86_unary_operator_ok (NEG, HImode, operands)"
10794   "#"
10795   [(set_attr "type" "alu1")
10796    (set_attr "mode" "HI")])
10797
10798 (define_split
10799   [(set (match_operand 0 "flags_reg_operand" "")
10800         (match_operator 2 "compare_operator"
10801           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10802            (const_int 0)]))
10803    (set (match_operand:HI 1 "nonimmediate_operand" "")
10804         (not:HI (match_dup 3)))]
10805   "ix86_match_ccmode (insn, CCNOmode)"
10806   [(parallel [(set (match_dup 0)
10807                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10808                                     (const_int 0)]))
10809               (set (match_dup 1)
10810                    (xor:HI (match_dup 3) (const_int -1)))])]
10811   "")
10812
10813 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10814 (define_expand "one_cmplqi2"
10815   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10816         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10817   "TARGET_QIMODE_MATH"
10818   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10819
10820 (define_insn "*one_cmplqi2_1"
10821   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10822         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10823   "ix86_unary_operator_ok (NOT, QImode, operands)"
10824   "@
10825    not{b}\t%0
10826    not{l}\t%k0"
10827   [(set_attr "type" "negnot")
10828    (set_attr "mode" "QI,SI")])
10829
10830 (define_insn "*one_cmplqi2_2"
10831   [(set (reg FLAGS_REG)
10832         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10833                  (const_int 0)))
10834    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10835         (not:QI (match_dup 1)))]
10836   "ix86_match_ccmode (insn, CCNOmode)
10837    && ix86_unary_operator_ok (NOT, QImode, operands)"
10838   "#"
10839   [(set_attr "type" "alu1")
10840    (set_attr "mode" "QI")])
10841
10842 (define_split
10843   [(set (match_operand 0 "flags_reg_operand" "")
10844         (match_operator 2 "compare_operator"
10845           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10846            (const_int 0)]))
10847    (set (match_operand:QI 1 "nonimmediate_operand" "")
10848         (not:QI (match_dup 3)))]
10849   "ix86_match_ccmode (insn, CCNOmode)"
10850   [(parallel [(set (match_dup 0)
10851                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10852                                     (const_int 0)]))
10853               (set (match_dup 1)
10854                    (xor:QI (match_dup 3) (const_int -1)))])]
10855   "")
10856 \f
10857 ;; Arithmetic shift instructions
10858
10859 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10860 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10861 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10862 ;; from the assembler input.
10863 ;;
10864 ;; This instruction shifts the target reg/mem as usual, but instead of
10865 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10866 ;; is a left shift double, bits are taken from the high order bits of
10867 ;; reg, else if the insn is a shift right double, bits are taken from the
10868 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10869 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10870 ;;
10871 ;; Since sh[lr]d does not change the `reg' operand, that is done
10872 ;; separately, making all shifts emit pairs of shift double and normal
10873 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10874 ;; support a 63 bit shift, each shift where the count is in a reg expands
10875 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10876 ;;
10877 ;; If the shift count is a constant, we need never emit more than one
10878 ;; shift pair, instead using moves and sign extension for counts greater
10879 ;; than 31.
10880
10881 (define_expand "ashlti3"
10882   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10883                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10884                               (match_operand:QI 2 "nonmemory_operand" "")))
10885               (clobber (reg:CC FLAGS_REG))])]
10886   "TARGET_64BIT"
10887 {
10888   if (! immediate_operand (operands[2], QImode))
10889     {
10890       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10891       DONE;
10892     }
10893   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10894   DONE;
10895 })
10896
10897 (define_insn "ashlti3_1"
10898   [(set (match_operand:TI 0 "register_operand" "=r")
10899         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10900                    (match_operand:QI 2 "register_operand" "c")))
10901    (clobber (match_scratch:DI 3 "=&r"))
10902    (clobber (reg:CC FLAGS_REG))]
10903   "TARGET_64BIT"
10904   "#"
10905   [(set_attr "type" "multi")])
10906
10907 ;; This pattern must be defined before *ashlti3_2 to prevent
10908 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10909
10910 (define_insn "sse2_ashlti3"
10911   [(set (match_operand:TI 0 "register_operand" "=x")
10912         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10913                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10914   "TARGET_SSE2"
10915 {
10916   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10917   return "pslldq\t{%2, %0|%0, %2}";
10918 }
10919   [(set_attr "type" "sseishft")
10920    (set_attr "prefix_data16" "1")
10921    (set_attr "mode" "TI")])
10922
10923 (define_insn "*ashlti3_2"
10924   [(set (match_operand:TI 0 "register_operand" "=r")
10925         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10926                    (match_operand:QI 2 "immediate_operand" "O")))
10927    (clobber (reg:CC FLAGS_REG))]
10928   "TARGET_64BIT"
10929   "#"
10930   [(set_attr "type" "multi")])
10931
10932 (define_split
10933   [(set (match_operand:TI 0 "register_operand" "")
10934         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10935                    (match_operand:QI 2 "register_operand" "")))
10936    (clobber (match_scratch:DI 3 ""))
10937    (clobber (reg:CC FLAGS_REG))]
10938   "TARGET_64BIT && reload_completed"
10939   [(const_int 0)]
10940   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10941
10942 (define_split
10943   [(set (match_operand:TI 0 "register_operand" "")
10944         (ashift:TI (match_operand:TI 1 "register_operand" "")
10945                    (match_operand:QI 2 "immediate_operand" "")))
10946    (clobber (reg:CC FLAGS_REG))]
10947   "TARGET_64BIT && reload_completed"
10948   [(const_int 0)]
10949   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10950
10951 (define_insn "x86_64_shld"
10952   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10953         (ior:DI (ashift:DI (match_dup 0)
10954                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10955                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10956                   (minus:QI (const_int 64) (match_dup 2)))))
10957    (clobber (reg:CC FLAGS_REG))]
10958   "TARGET_64BIT"
10959   "@
10960    shld{q}\t{%2, %1, %0|%0, %1, %2}
10961    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10962   [(set_attr "type" "ishift")
10963    (set_attr "prefix_0f" "1")
10964    (set_attr "mode" "DI")
10965    (set_attr "athlon_decode" "vector")
10966    (set_attr "amdfam10_decode" "vector")])
10967
10968 (define_expand "x86_64_shift_adj"
10969   [(set (reg:CCZ FLAGS_REG)
10970         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10971                              (const_int 64))
10972                      (const_int 0)))
10973    (set (match_operand:DI 0 "register_operand" "")
10974         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10975                          (match_operand:DI 1 "register_operand" "")
10976                          (match_dup 0)))
10977    (set (match_dup 1)
10978         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10979                          (match_operand:DI 3 "register_operand" "r")
10980                          (match_dup 1)))]
10981   "TARGET_64BIT"
10982   "")
10983
10984 (define_expand "ashldi3"
10985   [(set (match_operand:DI 0 "shiftdi_operand" "")
10986         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10987                    (match_operand:QI 2 "nonmemory_operand" "")))]
10988   ""
10989   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10990
10991 (define_insn "*ashldi3_1_rex64"
10992   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10993         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10994                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10995    (clobber (reg:CC FLAGS_REG))]
10996   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10997 {
10998   switch (get_attr_type (insn))
10999     {
11000     case TYPE_ALU:
11001       gcc_assert (operands[2] == const1_rtx);
11002       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11003       return "add{q}\t%0, %0";
11004
11005     case TYPE_LEA:
11006       gcc_assert (CONST_INT_P (operands[2]));
11007       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11008       operands[1] = gen_rtx_MULT (DImode, operands[1],
11009                                   GEN_INT (1 << INTVAL (operands[2])));
11010       return "lea{q}\t{%a1, %0|%0, %a1}";
11011
11012     default:
11013       if (REG_P (operands[2]))
11014         return "sal{q}\t{%b2, %0|%0, %b2}";
11015       else if (operands[2] == const1_rtx
11016                && (TARGET_SHIFT1 || optimize_size))
11017         return "sal{q}\t%0";
11018       else
11019         return "sal{q}\t{%2, %0|%0, %2}";
11020     }
11021 }
11022   [(set (attr "type")
11023      (cond [(eq_attr "alternative" "1")
11024               (const_string "lea")
11025             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11026                           (const_int 0))
11027                       (match_operand 0 "register_operand" ""))
11028                  (match_operand 2 "const1_operand" ""))
11029               (const_string "alu")
11030            ]
11031            (const_string "ishift")))
11032    (set_attr "mode" "DI")])
11033
11034 ;; Convert lea to the lea pattern to avoid flags dependency.
11035 (define_split
11036   [(set (match_operand:DI 0 "register_operand" "")
11037         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11038                    (match_operand:QI 2 "immediate_operand" "")))
11039    (clobber (reg:CC FLAGS_REG))]
11040   "TARGET_64BIT && reload_completed
11041    && true_regnum (operands[0]) != true_regnum (operands[1])"
11042   [(set (match_dup 0)
11043         (mult:DI (match_dup 1)
11044                  (match_dup 2)))]
11045   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11046
11047 ;; This pattern can't accept a variable shift count, since shifts by
11048 ;; zero don't affect the flags.  We assume that shifts by constant
11049 ;; zero are optimized away.
11050 (define_insn "*ashldi3_cmp_rex64"
11051   [(set (reg FLAGS_REG)
11052         (compare
11053           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11054                      (match_operand:QI 2 "immediate_operand" "e"))
11055           (const_int 0)))
11056    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11057         (ashift:DI (match_dup 1) (match_dup 2)))]
11058   "TARGET_64BIT
11059    && (optimize_size
11060        || !TARGET_PARTIAL_FLAG_REG_STALL
11061        || (operands[2] == const1_rtx
11062            && (TARGET_SHIFT1
11063                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11064    && ix86_match_ccmode (insn, CCGOCmode)
11065    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11066 {
11067   switch (get_attr_type (insn))
11068     {
11069     case TYPE_ALU:
11070       gcc_assert (operands[2] == const1_rtx);
11071       return "add{q}\t%0, %0";
11072
11073     default:
11074       if (REG_P (operands[2]))
11075         return "sal{q}\t{%b2, %0|%0, %b2}";
11076       else if (operands[2] == const1_rtx
11077                && (TARGET_SHIFT1 || optimize_size))
11078         return "sal{q}\t%0";
11079       else
11080         return "sal{q}\t{%2, %0|%0, %2}";
11081     }
11082 }
11083   [(set (attr "type")
11084      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11085                           (const_int 0))
11086                       (match_operand 0 "register_operand" ""))
11087                  (match_operand 2 "const1_operand" ""))
11088               (const_string "alu")
11089            ]
11090            (const_string "ishift")))
11091    (set_attr "mode" "DI")])
11092
11093 (define_insn "*ashldi3_cconly_rex64"
11094   [(set (reg FLAGS_REG)
11095         (compare
11096           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11097                      (match_operand:QI 2 "immediate_operand" "e"))
11098           (const_int 0)))
11099    (clobber (match_scratch:DI 0 "=r"))]
11100   "TARGET_64BIT
11101    && (optimize_size
11102        || !TARGET_PARTIAL_FLAG_REG_STALL
11103        || (operands[2] == const1_rtx
11104            && (TARGET_SHIFT1
11105                || TARGET_DOUBLE_WITH_ADD)))
11106    && ix86_match_ccmode (insn, CCGOCmode)
11107    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11108 {
11109   switch (get_attr_type (insn))
11110     {
11111     case TYPE_ALU:
11112       gcc_assert (operands[2] == const1_rtx);
11113       return "add{q}\t%0, %0";
11114
11115     default:
11116       if (REG_P (operands[2]))
11117         return "sal{q}\t{%b2, %0|%0, %b2}";
11118       else if (operands[2] == const1_rtx
11119                && (TARGET_SHIFT1 || optimize_size))
11120         return "sal{q}\t%0";
11121       else
11122         return "sal{q}\t{%2, %0|%0, %2}";
11123     }
11124 }
11125   [(set (attr "type")
11126      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11127                           (const_int 0))
11128                       (match_operand 0 "register_operand" ""))
11129                  (match_operand 2 "const1_operand" ""))
11130               (const_string "alu")
11131            ]
11132            (const_string "ishift")))
11133    (set_attr "mode" "DI")])
11134
11135 (define_insn "*ashldi3_1"
11136   [(set (match_operand:DI 0 "register_operand" "=&r,r")
11137         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11138                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11139    (clobber (reg:CC FLAGS_REG))]
11140   "!TARGET_64BIT"
11141   "#"
11142   [(set_attr "type" "multi")])
11143
11144 ;; By default we don't ask for a scratch register, because when DImode
11145 ;; values are manipulated, registers are already at a premium.  But if
11146 ;; we have one handy, we won't turn it away.
11147 (define_peephole2
11148   [(match_scratch:SI 3 "r")
11149    (parallel [(set (match_operand:DI 0 "register_operand" "")
11150                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11151                               (match_operand:QI 2 "nonmemory_operand" "")))
11152               (clobber (reg:CC FLAGS_REG))])
11153    (match_dup 3)]
11154   "!TARGET_64BIT && TARGET_CMOVE"
11155   [(const_int 0)]
11156   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11157
11158 (define_split
11159   [(set (match_operand:DI 0 "register_operand" "")
11160         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11161                    (match_operand:QI 2 "nonmemory_operand" "")))
11162    (clobber (reg:CC FLAGS_REG))]
11163   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11164                      ? epilogue_completed : reload_completed)"
11165   [(const_int 0)]
11166   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11167
11168 (define_insn "x86_shld_1"
11169   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11170         (ior:SI (ashift:SI (match_dup 0)
11171                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11172                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11173                   (minus:QI (const_int 32) (match_dup 2)))))
11174    (clobber (reg:CC FLAGS_REG))]
11175   ""
11176   "@
11177    shld{l}\t{%2, %1, %0|%0, %1, %2}
11178    shld{l}\t{%s2%1, %0|%0, %1, %2}"
11179   [(set_attr "type" "ishift")
11180    (set_attr "prefix_0f" "1")
11181    (set_attr "mode" "SI")
11182    (set_attr "pent_pair" "np")
11183    (set_attr "athlon_decode" "vector")
11184    (set_attr "amdfam10_decode" "vector")])
11185
11186 (define_expand "x86_shift_adj_1"
11187   [(set (reg:CCZ FLAGS_REG)
11188         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11189                              (const_int 32))
11190                      (const_int 0)))
11191    (set (match_operand:SI 0 "register_operand" "")
11192         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11193                          (match_operand:SI 1 "register_operand" "")
11194                          (match_dup 0)))
11195    (set (match_dup 1)
11196         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11197                          (match_operand:SI 3 "register_operand" "r")
11198                          (match_dup 1)))]
11199   "TARGET_CMOVE"
11200   "")
11201
11202 (define_expand "x86_shift_adj_2"
11203   [(use (match_operand:SI 0 "register_operand" ""))
11204    (use (match_operand:SI 1 "register_operand" ""))
11205    (use (match_operand:QI 2 "register_operand" ""))]
11206   ""
11207 {
11208   rtx label = gen_label_rtx ();
11209   rtx tmp;
11210
11211   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11212
11213   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11214   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11215   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11216                               gen_rtx_LABEL_REF (VOIDmode, label),
11217                               pc_rtx);
11218   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11219   JUMP_LABEL (tmp) = label;
11220
11221   emit_move_insn (operands[0], operands[1]);
11222   ix86_expand_clear (operands[1]);
11223
11224   emit_label (label);
11225   LABEL_NUSES (label) = 1;
11226
11227   DONE;
11228 })
11229
11230 (define_expand "ashlsi3"
11231   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11232         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11233                    (match_operand:QI 2 "nonmemory_operand" "")))
11234    (clobber (reg:CC FLAGS_REG))]
11235   ""
11236   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11237
11238 (define_insn "*ashlsi3_1"
11239   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11240         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11241                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11242    (clobber (reg:CC FLAGS_REG))]
11243   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11244 {
11245   switch (get_attr_type (insn))
11246     {
11247     case TYPE_ALU:
11248       gcc_assert (operands[2] == const1_rtx);
11249       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11250       return "add{l}\t%0, %0";
11251
11252     case TYPE_LEA:
11253       return "#";
11254
11255     default:
11256       if (REG_P (operands[2]))
11257         return "sal{l}\t{%b2, %0|%0, %b2}";
11258       else if (operands[2] == const1_rtx
11259                && (TARGET_SHIFT1 || optimize_size))
11260         return "sal{l}\t%0";
11261       else
11262         return "sal{l}\t{%2, %0|%0, %2}";
11263     }
11264 }
11265   [(set (attr "type")
11266      (cond [(eq_attr "alternative" "1")
11267               (const_string "lea")
11268             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11269                           (const_int 0))
11270                       (match_operand 0 "register_operand" ""))
11271                  (match_operand 2 "const1_operand" ""))
11272               (const_string "alu")
11273            ]
11274            (const_string "ishift")))
11275    (set_attr "mode" "SI")])
11276
11277 ;; Convert lea to the lea pattern to avoid flags dependency.
11278 (define_split
11279   [(set (match_operand 0 "register_operand" "")
11280         (ashift (match_operand 1 "index_register_operand" "")
11281                 (match_operand:QI 2 "const_int_operand" "")))
11282    (clobber (reg:CC FLAGS_REG))]
11283   "reload_completed
11284    && true_regnum (operands[0]) != true_regnum (operands[1])
11285    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11286   [(const_int 0)]
11287 {
11288   rtx pat;
11289   enum machine_mode mode = GET_MODE (operands[0]);
11290
11291   if (GET_MODE_SIZE (mode) < 4)
11292     operands[0] = gen_lowpart (SImode, operands[0]);
11293   if (mode != Pmode)
11294     operands[1] = gen_lowpart (Pmode, operands[1]);
11295   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11296
11297   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11298   if (Pmode != SImode)
11299     pat = gen_rtx_SUBREG (SImode, pat, 0);
11300   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11301   DONE;
11302 })
11303
11304 ;; Rare case of shifting RSP is handled by generating move and shift
11305 (define_split
11306   [(set (match_operand 0 "register_operand" "")
11307         (ashift (match_operand 1 "register_operand" "")
11308                 (match_operand:QI 2 "const_int_operand" "")))
11309    (clobber (reg:CC FLAGS_REG))]
11310   "reload_completed
11311    && true_regnum (operands[0]) != true_regnum (operands[1])"
11312   [(const_int 0)]
11313 {
11314   rtx pat, clob;
11315   emit_move_insn (operands[0], operands[1]);
11316   pat = gen_rtx_SET (VOIDmode, operands[0],
11317                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11318                                      operands[0], operands[2]));
11319   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11320   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11321   DONE;
11322 })
11323
11324 (define_insn "*ashlsi3_1_zext"
11325   [(set (match_operand:DI 0 "register_operand" "=r,r")
11326         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11327                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11328    (clobber (reg:CC FLAGS_REG))]
11329   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11330 {
11331   switch (get_attr_type (insn))
11332     {
11333     case TYPE_ALU:
11334       gcc_assert (operands[2] == const1_rtx);
11335       return "add{l}\t%k0, %k0";
11336
11337     case TYPE_LEA:
11338       return "#";
11339
11340     default:
11341       if (REG_P (operands[2]))
11342         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11343       else if (operands[2] == const1_rtx
11344                && (TARGET_SHIFT1 || optimize_size))
11345         return "sal{l}\t%k0";
11346       else
11347         return "sal{l}\t{%2, %k0|%k0, %2}";
11348     }
11349 }
11350   [(set (attr "type")
11351      (cond [(eq_attr "alternative" "1")
11352               (const_string "lea")
11353             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11354                      (const_int 0))
11355                  (match_operand 2 "const1_operand" ""))
11356               (const_string "alu")
11357            ]
11358            (const_string "ishift")))
11359    (set_attr "mode" "SI")])
11360
11361 ;; Convert lea to the lea pattern to avoid flags dependency.
11362 (define_split
11363   [(set (match_operand:DI 0 "register_operand" "")
11364         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11365                                 (match_operand:QI 2 "const_int_operand" ""))))
11366    (clobber (reg:CC FLAGS_REG))]
11367   "TARGET_64BIT && reload_completed
11368    && true_regnum (operands[0]) != true_regnum (operands[1])"
11369   [(set (match_dup 0) (zero_extend:DI
11370                         (subreg:SI (mult:SI (match_dup 1)
11371                                             (match_dup 2)) 0)))]
11372 {
11373   operands[1] = gen_lowpart (Pmode, operands[1]);
11374   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11375 })
11376
11377 ;; This pattern can't accept a variable shift count, since shifts by
11378 ;; zero don't affect the flags.  We assume that shifts by constant
11379 ;; zero are optimized away.
11380 (define_insn "*ashlsi3_cmp"
11381   [(set (reg FLAGS_REG)
11382         (compare
11383           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11384                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11385           (const_int 0)))
11386    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11387         (ashift:SI (match_dup 1) (match_dup 2)))]
11388    "(optimize_size
11389      || !TARGET_PARTIAL_FLAG_REG_STALL
11390      || (operands[2] == const1_rtx
11391          && (TARGET_SHIFT1
11392              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11393    && ix86_match_ccmode (insn, CCGOCmode)
11394    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11395 {
11396   switch (get_attr_type (insn))
11397     {
11398     case TYPE_ALU:
11399       gcc_assert (operands[2] == const1_rtx);
11400       return "add{l}\t%0, %0";
11401
11402     default:
11403       if (REG_P (operands[2]))
11404         return "sal{l}\t{%b2, %0|%0, %b2}";
11405       else if (operands[2] == const1_rtx
11406                && (TARGET_SHIFT1 || optimize_size))
11407         return "sal{l}\t%0";
11408       else
11409         return "sal{l}\t{%2, %0|%0, %2}";
11410     }
11411 }
11412   [(set (attr "type")
11413      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11414                           (const_int 0))
11415                       (match_operand 0 "register_operand" ""))
11416                  (match_operand 2 "const1_operand" ""))
11417               (const_string "alu")
11418            ]
11419            (const_string "ishift")))
11420    (set_attr "mode" "SI")])
11421
11422 (define_insn "*ashlsi3_cconly"
11423   [(set (reg FLAGS_REG)
11424         (compare
11425           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11426                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11427           (const_int 0)))
11428    (clobber (match_scratch:SI 0 "=r"))]
11429   "(optimize_size
11430     || !TARGET_PARTIAL_FLAG_REG_STALL
11431     || (operands[2] == const1_rtx
11432         && (TARGET_SHIFT1
11433             || TARGET_DOUBLE_WITH_ADD)))
11434    && ix86_match_ccmode (insn, CCGOCmode)
11435    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11436 {
11437   switch (get_attr_type (insn))
11438     {
11439     case TYPE_ALU:
11440       gcc_assert (operands[2] == const1_rtx);
11441       return "add{l}\t%0, %0";
11442
11443     default:
11444       if (REG_P (operands[2]))
11445         return "sal{l}\t{%b2, %0|%0, %b2}";
11446       else if (operands[2] == const1_rtx
11447                && (TARGET_SHIFT1 || optimize_size))
11448         return "sal{l}\t%0";
11449       else
11450         return "sal{l}\t{%2, %0|%0, %2}";
11451     }
11452 }
11453   [(set (attr "type")
11454      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11455                           (const_int 0))
11456                       (match_operand 0 "register_operand" ""))
11457                  (match_operand 2 "const1_operand" ""))
11458               (const_string "alu")
11459            ]
11460            (const_string "ishift")))
11461    (set_attr "mode" "SI")])
11462
11463 (define_insn "*ashlsi3_cmp_zext"
11464   [(set (reg FLAGS_REG)
11465         (compare
11466           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11467                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11468           (const_int 0)))
11469    (set (match_operand:DI 0 "register_operand" "=r")
11470         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11471   "TARGET_64BIT
11472    && (optimize_size
11473        || !TARGET_PARTIAL_FLAG_REG_STALL
11474        || (operands[2] == const1_rtx
11475            && (TARGET_SHIFT1
11476                || TARGET_DOUBLE_WITH_ADD)))
11477    && ix86_match_ccmode (insn, CCGOCmode)
11478    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11479 {
11480   switch (get_attr_type (insn))
11481     {
11482     case TYPE_ALU:
11483       gcc_assert (operands[2] == const1_rtx);
11484       return "add{l}\t%k0, %k0";
11485
11486     default:
11487       if (REG_P (operands[2]))
11488         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11489       else if (operands[2] == const1_rtx
11490                && (TARGET_SHIFT1 || optimize_size))
11491         return "sal{l}\t%k0";
11492       else
11493         return "sal{l}\t{%2, %k0|%k0, %2}";
11494     }
11495 }
11496   [(set (attr "type")
11497      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11498                      (const_int 0))
11499                  (match_operand 2 "const1_operand" ""))
11500               (const_string "alu")
11501            ]
11502            (const_string "ishift")))
11503    (set_attr "mode" "SI")])
11504
11505 (define_expand "ashlhi3"
11506   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11507         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11508                    (match_operand:QI 2 "nonmemory_operand" "")))
11509    (clobber (reg:CC FLAGS_REG))]
11510   "TARGET_HIMODE_MATH"
11511   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11512
11513 (define_insn "*ashlhi3_1_lea"
11514   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11515         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11516                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11517    (clobber (reg:CC FLAGS_REG))]
11518   "!TARGET_PARTIAL_REG_STALL
11519    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11520 {
11521   switch (get_attr_type (insn))
11522     {
11523     case TYPE_LEA:
11524       return "#";
11525     case TYPE_ALU:
11526       gcc_assert (operands[2] == const1_rtx);
11527       return "add{w}\t%0, %0";
11528
11529     default:
11530       if (REG_P (operands[2]))
11531         return "sal{w}\t{%b2, %0|%0, %b2}";
11532       else if (operands[2] == const1_rtx
11533                && (TARGET_SHIFT1 || optimize_size))
11534         return "sal{w}\t%0";
11535       else
11536         return "sal{w}\t{%2, %0|%0, %2}";
11537     }
11538 }
11539   [(set (attr "type")
11540      (cond [(eq_attr "alternative" "1")
11541               (const_string "lea")
11542             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11543                           (const_int 0))
11544                       (match_operand 0 "register_operand" ""))
11545                  (match_operand 2 "const1_operand" ""))
11546               (const_string "alu")
11547            ]
11548            (const_string "ishift")))
11549    (set_attr "mode" "HI,SI")])
11550
11551 (define_insn "*ashlhi3_1"
11552   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11553         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11554                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11555    (clobber (reg:CC FLAGS_REG))]
11556   "TARGET_PARTIAL_REG_STALL
11557    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11558 {
11559   switch (get_attr_type (insn))
11560     {
11561     case TYPE_ALU:
11562       gcc_assert (operands[2] == const1_rtx);
11563       return "add{w}\t%0, %0";
11564
11565     default:
11566       if (REG_P (operands[2]))
11567         return "sal{w}\t{%b2, %0|%0, %b2}";
11568       else if (operands[2] == const1_rtx
11569                && (TARGET_SHIFT1 || optimize_size))
11570         return "sal{w}\t%0";
11571       else
11572         return "sal{w}\t{%2, %0|%0, %2}";
11573     }
11574 }
11575   [(set (attr "type")
11576      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11577                           (const_int 0))
11578                       (match_operand 0 "register_operand" ""))
11579                  (match_operand 2 "const1_operand" ""))
11580               (const_string "alu")
11581            ]
11582            (const_string "ishift")))
11583    (set_attr "mode" "HI")])
11584
11585 ;; This pattern can't accept a variable shift count, since shifts by
11586 ;; zero don't affect the flags.  We assume that shifts by constant
11587 ;; zero are optimized away.
11588 (define_insn "*ashlhi3_cmp"
11589   [(set (reg FLAGS_REG)
11590         (compare
11591           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11592                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11593           (const_int 0)))
11594    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11595         (ashift:HI (match_dup 1) (match_dup 2)))]
11596   "(optimize_size
11597     || !TARGET_PARTIAL_FLAG_REG_STALL
11598     || (operands[2] == const1_rtx
11599         && (TARGET_SHIFT1
11600             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11601    && ix86_match_ccmode (insn, CCGOCmode)
11602    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11603 {
11604   switch (get_attr_type (insn))
11605     {
11606     case TYPE_ALU:
11607       gcc_assert (operands[2] == const1_rtx);
11608       return "add{w}\t%0, %0";
11609
11610     default:
11611       if (REG_P (operands[2]))
11612         return "sal{w}\t{%b2, %0|%0, %b2}";
11613       else if (operands[2] == const1_rtx
11614                && (TARGET_SHIFT1 || optimize_size))
11615         return "sal{w}\t%0";
11616       else
11617         return "sal{w}\t{%2, %0|%0, %2}";
11618     }
11619 }
11620   [(set (attr "type")
11621      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11622                           (const_int 0))
11623                       (match_operand 0 "register_operand" ""))
11624                  (match_operand 2 "const1_operand" ""))
11625               (const_string "alu")
11626            ]
11627            (const_string "ishift")))
11628    (set_attr "mode" "HI")])
11629
11630 (define_insn "*ashlhi3_cconly"
11631   [(set (reg FLAGS_REG)
11632         (compare
11633           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11634                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11635           (const_int 0)))
11636    (clobber (match_scratch:HI 0 "=r"))]
11637   "(optimize_size
11638     || !TARGET_PARTIAL_FLAG_REG_STALL
11639     || (operands[2] == const1_rtx
11640         && (TARGET_SHIFT1
11641             || TARGET_DOUBLE_WITH_ADD)))
11642    && ix86_match_ccmode (insn, CCGOCmode)
11643    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11644 {
11645   switch (get_attr_type (insn))
11646     {
11647     case TYPE_ALU:
11648       gcc_assert (operands[2] == const1_rtx);
11649       return "add{w}\t%0, %0";
11650
11651     default:
11652       if (REG_P (operands[2]))
11653         return "sal{w}\t{%b2, %0|%0, %b2}";
11654       else if (operands[2] == const1_rtx
11655                && (TARGET_SHIFT1 || optimize_size))
11656         return "sal{w}\t%0";
11657       else
11658         return "sal{w}\t{%2, %0|%0, %2}";
11659     }
11660 }
11661   [(set (attr "type")
11662      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11663                           (const_int 0))
11664                       (match_operand 0 "register_operand" ""))
11665                  (match_operand 2 "const1_operand" ""))
11666               (const_string "alu")
11667            ]
11668            (const_string "ishift")))
11669    (set_attr "mode" "HI")])
11670
11671 (define_expand "ashlqi3"
11672   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11673         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11674                    (match_operand:QI 2 "nonmemory_operand" "")))
11675    (clobber (reg:CC FLAGS_REG))]
11676   "TARGET_QIMODE_MATH"
11677   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11678
11679 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11680
11681 (define_insn "*ashlqi3_1_lea"
11682   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11683         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11684                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11685    (clobber (reg:CC FLAGS_REG))]
11686   "!TARGET_PARTIAL_REG_STALL
11687    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11688 {
11689   switch (get_attr_type (insn))
11690     {
11691     case TYPE_LEA:
11692       return "#";
11693     case TYPE_ALU:
11694       gcc_assert (operands[2] == const1_rtx);
11695       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11696         return "add{l}\t%k0, %k0";
11697       else
11698         return "add{b}\t%0, %0";
11699
11700     default:
11701       if (REG_P (operands[2]))
11702         {
11703           if (get_attr_mode (insn) == MODE_SI)
11704             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11705           else
11706             return "sal{b}\t{%b2, %0|%0, %b2}";
11707         }
11708       else if (operands[2] == const1_rtx
11709                && (TARGET_SHIFT1 || optimize_size))
11710         {
11711           if (get_attr_mode (insn) == MODE_SI)
11712             return "sal{l}\t%0";
11713           else
11714             return "sal{b}\t%0";
11715         }
11716       else
11717         {
11718           if (get_attr_mode (insn) == MODE_SI)
11719             return "sal{l}\t{%2, %k0|%k0, %2}";
11720           else
11721             return "sal{b}\t{%2, %0|%0, %2}";
11722         }
11723     }
11724 }
11725   [(set (attr "type")
11726      (cond [(eq_attr "alternative" "2")
11727               (const_string "lea")
11728             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11729                           (const_int 0))
11730                       (match_operand 0 "register_operand" ""))
11731                  (match_operand 2 "const1_operand" ""))
11732               (const_string "alu")
11733            ]
11734            (const_string "ishift")))
11735    (set_attr "mode" "QI,SI,SI")])
11736
11737 (define_insn "*ashlqi3_1"
11738   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11739         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11740                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11741    (clobber (reg:CC FLAGS_REG))]
11742   "TARGET_PARTIAL_REG_STALL
11743    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11744 {
11745   switch (get_attr_type (insn))
11746     {
11747     case TYPE_ALU:
11748       gcc_assert (operands[2] == const1_rtx);
11749       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11750         return "add{l}\t%k0, %k0";
11751       else
11752         return "add{b}\t%0, %0";
11753
11754     default:
11755       if (REG_P (operands[2]))
11756         {
11757           if (get_attr_mode (insn) == MODE_SI)
11758             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11759           else
11760             return "sal{b}\t{%b2, %0|%0, %b2}";
11761         }
11762       else if (operands[2] == const1_rtx
11763                && (TARGET_SHIFT1 || optimize_size))
11764         {
11765           if (get_attr_mode (insn) == MODE_SI)
11766             return "sal{l}\t%0";
11767           else
11768             return "sal{b}\t%0";
11769         }
11770       else
11771         {
11772           if (get_attr_mode (insn) == MODE_SI)
11773             return "sal{l}\t{%2, %k0|%k0, %2}";
11774           else
11775             return "sal{b}\t{%2, %0|%0, %2}";
11776         }
11777     }
11778 }
11779   [(set (attr "type")
11780      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11781                           (const_int 0))
11782                       (match_operand 0 "register_operand" ""))
11783                  (match_operand 2 "const1_operand" ""))
11784               (const_string "alu")
11785            ]
11786            (const_string "ishift")))
11787    (set_attr "mode" "QI,SI")])
11788
11789 ;; This pattern can't accept a variable shift count, since shifts by
11790 ;; zero don't affect the flags.  We assume that shifts by constant
11791 ;; zero are optimized away.
11792 (define_insn "*ashlqi3_cmp"
11793   [(set (reg FLAGS_REG)
11794         (compare
11795           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11796                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11797           (const_int 0)))
11798    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11799         (ashift:QI (match_dup 1) (match_dup 2)))]
11800   "(optimize_size
11801     || !TARGET_PARTIAL_FLAG_REG_STALL
11802     || (operands[2] == const1_rtx
11803         && (TARGET_SHIFT1
11804             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11805    && ix86_match_ccmode (insn, CCGOCmode)
11806    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11807 {
11808   switch (get_attr_type (insn))
11809     {
11810     case TYPE_ALU:
11811       gcc_assert (operands[2] == const1_rtx);
11812       return "add{b}\t%0, %0";
11813
11814     default:
11815       if (REG_P (operands[2]))
11816         return "sal{b}\t{%b2, %0|%0, %b2}";
11817       else if (operands[2] == const1_rtx
11818                && (TARGET_SHIFT1 || optimize_size))
11819         return "sal{b}\t%0";
11820       else
11821         return "sal{b}\t{%2, %0|%0, %2}";
11822     }
11823 }
11824   [(set (attr "type")
11825      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11826                           (const_int 0))
11827                       (match_operand 0 "register_operand" ""))
11828                  (match_operand 2 "const1_operand" ""))
11829               (const_string "alu")
11830            ]
11831            (const_string "ishift")))
11832    (set_attr "mode" "QI")])
11833
11834 (define_insn "*ashlqi3_cconly"
11835   [(set (reg FLAGS_REG)
11836         (compare
11837           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11838                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11839           (const_int 0)))
11840    (clobber (match_scratch:QI 0 "=q"))]
11841   "(optimize_size
11842     || !TARGET_PARTIAL_FLAG_REG_STALL
11843     || (operands[2] == const1_rtx
11844         && (TARGET_SHIFT1
11845             || TARGET_DOUBLE_WITH_ADD)))
11846    && ix86_match_ccmode (insn, CCGOCmode)
11847    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11848 {
11849   switch (get_attr_type (insn))
11850     {
11851     case TYPE_ALU:
11852       gcc_assert (operands[2] == const1_rtx);
11853       return "add{b}\t%0, %0";
11854
11855     default:
11856       if (REG_P (operands[2]))
11857         return "sal{b}\t{%b2, %0|%0, %b2}";
11858       else if (operands[2] == const1_rtx
11859                && (TARGET_SHIFT1 || optimize_size))
11860         return "sal{b}\t%0";
11861       else
11862         return "sal{b}\t{%2, %0|%0, %2}";
11863     }
11864 }
11865   [(set (attr "type")
11866      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11867                           (const_int 0))
11868                       (match_operand 0 "register_operand" ""))
11869                  (match_operand 2 "const1_operand" ""))
11870               (const_string "alu")
11871            ]
11872            (const_string "ishift")))
11873    (set_attr "mode" "QI")])
11874
11875 ;; See comment above `ashldi3' about how this works.
11876
11877 (define_expand "ashrti3"
11878   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11879                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11880                                 (match_operand:QI 2 "nonmemory_operand" "")))
11881               (clobber (reg:CC FLAGS_REG))])]
11882   "TARGET_64BIT"
11883 {
11884   if (! immediate_operand (operands[2], QImode))
11885     {
11886       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11887       DONE;
11888     }
11889   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11890   DONE;
11891 })
11892
11893 (define_insn "ashrti3_1"
11894   [(set (match_operand:TI 0 "register_operand" "=r")
11895         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11896                      (match_operand:QI 2 "register_operand" "c")))
11897    (clobber (match_scratch:DI 3 "=&r"))
11898    (clobber (reg:CC FLAGS_REG))]
11899   "TARGET_64BIT"
11900   "#"
11901   [(set_attr "type" "multi")])
11902
11903 (define_insn "*ashrti3_2"
11904   [(set (match_operand:TI 0 "register_operand" "=r")
11905         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11906                      (match_operand:QI 2 "immediate_operand" "O")))
11907    (clobber (reg:CC FLAGS_REG))]
11908   "TARGET_64BIT"
11909   "#"
11910   [(set_attr "type" "multi")])
11911
11912 (define_split
11913   [(set (match_operand:TI 0 "register_operand" "")
11914         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11915                      (match_operand:QI 2 "register_operand" "")))
11916    (clobber (match_scratch:DI 3 ""))
11917    (clobber (reg:CC FLAGS_REG))]
11918   "TARGET_64BIT && reload_completed"
11919   [(const_int 0)]
11920   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11921
11922 (define_split
11923   [(set (match_operand:TI 0 "register_operand" "")
11924         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11925                      (match_operand:QI 2 "immediate_operand" "")))
11926    (clobber (reg:CC FLAGS_REG))]
11927   "TARGET_64BIT && reload_completed"
11928   [(const_int 0)]
11929   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11930
11931 (define_insn "x86_64_shrd"
11932   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11933         (ior:DI (ashiftrt:DI (match_dup 0)
11934                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11935                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11936                   (minus:QI (const_int 64) (match_dup 2)))))
11937    (clobber (reg:CC FLAGS_REG))]
11938   "TARGET_64BIT"
11939   "@
11940    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11941    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11942   [(set_attr "type" "ishift")
11943    (set_attr "prefix_0f" "1")
11944    (set_attr "mode" "DI")
11945    (set_attr "athlon_decode" "vector")
11946    (set_attr "amdfam10_decode" "vector")])
11947
11948 (define_expand "ashrdi3"
11949   [(set (match_operand:DI 0 "shiftdi_operand" "")
11950         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11951                      (match_operand:QI 2 "nonmemory_operand" "")))]
11952   ""
11953   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11954
11955 (define_insn "*ashrdi3_63_rex64"
11956   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11957         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11958                      (match_operand:DI 2 "const_int_operand" "i,i")))
11959    (clobber (reg:CC FLAGS_REG))]
11960   "TARGET_64BIT && INTVAL (operands[2]) == 63
11961    && (TARGET_USE_CLTD || optimize_size)
11962    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11963   "@
11964    {cqto|cqo}
11965    sar{q}\t{%2, %0|%0, %2}"
11966   [(set_attr "type" "imovx,ishift")
11967    (set_attr "prefix_0f" "0,*")
11968    (set_attr "length_immediate" "0,*")
11969    (set_attr "modrm" "0,1")
11970    (set_attr "mode" "DI")])
11971
11972 (define_insn "*ashrdi3_1_one_bit_rex64"
11973   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11974         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11975                      (match_operand:QI 2 "const1_operand" "")))
11976    (clobber (reg:CC FLAGS_REG))]
11977   "TARGET_64BIT
11978    && (TARGET_SHIFT1 || optimize_size)
11979    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11980   "sar{q}\t%0"
11981   [(set_attr "type" "ishift")
11982    (set (attr "length")
11983      (if_then_else (match_operand:DI 0 "register_operand" "")
11984         (const_string "2")
11985         (const_string "*")))])
11986
11987 (define_insn "*ashrdi3_1_rex64"
11988   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11989         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11990                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11991    (clobber (reg:CC FLAGS_REG))]
11992   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11993   "@
11994    sar{q}\t{%2, %0|%0, %2}
11995    sar{q}\t{%b2, %0|%0, %b2}"
11996   [(set_attr "type" "ishift")
11997    (set_attr "mode" "DI")])
11998
11999 ;; This pattern can't accept a variable shift count, since shifts by
12000 ;; zero don't affect the flags.  We assume that shifts by constant
12001 ;; zero are optimized away.
12002 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12003   [(set (reg FLAGS_REG)
12004         (compare
12005           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12006                        (match_operand:QI 2 "const1_operand" ""))
12007           (const_int 0)))
12008    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12009         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12010   "TARGET_64BIT
12011    && (TARGET_SHIFT1 || optimize_size)
12012    && ix86_match_ccmode (insn, CCGOCmode)
12013    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12014   "sar{q}\t%0"
12015   [(set_attr "type" "ishift")
12016    (set (attr "length")
12017      (if_then_else (match_operand:DI 0 "register_operand" "")
12018         (const_string "2")
12019         (const_string "*")))])
12020
12021 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12022   [(set (reg FLAGS_REG)
12023         (compare
12024           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12025                        (match_operand:QI 2 "const1_operand" ""))
12026           (const_int 0)))
12027    (clobber (match_scratch:DI 0 "=r"))]
12028   "TARGET_64BIT
12029    && (TARGET_SHIFT1 || optimize_size)
12030    && ix86_match_ccmode (insn, CCGOCmode)
12031    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12032   "sar{q}\t%0"
12033   [(set_attr "type" "ishift")
12034    (set_attr "length" "2")])
12035
12036 ;; This pattern can't accept a variable shift count, since shifts by
12037 ;; zero don't affect the flags.  We assume that shifts by constant
12038 ;; zero are optimized away.
12039 (define_insn "*ashrdi3_cmp_rex64"
12040   [(set (reg FLAGS_REG)
12041         (compare
12042           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12043                        (match_operand:QI 2 "const_int_operand" "n"))
12044           (const_int 0)))
12045    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12046         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12047   "TARGET_64BIT
12048    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12049    && ix86_match_ccmode (insn, CCGOCmode)
12050    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12051   "sar{q}\t{%2, %0|%0, %2}"
12052   [(set_attr "type" "ishift")
12053    (set_attr "mode" "DI")])
12054
12055 (define_insn "*ashrdi3_cconly_rex64"
12056   [(set (reg FLAGS_REG)
12057         (compare
12058           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12059                        (match_operand:QI 2 "const_int_operand" "n"))
12060           (const_int 0)))
12061    (clobber (match_scratch:DI 0 "=r"))]
12062   "TARGET_64BIT
12063    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12064    && ix86_match_ccmode (insn, CCGOCmode)
12065    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12066   "sar{q}\t{%2, %0|%0, %2}"
12067   [(set_attr "type" "ishift")
12068    (set_attr "mode" "DI")])
12069
12070 (define_insn "*ashrdi3_1"
12071   [(set (match_operand:DI 0 "register_operand" "=r")
12072         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12073                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12074    (clobber (reg:CC FLAGS_REG))]
12075   "!TARGET_64BIT"
12076   "#"
12077   [(set_attr "type" "multi")])
12078
12079 ;; By default we don't ask for a scratch register, because when DImode
12080 ;; values are manipulated, registers are already at a premium.  But if
12081 ;; we have one handy, we won't turn it away.
12082 (define_peephole2
12083   [(match_scratch:SI 3 "r")
12084    (parallel [(set (match_operand:DI 0 "register_operand" "")
12085                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12086                                 (match_operand:QI 2 "nonmemory_operand" "")))
12087               (clobber (reg:CC FLAGS_REG))])
12088    (match_dup 3)]
12089   "!TARGET_64BIT && TARGET_CMOVE"
12090   [(const_int 0)]
12091   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12092
12093 (define_split
12094   [(set (match_operand:DI 0 "register_operand" "")
12095         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12096                      (match_operand:QI 2 "nonmemory_operand" "")))
12097    (clobber (reg:CC FLAGS_REG))]
12098   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12099                      ? epilogue_completed : reload_completed)"
12100   [(const_int 0)]
12101   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12102
12103 (define_insn "x86_shrd_1"
12104   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
12105         (ior:SI (ashiftrt:SI (match_dup 0)
12106                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
12107                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
12108                   (minus:QI (const_int 32) (match_dup 2)))))
12109    (clobber (reg:CC FLAGS_REG))]
12110   ""
12111   "@
12112    shrd{l}\t{%2, %1, %0|%0, %1, %2}
12113    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12114   [(set_attr "type" "ishift")
12115    (set_attr "prefix_0f" "1")
12116    (set_attr "pent_pair" "np")
12117    (set_attr "mode" "SI")])
12118
12119 (define_expand "x86_shift_adj_3"
12120   [(use (match_operand:SI 0 "register_operand" ""))
12121    (use (match_operand:SI 1 "register_operand" ""))
12122    (use (match_operand:QI 2 "register_operand" ""))]
12123   ""
12124 {
12125   rtx label = gen_label_rtx ();
12126   rtx tmp;
12127
12128   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12129
12130   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12131   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12132   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12133                               gen_rtx_LABEL_REF (VOIDmode, label),
12134                               pc_rtx);
12135   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12136   JUMP_LABEL (tmp) = label;
12137
12138   emit_move_insn (operands[0], operands[1]);
12139   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12140
12141   emit_label (label);
12142   LABEL_NUSES (label) = 1;
12143
12144   DONE;
12145 })
12146
12147 (define_insn "ashrsi3_31"
12148   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12149         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12150                      (match_operand:SI 2 "const_int_operand" "i,i")))
12151    (clobber (reg:CC FLAGS_REG))]
12152   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12153    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12154   "@
12155    {cltd|cdq}
12156    sar{l}\t{%2, %0|%0, %2}"
12157   [(set_attr "type" "imovx,ishift")
12158    (set_attr "prefix_0f" "0,*")
12159    (set_attr "length_immediate" "0,*")
12160    (set_attr "modrm" "0,1")
12161    (set_attr "mode" "SI")])
12162
12163 (define_insn "*ashrsi3_31_zext"
12164   [(set (match_operand:DI 0 "register_operand" "=*d,r")
12165         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12166                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
12167    (clobber (reg:CC FLAGS_REG))]
12168   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12169    && INTVAL (operands[2]) == 31
12170    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12171   "@
12172    {cltd|cdq}
12173    sar{l}\t{%2, %k0|%k0, %2}"
12174   [(set_attr "type" "imovx,ishift")
12175    (set_attr "prefix_0f" "0,*")
12176    (set_attr "length_immediate" "0,*")
12177    (set_attr "modrm" "0,1")
12178    (set_attr "mode" "SI")])
12179
12180 (define_expand "ashrsi3"
12181   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12182         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12183                      (match_operand:QI 2 "nonmemory_operand" "")))
12184    (clobber (reg:CC FLAGS_REG))]
12185   ""
12186   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12187
12188 (define_insn "*ashrsi3_1_one_bit"
12189   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12190         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12191                      (match_operand:QI 2 "const1_operand" "")))
12192    (clobber (reg:CC FLAGS_REG))]
12193   "(TARGET_SHIFT1 || optimize_size)
12194    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12195   "sar{l}\t%0"
12196   [(set_attr "type" "ishift")
12197    (set (attr "length")
12198      (if_then_else (match_operand:SI 0 "register_operand" "")
12199         (const_string "2")
12200         (const_string "*")))])
12201
12202 (define_insn "*ashrsi3_1_one_bit_zext"
12203   [(set (match_operand:DI 0 "register_operand" "=r")
12204         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12205                                      (match_operand:QI 2 "const1_operand" ""))))
12206    (clobber (reg:CC FLAGS_REG))]
12207   "TARGET_64BIT
12208    && (TARGET_SHIFT1 || optimize_size)
12209    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12210   "sar{l}\t%k0"
12211   [(set_attr "type" "ishift")
12212    (set_attr "length" "2")])
12213
12214 (define_insn "*ashrsi3_1"
12215   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12216         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12217                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12218    (clobber (reg:CC FLAGS_REG))]
12219   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12220   "@
12221    sar{l}\t{%2, %0|%0, %2}
12222    sar{l}\t{%b2, %0|%0, %b2}"
12223   [(set_attr "type" "ishift")
12224    (set_attr "mode" "SI")])
12225
12226 (define_insn "*ashrsi3_1_zext"
12227   [(set (match_operand:DI 0 "register_operand" "=r,r")
12228         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12229                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12230    (clobber (reg:CC FLAGS_REG))]
12231   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12232   "@
12233    sar{l}\t{%2, %k0|%k0, %2}
12234    sar{l}\t{%b2, %k0|%k0, %b2}"
12235   [(set_attr "type" "ishift")
12236    (set_attr "mode" "SI")])
12237
12238 ;; This pattern can't accept a variable shift count, since shifts by
12239 ;; zero don't affect the flags.  We assume that shifts by constant
12240 ;; zero are optimized away.
12241 (define_insn "*ashrsi3_one_bit_cmp"
12242   [(set (reg FLAGS_REG)
12243         (compare
12244           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12245                        (match_operand:QI 2 "const1_operand" ""))
12246           (const_int 0)))
12247    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12248         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12249   "(TARGET_SHIFT1 || optimize_size)
12250    && ix86_match_ccmode (insn, CCGOCmode)
12251    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12252   "sar{l}\t%0"
12253   [(set_attr "type" "ishift")
12254    (set (attr "length")
12255      (if_then_else (match_operand:SI 0 "register_operand" "")
12256         (const_string "2")
12257         (const_string "*")))])
12258
12259 (define_insn "*ashrsi3_one_bit_cconly"
12260   [(set (reg FLAGS_REG)
12261         (compare
12262           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12263                        (match_operand:QI 2 "const1_operand" ""))
12264           (const_int 0)))
12265    (clobber (match_scratch:SI 0 "=r"))]
12266   "(TARGET_SHIFT1 || optimize_size)
12267    && ix86_match_ccmode (insn, CCGOCmode)
12268    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12269   "sar{l}\t%0"
12270   [(set_attr "type" "ishift")
12271    (set_attr "length" "2")])
12272
12273 (define_insn "*ashrsi3_one_bit_cmp_zext"
12274   [(set (reg FLAGS_REG)
12275         (compare
12276           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12277                        (match_operand:QI 2 "const1_operand" ""))
12278           (const_int 0)))
12279    (set (match_operand:DI 0 "register_operand" "=r")
12280         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12281   "TARGET_64BIT
12282    && (TARGET_SHIFT1 || optimize_size)
12283    && ix86_match_ccmode (insn, CCmode)
12284    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12285   "sar{l}\t%k0"
12286   [(set_attr "type" "ishift")
12287    (set_attr "length" "2")])
12288
12289 ;; This pattern can't accept a variable shift count, since shifts by
12290 ;; zero don't affect the flags.  We assume that shifts by constant
12291 ;; zero are optimized away.
12292 (define_insn "*ashrsi3_cmp"
12293   [(set (reg FLAGS_REG)
12294         (compare
12295           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12296                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12297           (const_int 0)))
12298    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12299         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12300   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12301    && ix86_match_ccmode (insn, CCGOCmode)
12302    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12303   "sar{l}\t{%2, %0|%0, %2}"
12304   [(set_attr "type" "ishift")
12305    (set_attr "mode" "SI")])
12306
12307 (define_insn "*ashrsi3_cconly"
12308   [(set (reg FLAGS_REG)
12309         (compare
12310           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12311                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12312           (const_int 0)))
12313    (clobber (match_scratch:SI 0 "=r"))]
12314   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12315    && ix86_match_ccmode (insn, CCGOCmode)
12316    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12317   "sar{l}\t{%2, %0|%0, %2}"
12318   [(set_attr "type" "ishift")
12319    (set_attr "mode" "SI")])
12320
12321 (define_insn "*ashrsi3_cmp_zext"
12322   [(set (reg FLAGS_REG)
12323         (compare
12324           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12325                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12326           (const_int 0)))
12327    (set (match_operand:DI 0 "register_operand" "=r")
12328         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12329   "TARGET_64BIT
12330    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12331    && ix86_match_ccmode (insn, CCGOCmode)
12332    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12333   "sar{l}\t{%2, %k0|%k0, %2}"
12334   [(set_attr "type" "ishift")
12335    (set_attr "mode" "SI")])
12336
12337 (define_expand "ashrhi3"
12338   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12339         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12340                      (match_operand:QI 2 "nonmemory_operand" "")))
12341    (clobber (reg:CC FLAGS_REG))]
12342   "TARGET_HIMODE_MATH"
12343   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12344
12345 (define_insn "*ashrhi3_1_one_bit"
12346   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12347         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12348                      (match_operand:QI 2 "const1_operand" "")))
12349    (clobber (reg:CC FLAGS_REG))]
12350   "(TARGET_SHIFT1 || optimize_size)
12351    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12352   "sar{w}\t%0"
12353   [(set_attr "type" "ishift")
12354    (set (attr "length")
12355      (if_then_else (match_operand 0 "register_operand" "")
12356         (const_string "2")
12357         (const_string "*")))])
12358
12359 (define_insn "*ashrhi3_1"
12360   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12361         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12362                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12363    (clobber (reg:CC FLAGS_REG))]
12364   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12365   "@
12366    sar{w}\t{%2, %0|%0, %2}
12367    sar{w}\t{%b2, %0|%0, %b2}"
12368   [(set_attr "type" "ishift")
12369    (set_attr "mode" "HI")])
12370
12371 ;; This pattern can't accept a variable shift count, since shifts by
12372 ;; zero don't affect the flags.  We assume that shifts by constant
12373 ;; zero are optimized away.
12374 (define_insn "*ashrhi3_one_bit_cmp"
12375   [(set (reg FLAGS_REG)
12376         (compare
12377           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12378                        (match_operand:QI 2 "const1_operand" ""))
12379           (const_int 0)))
12380    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12381         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12382   "(TARGET_SHIFT1 || optimize_size)
12383    && ix86_match_ccmode (insn, CCGOCmode)
12384    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12385   "sar{w}\t%0"
12386   [(set_attr "type" "ishift")
12387    (set (attr "length")
12388      (if_then_else (match_operand 0 "register_operand" "")
12389         (const_string "2")
12390         (const_string "*")))])
12391
12392 (define_insn "*ashrhi3_one_bit_cconly"
12393   [(set (reg FLAGS_REG)
12394         (compare
12395           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12396                        (match_operand:QI 2 "const1_operand" ""))
12397           (const_int 0)))
12398    (clobber (match_scratch:HI 0 "=r"))]
12399   "(TARGET_SHIFT1 || optimize_size)
12400    && ix86_match_ccmode (insn, CCGOCmode)
12401    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12402   "sar{w}\t%0"
12403   [(set_attr "type" "ishift")
12404    (set_attr "length" "2")])
12405
12406 ;; This pattern can't accept a variable shift count, since shifts by
12407 ;; zero don't affect the flags.  We assume that shifts by constant
12408 ;; zero are optimized away.
12409 (define_insn "*ashrhi3_cmp"
12410   [(set (reg FLAGS_REG)
12411         (compare
12412           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12413                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12414           (const_int 0)))
12415    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12416         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12417   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12418    && ix86_match_ccmode (insn, CCGOCmode)
12419    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12420   "sar{w}\t{%2, %0|%0, %2}"
12421   [(set_attr "type" "ishift")
12422    (set_attr "mode" "HI")])
12423
12424 (define_insn "*ashrhi3_cconly"
12425   [(set (reg FLAGS_REG)
12426         (compare
12427           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12428                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12429           (const_int 0)))
12430    (clobber (match_scratch:HI 0 "=r"))]
12431   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12432    && ix86_match_ccmode (insn, CCGOCmode)
12433    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12434   "sar{w}\t{%2, %0|%0, %2}"
12435   [(set_attr "type" "ishift")
12436    (set_attr "mode" "HI")])
12437
12438 (define_expand "ashrqi3"
12439   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12440         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12441                      (match_operand:QI 2 "nonmemory_operand" "")))
12442    (clobber (reg:CC FLAGS_REG))]
12443   "TARGET_QIMODE_MATH"
12444   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12445
12446 (define_insn "*ashrqi3_1_one_bit"
12447   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12448         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12449                      (match_operand:QI 2 "const1_operand" "")))
12450    (clobber (reg:CC FLAGS_REG))]
12451   "(TARGET_SHIFT1 || optimize_size)
12452    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12453   "sar{b}\t%0"
12454   [(set_attr "type" "ishift")
12455    (set (attr "length")
12456      (if_then_else (match_operand 0 "register_operand" "")
12457         (const_string "2")
12458         (const_string "*")))])
12459
12460 (define_insn "*ashrqi3_1_one_bit_slp"
12461   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12462         (ashiftrt:QI (match_dup 0)
12463                      (match_operand:QI 1 "const1_operand" "")))
12464    (clobber (reg:CC FLAGS_REG))]
12465   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12466    && (TARGET_SHIFT1 || optimize_size)
12467    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12468   "sar{b}\t%0"
12469   [(set_attr "type" "ishift1")
12470    (set (attr "length")
12471      (if_then_else (match_operand 0 "register_operand" "")
12472         (const_string "2")
12473         (const_string "*")))])
12474
12475 (define_insn "*ashrqi3_1"
12476   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12477         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12478                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12479    (clobber (reg:CC FLAGS_REG))]
12480   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12481   "@
12482    sar{b}\t{%2, %0|%0, %2}
12483    sar{b}\t{%b2, %0|%0, %b2}"
12484   [(set_attr "type" "ishift")
12485    (set_attr "mode" "QI")])
12486
12487 (define_insn "*ashrqi3_1_slp"
12488   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12489         (ashiftrt:QI (match_dup 0)
12490                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12491    (clobber (reg:CC FLAGS_REG))]
12492   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12493    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12494   "@
12495    sar{b}\t{%1, %0|%0, %1}
12496    sar{b}\t{%b1, %0|%0, %b1}"
12497   [(set_attr "type" "ishift1")
12498    (set_attr "mode" "QI")])
12499
12500 ;; This pattern can't accept a variable shift count, since shifts by
12501 ;; zero don't affect the flags.  We assume that shifts by constant
12502 ;; zero are optimized away.
12503 (define_insn "*ashrqi3_one_bit_cmp"
12504   [(set (reg FLAGS_REG)
12505         (compare
12506           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12507                        (match_operand:QI 2 "const1_operand" "I"))
12508           (const_int 0)))
12509    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12510         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12511   "(TARGET_SHIFT1 || optimize_size)
12512    && ix86_match_ccmode (insn, CCGOCmode)
12513    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12514   "sar{b}\t%0"
12515   [(set_attr "type" "ishift")
12516    (set (attr "length")
12517      (if_then_else (match_operand 0 "register_operand" "")
12518         (const_string "2")
12519         (const_string "*")))])
12520
12521 (define_insn "*ashrqi3_one_bit_cconly"
12522   [(set (reg FLAGS_REG)
12523         (compare
12524           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12525                        (match_operand:QI 2 "const1_operand" "I"))
12526           (const_int 0)))
12527    (clobber (match_scratch:QI 0 "=q"))]
12528   "(TARGET_SHIFT1 || optimize_size)
12529    && ix86_match_ccmode (insn, CCGOCmode)
12530    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12531   "sar{b}\t%0"
12532   [(set_attr "type" "ishift")
12533    (set_attr "length" "2")])
12534
12535 ;; This pattern can't accept a variable shift count, since shifts by
12536 ;; zero don't affect the flags.  We assume that shifts by constant
12537 ;; zero are optimized away.
12538 (define_insn "*ashrqi3_cmp"
12539   [(set (reg FLAGS_REG)
12540         (compare
12541           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12542                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12543           (const_int 0)))
12544    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12545         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12546   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12547    && ix86_match_ccmode (insn, CCGOCmode)
12548    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12549   "sar{b}\t{%2, %0|%0, %2}"
12550   [(set_attr "type" "ishift")
12551    (set_attr "mode" "QI")])
12552
12553 (define_insn "*ashrqi3_cconly"
12554   [(set (reg FLAGS_REG)
12555         (compare
12556           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12557                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12558           (const_int 0)))
12559    (clobber (match_scratch:QI 0 "=q"))]
12560   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12561    && ix86_match_ccmode (insn, CCGOCmode)
12562    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12563   "sar{b}\t{%2, %0|%0, %2}"
12564   [(set_attr "type" "ishift")
12565    (set_attr "mode" "QI")])
12566
12567 \f
12568 ;; Logical shift instructions
12569
12570 ;; See comment above `ashldi3' about how this works.
12571
12572 (define_expand "lshrti3"
12573   [(parallel [(set (match_operand:TI 0 "register_operand" "")
12574                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12575                                 (match_operand:QI 2 "nonmemory_operand" "")))
12576               (clobber (reg:CC FLAGS_REG))])]
12577   "TARGET_64BIT"
12578 {
12579   if (! immediate_operand (operands[2], QImode))
12580     {
12581       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12582       DONE;
12583     }
12584   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12585   DONE;
12586 })
12587
12588 (define_insn "lshrti3_1"
12589   [(set (match_operand:TI 0 "register_operand" "=r")
12590         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12591                      (match_operand:QI 2 "register_operand" "c")))
12592    (clobber (match_scratch:DI 3 "=&r"))
12593    (clobber (reg:CC FLAGS_REG))]
12594   "TARGET_64BIT"
12595   "#"
12596   [(set_attr "type" "multi")])
12597
12598 ;; This pattern must be defined before *lshrti3_2 to prevent
12599 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12600
12601 (define_insn "sse2_lshrti3"
12602   [(set (match_operand:TI 0 "register_operand" "=x")
12603         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12604                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12605   "TARGET_SSE2"
12606 {
12607   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12608   return "psrldq\t{%2, %0|%0, %2}";
12609 }
12610   [(set_attr "type" "sseishft")
12611    (set_attr "prefix_data16" "1")
12612    (set_attr "mode" "TI")])
12613
12614 (define_insn "*lshrti3_2"
12615   [(set (match_operand:TI 0 "register_operand" "=r")
12616         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12617                      (match_operand:QI 2 "immediate_operand" "O")))
12618    (clobber (reg:CC FLAGS_REG))]
12619   "TARGET_64BIT"
12620   "#"
12621   [(set_attr "type" "multi")])
12622
12623 (define_split
12624   [(set (match_operand:TI 0 "register_operand" "")
12625         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12626                      (match_operand:QI 2 "register_operand" "")))
12627    (clobber (match_scratch:DI 3 ""))
12628    (clobber (reg:CC FLAGS_REG))]
12629   "TARGET_64BIT && reload_completed"
12630   [(const_int 0)]
12631   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12632
12633 (define_split
12634   [(set (match_operand:TI 0 "register_operand" "")
12635         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12636                      (match_operand:QI 2 "immediate_operand" "")))
12637    (clobber (reg:CC FLAGS_REG))]
12638   "TARGET_64BIT && reload_completed"
12639   [(const_int 0)]
12640   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12641
12642 (define_expand "lshrdi3"
12643   [(set (match_operand:DI 0 "shiftdi_operand" "")
12644         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12645                      (match_operand:QI 2 "nonmemory_operand" "")))]
12646   ""
12647   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12648
12649 (define_insn "*lshrdi3_1_one_bit_rex64"
12650   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12651         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12652                      (match_operand:QI 2 "const1_operand" "")))
12653    (clobber (reg:CC FLAGS_REG))]
12654   "TARGET_64BIT
12655    && (TARGET_SHIFT1 || optimize_size)
12656    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12657   "shr{q}\t%0"
12658   [(set_attr "type" "ishift")
12659    (set (attr "length")
12660      (if_then_else (match_operand:DI 0 "register_operand" "")
12661         (const_string "2")
12662         (const_string "*")))])
12663
12664 (define_insn "*lshrdi3_1_rex64"
12665   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12666         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12667                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12668    (clobber (reg:CC FLAGS_REG))]
12669   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12670   "@
12671    shr{q}\t{%2, %0|%0, %2}
12672    shr{q}\t{%b2, %0|%0, %b2}"
12673   [(set_attr "type" "ishift")
12674    (set_attr "mode" "DI")])
12675
12676 ;; This pattern can't accept a variable shift count, since shifts by
12677 ;; zero don't affect the flags.  We assume that shifts by constant
12678 ;; zero are optimized away.
12679 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12680   [(set (reg FLAGS_REG)
12681         (compare
12682           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12683                        (match_operand:QI 2 "const1_operand" ""))
12684           (const_int 0)))
12685    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12686         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12687   "TARGET_64BIT
12688    && (TARGET_SHIFT1 || optimize_size)
12689    && ix86_match_ccmode (insn, CCGOCmode)
12690    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12691   "shr{q}\t%0"
12692   [(set_attr "type" "ishift")
12693    (set (attr "length")
12694      (if_then_else (match_operand:DI 0 "register_operand" "")
12695         (const_string "2")
12696         (const_string "*")))])
12697
12698 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12699   [(set (reg FLAGS_REG)
12700         (compare
12701           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12702                        (match_operand:QI 2 "const1_operand" ""))
12703           (const_int 0)))
12704    (clobber (match_scratch:DI 0 "=r"))]
12705   "TARGET_64BIT
12706    && (TARGET_SHIFT1 || optimize_size)
12707    && ix86_match_ccmode (insn, CCGOCmode)
12708    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12709   "shr{q}\t%0"
12710   [(set_attr "type" "ishift")
12711    (set_attr "length" "2")])
12712
12713 ;; This pattern can't accept a variable shift count, since shifts by
12714 ;; zero don't affect the flags.  We assume that shifts by constant
12715 ;; zero are optimized away.
12716 (define_insn "*lshrdi3_cmp_rex64"
12717   [(set (reg FLAGS_REG)
12718         (compare
12719           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12720                        (match_operand:QI 2 "const_int_operand" "e"))
12721           (const_int 0)))
12722    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12723         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12724   "TARGET_64BIT
12725    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12726    && ix86_match_ccmode (insn, CCGOCmode)
12727    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12728   "shr{q}\t{%2, %0|%0, %2}"
12729   [(set_attr "type" "ishift")
12730    (set_attr "mode" "DI")])
12731
12732 (define_insn "*lshrdi3_cconly_rex64"
12733   [(set (reg FLAGS_REG)
12734         (compare
12735           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12736                        (match_operand:QI 2 "const_int_operand" "e"))
12737           (const_int 0)))
12738    (clobber (match_scratch:DI 0 "=r"))]
12739   "TARGET_64BIT
12740    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12741    && ix86_match_ccmode (insn, CCGOCmode)
12742    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12743   "shr{q}\t{%2, %0|%0, %2}"
12744   [(set_attr "type" "ishift")
12745    (set_attr "mode" "DI")])
12746
12747 (define_insn "*lshrdi3_1"
12748   [(set (match_operand:DI 0 "register_operand" "=r")
12749         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12750                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12751    (clobber (reg:CC FLAGS_REG))]
12752   "!TARGET_64BIT"
12753   "#"
12754   [(set_attr "type" "multi")])
12755
12756 ;; By default we don't ask for a scratch register, because when DImode
12757 ;; values are manipulated, registers are already at a premium.  But if
12758 ;; we have one handy, we won't turn it away.
12759 (define_peephole2
12760   [(match_scratch:SI 3 "r")
12761    (parallel [(set (match_operand:DI 0 "register_operand" "")
12762                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12763                                 (match_operand:QI 2 "nonmemory_operand" "")))
12764               (clobber (reg:CC FLAGS_REG))])
12765    (match_dup 3)]
12766   "!TARGET_64BIT && TARGET_CMOVE"
12767   [(const_int 0)]
12768   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12769
12770 (define_split
12771   [(set (match_operand:DI 0 "register_operand" "")
12772         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12773                      (match_operand:QI 2 "nonmemory_operand" "")))
12774    (clobber (reg:CC FLAGS_REG))]
12775   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12776                      ? epilogue_completed : reload_completed)"
12777   [(const_int 0)]
12778   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12779
12780 (define_expand "lshrsi3"
12781   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12782         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12783                      (match_operand:QI 2 "nonmemory_operand" "")))
12784    (clobber (reg:CC FLAGS_REG))]
12785   ""
12786   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12787
12788 (define_insn "*lshrsi3_1_one_bit"
12789   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12790         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12791                      (match_operand:QI 2 "const1_operand" "")))
12792    (clobber (reg:CC FLAGS_REG))]
12793   "(TARGET_SHIFT1 || optimize_size)
12794    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12795   "shr{l}\t%0"
12796   [(set_attr "type" "ishift")
12797    (set (attr "length")
12798      (if_then_else (match_operand:SI 0 "register_operand" "")
12799         (const_string "2")
12800         (const_string "*")))])
12801
12802 (define_insn "*lshrsi3_1_one_bit_zext"
12803   [(set (match_operand:DI 0 "register_operand" "=r")
12804         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12805                      (match_operand:QI 2 "const1_operand" "")))
12806    (clobber (reg:CC FLAGS_REG))]
12807   "TARGET_64BIT
12808    && (TARGET_SHIFT1 || optimize_size)
12809    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12810   "shr{l}\t%k0"
12811   [(set_attr "type" "ishift")
12812    (set_attr "length" "2")])
12813
12814 (define_insn "*lshrsi3_1"
12815   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12816         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12817                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12818    (clobber (reg:CC FLAGS_REG))]
12819   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12820   "@
12821    shr{l}\t{%2, %0|%0, %2}
12822    shr{l}\t{%b2, %0|%0, %b2}"
12823   [(set_attr "type" "ishift")
12824    (set_attr "mode" "SI")])
12825
12826 (define_insn "*lshrsi3_1_zext"
12827   [(set (match_operand:DI 0 "register_operand" "=r,r")
12828         (zero_extend:DI
12829           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12830                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12831    (clobber (reg:CC FLAGS_REG))]
12832   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12833   "@
12834    shr{l}\t{%2, %k0|%k0, %2}
12835    shr{l}\t{%b2, %k0|%k0, %b2}"
12836   [(set_attr "type" "ishift")
12837    (set_attr "mode" "SI")])
12838
12839 ;; This pattern can't accept a variable shift count, since shifts by
12840 ;; zero don't affect the flags.  We assume that shifts by constant
12841 ;; zero are optimized away.
12842 (define_insn "*lshrsi3_one_bit_cmp"
12843   [(set (reg FLAGS_REG)
12844         (compare
12845           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12846                        (match_operand:QI 2 "const1_operand" ""))
12847           (const_int 0)))
12848    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12849         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12850   "(TARGET_SHIFT1 || optimize_size)
12851    && ix86_match_ccmode (insn, CCGOCmode)
12852    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12853   "shr{l}\t%0"
12854   [(set_attr "type" "ishift")
12855    (set (attr "length")
12856      (if_then_else (match_operand:SI 0 "register_operand" "")
12857         (const_string "2")
12858         (const_string "*")))])
12859
12860 (define_insn "*lshrsi3_one_bit_cconly"
12861   [(set (reg FLAGS_REG)
12862         (compare
12863           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12864                        (match_operand:QI 2 "const1_operand" ""))
12865           (const_int 0)))
12866    (clobber (match_scratch:SI 0 "=r"))]
12867   "(TARGET_SHIFT1 || optimize_size)
12868    && ix86_match_ccmode (insn, CCGOCmode)
12869    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12870   "shr{l}\t%0"
12871   [(set_attr "type" "ishift")
12872    (set_attr "length" "2")])
12873
12874 (define_insn "*lshrsi3_cmp_one_bit_zext"
12875   [(set (reg FLAGS_REG)
12876         (compare
12877           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12878                        (match_operand:QI 2 "const1_operand" ""))
12879           (const_int 0)))
12880    (set (match_operand:DI 0 "register_operand" "=r")
12881         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12882   "TARGET_64BIT
12883    && (TARGET_SHIFT1 || optimize_size)
12884    && ix86_match_ccmode (insn, CCGOCmode)
12885    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12886   "shr{l}\t%k0"
12887   [(set_attr "type" "ishift")
12888    (set_attr "length" "2")])
12889
12890 ;; This pattern can't accept a variable shift count, since shifts by
12891 ;; zero don't affect the flags.  We assume that shifts by constant
12892 ;; zero are optimized away.
12893 (define_insn "*lshrsi3_cmp"
12894   [(set (reg FLAGS_REG)
12895         (compare
12896           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12897                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12898           (const_int 0)))
12899    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12900         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12901   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12902    && ix86_match_ccmode (insn, CCGOCmode)
12903    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12904   "shr{l}\t{%2, %0|%0, %2}"
12905   [(set_attr "type" "ishift")
12906    (set_attr "mode" "SI")])
12907
12908 (define_insn "*lshrsi3_cconly"
12909   [(set (reg FLAGS_REG)
12910       (compare
12911         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12912                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12913         (const_int 0)))
12914    (clobber (match_scratch:SI 0 "=r"))]
12915   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12916    && ix86_match_ccmode (insn, CCGOCmode)
12917    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12918   "shr{l}\t{%2, %0|%0, %2}"
12919   [(set_attr "type" "ishift")
12920    (set_attr "mode" "SI")])
12921
12922 (define_insn "*lshrsi3_cmp_zext"
12923   [(set (reg FLAGS_REG)
12924         (compare
12925           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12926                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12927           (const_int 0)))
12928    (set (match_operand:DI 0 "register_operand" "=r")
12929         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12930   "TARGET_64BIT
12931    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12932    && ix86_match_ccmode (insn, CCGOCmode)
12933    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12934   "shr{l}\t{%2, %k0|%k0, %2}"
12935   [(set_attr "type" "ishift")
12936    (set_attr "mode" "SI")])
12937
12938 (define_expand "lshrhi3"
12939   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12940         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12941                      (match_operand:QI 2 "nonmemory_operand" "")))
12942    (clobber (reg:CC FLAGS_REG))]
12943   "TARGET_HIMODE_MATH"
12944   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12945
12946 (define_insn "*lshrhi3_1_one_bit"
12947   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12948         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12949                      (match_operand:QI 2 "const1_operand" "")))
12950    (clobber (reg:CC FLAGS_REG))]
12951   "(TARGET_SHIFT1 || optimize_size)
12952    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12953   "shr{w}\t%0"
12954   [(set_attr "type" "ishift")
12955    (set (attr "length")
12956      (if_then_else (match_operand 0 "register_operand" "")
12957         (const_string "2")
12958         (const_string "*")))])
12959
12960 (define_insn "*lshrhi3_1"
12961   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12962         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12963                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12964    (clobber (reg:CC FLAGS_REG))]
12965   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12966   "@
12967    shr{w}\t{%2, %0|%0, %2}
12968    shr{w}\t{%b2, %0|%0, %b2}"
12969   [(set_attr "type" "ishift")
12970    (set_attr "mode" "HI")])
12971
12972 ;; This pattern can't accept a variable shift count, since shifts by
12973 ;; zero don't affect the flags.  We assume that shifts by constant
12974 ;; zero are optimized away.
12975 (define_insn "*lshrhi3_one_bit_cmp"
12976   [(set (reg FLAGS_REG)
12977         (compare
12978           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12979                        (match_operand:QI 2 "const1_operand" ""))
12980           (const_int 0)))
12981    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12982         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12983   "(TARGET_SHIFT1 || optimize_size)
12984    && ix86_match_ccmode (insn, CCGOCmode)
12985    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12986   "shr{w}\t%0"
12987   [(set_attr "type" "ishift")
12988    (set (attr "length")
12989      (if_then_else (match_operand:SI 0 "register_operand" "")
12990         (const_string "2")
12991         (const_string "*")))])
12992
12993 (define_insn "*lshrhi3_one_bit_cconly"
12994   [(set (reg FLAGS_REG)
12995         (compare
12996           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12997                        (match_operand:QI 2 "const1_operand" ""))
12998           (const_int 0)))
12999    (clobber (match_scratch:HI 0 "=r"))]
13000   "(TARGET_SHIFT1 || optimize_size)
13001    && ix86_match_ccmode (insn, CCGOCmode)
13002    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13003   "shr{w}\t%0"
13004   [(set_attr "type" "ishift")
13005    (set_attr "length" "2")])
13006
13007 ;; This pattern can't accept a variable shift count, since shifts by
13008 ;; zero don't affect the flags.  We assume that shifts by constant
13009 ;; zero are optimized away.
13010 (define_insn "*lshrhi3_cmp"
13011   [(set (reg FLAGS_REG)
13012         (compare
13013           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13014                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13015           (const_int 0)))
13016    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13017         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13018   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13019    && ix86_match_ccmode (insn, CCGOCmode)
13020    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13021   "shr{w}\t{%2, %0|%0, %2}"
13022   [(set_attr "type" "ishift")
13023    (set_attr "mode" "HI")])
13024
13025 (define_insn "*lshrhi3_cconly"
13026   [(set (reg FLAGS_REG)
13027         (compare
13028           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13029                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13030           (const_int 0)))
13031    (clobber (match_scratch:HI 0 "=r"))]
13032   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13033    && ix86_match_ccmode (insn, CCGOCmode)
13034    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13035   "shr{w}\t{%2, %0|%0, %2}"
13036   [(set_attr "type" "ishift")
13037    (set_attr "mode" "HI")])
13038
13039 (define_expand "lshrqi3"
13040   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13041         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13042                      (match_operand:QI 2 "nonmemory_operand" "")))
13043    (clobber (reg:CC FLAGS_REG))]
13044   "TARGET_QIMODE_MATH"
13045   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13046
13047 (define_insn "*lshrqi3_1_one_bit"
13048   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13049         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13050                      (match_operand:QI 2 "const1_operand" "")))
13051    (clobber (reg:CC FLAGS_REG))]
13052   "(TARGET_SHIFT1 || optimize_size)
13053    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13054   "shr{b}\t%0"
13055   [(set_attr "type" "ishift")
13056    (set (attr "length")
13057      (if_then_else (match_operand 0 "register_operand" "")
13058         (const_string "2")
13059         (const_string "*")))])
13060
13061 (define_insn "*lshrqi3_1_one_bit_slp"
13062   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13063         (lshiftrt:QI (match_dup 0)
13064                      (match_operand:QI 1 "const1_operand" "")))
13065    (clobber (reg:CC FLAGS_REG))]
13066   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13067    && (TARGET_SHIFT1 || optimize_size)"
13068   "shr{b}\t%0"
13069   [(set_attr "type" "ishift1")
13070    (set (attr "length")
13071      (if_then_else (match_operand 0 "register_operand" "")
13072         (const_string "2")
13073         (const_string "*")))])
13074
13075 (define_insn "*lshrqi3_1"
13076   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13077         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13078                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13079    (clobber (reg:CC FLAGS_REG))]
13080   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13081   "@
13082    shr{b}\t{%2, %0|%0, %2}
13083    shr{b}\t{%b2, %0|%0, %b2}"
13084   [(set_attr "type" "ishift")
13085    (set_attr "mode" "QI")])
13086
13087 (define_insn "*lshrqi3_1_slp"
13088   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13089         (lshiftrt:QI (match_dup 0)
13090                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13091    (clobber (reg:CC FLAGS_REG))]
13092   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13093    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13094   "@
13095    shr{b}\t{%1, %0|%0, %1}
13096    shr{b}\t{%b1, %0|%0, %b1}"
13097   [(set_attr "type" "ishift1")
13098    (set_attr "mode" "QI")])
13099
13100 ;; This pattern can't accept a variable shift count, since shifts by
13101 ;; zero don't affect the flags.  We assume that shifts by constant
13102 ;; zero are optimized away.
13103 (define_insn "*lshrqi2_one_bit_cmp"
13104   [(set (reg FLAGS_REG)
13105         (compare
13106           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13107                        (match_operand:QI 2 "const1_operand" ""))
13108           (const_int 0)))
13109    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13110         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13111   "(TARGET_SHIFT1 || optimize_size)
13112    && ix86_match_ccmode (insn, CCGOCmode)
13113    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13114   "shr{b}\t%0"
13115   [(set_attr "type" "ishift")
13116    (set (attr "length")
13117      (if_then_else (match_operand:SI 0 "register_operand" "")
13118         (const_string "2")
13119         (const_string "*")))])
13120
13121 (define_insn "*lshrqi2_one_bit_cconly"
13122   [(set (reg FLAGS_REG)
13123         (compare
13124           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13125                        (match_operand:QI 2 "const1_operand" ""))
13126           (const_int 0)))
13127    (clobber (match_scratch:QI 0 "=q"))]
13128   "(TARGET_SHIFT1 || optimize_size)
13129    && ix86_match_ccmode (insn, CCGOCmode)
13130    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13131   "shr{b}\t%0"
13132   [(set_attr "type" "ishift")
13133    (set_attr "length" "2")])
13134
13135 ;; This pattern can't accept a variable shift count, since shifts by
13136 ;; zero don't affect the flags.  We assume that shifts by constant
13137 ;; zero are optimized away.
13138 (define_insn "*lshrqi2_cmp"
13139   [(set (reg FLAGS_REG)
13140         (compare
13141           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13142                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13143           (const_int 0)))
13144    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13145         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13146   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13147    && ix86_match_ccmode (insn, CCGOCmode)
13148    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13149   "shr{b}\t{%2, %0|%0, %2}"
13150   [(set_attr "type" "ishift")
13151    (set_attr "mode" "QI")])
13152
13153 (define_insn "*lshrqi2_cconly"
13154   [(set (reg FLAGS_REG)
13155         (compare
13156           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13157                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13158           (const_int 0)))
13159    (clobber (match_scratch:QI 0 "=q"))]
13160   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13161    && ix86_match_ccmode (insn, CCGOCmode)
13162    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13163   "shr{b}\t{%2, %0|%0, %2}"
13164   [(set_attr "type" "ishift")
13165    (set_attr "mode" "QI")])
13166 \f
13167 ;; Rotate instructions
13168
13169 (define_expand "rotldi3"
13170   [(set (match_operand:DI 0 "shiftdi_operand" "")
13171         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13172                    (match_operand:QI 2 "nonmemory_operand" "")))
13173    (clobber (reg:CC FLAGS_REG))]
13174  ""
13175 {
13176   if (TARGET_64BIT)
13177     {
13178       ix86_expand_binary_operator (ROTATE, DImode, operands);
13179       DONE;
13180     }
13181   if (!const_1_to_31_operand (operands[2], VOIDmode))
13182     FAIL;
13183   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13184   DONE;
13185 })
13186
13187 ;; Implement rotation using two double-precision shift instructions
13188 ;; and a scratch register.
13189 (define_insn_and_split "ix86_rotldi3"
13190  [(set (match_operand:DI 0 "register_operand" "=r")
13191        (rotate:DI (match_operand:DI 1 "register_operand" "0")
13192                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
13193   (clobber (reg:CC FLAGS_REG))
13194   (clobber (match_scratch:SI 3 "=&r"))]
13195  "!TARGET_64BIT"
13196  ""
13197  "&& reload_completed"
13198  [(set (match_dup 3) (match_dup 4))
13199   (parallel
13200    [(set (match_dup 4)
13201          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13202                  (lshiftrt:SI (match_dup 5)
13203                               (minus:QI (const_int 32) (match_dup 2)))))
13204     (clobber (reg:CC FLAGS_REG))])
13205   (parallel
13206    [(set (match_dup 5)
13207          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13208                  (lshiftrt:SI (match_dup 3)
13209                               (minus:QI (const_int 32) (match_dup 2)))))
13210     (clobber (reg:CC FLAGS_REG))])]
13211  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13212
13213 (define_insn "*rotlsi3_1_one_bit_rex64"
13214   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13215         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13216                    (match_operand:QI 2 "const1_operand" "")))
13217    (clobber (reg:CC FLAGS_REG))]
13218   "TARGET_64BIT
13219    && (TARGET_SHIFT1 || optimize_size)
13220    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13221   "rol{q}\t%0"
13222   [(set_attr "type" "rotate")
13223    (set (attr "length")
13224      (if_then_else (match_operand:DI 0 "register_operand" "")
13225         (const_string "2")
13226         (const_string "*")))])
13227
13228 (define_insn "*rotldi3_1_rex64"
13229   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13230         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13231                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
13232    (clobber (reg:CC FLAGS_REG))]
13233   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13234   "@
13235    rol{q}\t{%2, %0|%0, %2}
13236    rol{q}\t{%b2, %0|%0, %b2}"
13237   [(set_attr "type" "rotate")
13238    (set_attr "mode" "DI")])
13239
13240 (define_expand "rotlsi3"
13241   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13242         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13243                    (match_operand:QI 2 "nonmemory_operand" "")))
13244    (clobber (reg:CC FLAGS_REG))]
13245   ""
13246   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13247
13248 (define_insn "*rotlsi3_1_one_bit"
13249   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13250         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13251                    (match_operand:QI 2 "const1_operand" "")))
13252    (clobber (reg:CC FLAGS_REG))]
13253   "(TARGET_SHIFT1 || optimize_size)
13254    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13255   "rol{l}\t%0"
13256   [(set_attr "type" "rotate")
13257    (set (attr "length")
13258      (if_then_else (match_operand:SI 0 "register_operand" "")
13259         (const_string "2")
13260         (const_string "*")))])
13261
13262 (define_insn "*rotlsi3_1_one_bit_zext"
13263   [(set (match_operand:DI 0 "register_operand" "=r")
13264         (zero_extend:DI
13265           (rotate:SI (match_operand:SI 1 "register_operand" "0")
13266                      (match_operand:QI 2 "const1_operand" ""))))
13267    (clobber (reg:CC FLAGS_REG))]
13268   "TARGET_64BIT
13269    && (TARGET_SHIFT1 || optimize_size)
13270    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13271   "rol{l}\t%k0"
13272   [(set_attr "type" "rotate")
13273    (set_attr "length" "2")])
13274
13275 (define_insn "*rotlsi3_1"
13276   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13277         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13278                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13279    (clobber (reg:CC FLAGS_REG))]
13280   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13281   "@
13282    rol{l}\t{%2, %0|%0, %2}
13283    rol{l}\t{%b2, %0|%0, %b2}"
13284   [(set_attr "type" "rotate")
13285    (set_attr "mode" "SI")])
13286
13287 (define_insn "*rotlsi3_1_zext"
13288   [(set (match_operand:DI 0 "register_operand" "=r,r")
13289         (zero_extend:DI
13290           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13291                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13292    (clobber (reg:CC FLAGS_REG))]
13293   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13294   "@
13295    rol{l}\t{%2, %k0|%k0, %2}
13296    rol{l}\t{%b2, %k0|%k0, %b2}"
13297   [(set_attr "type" "rotate")
13298    (set_attr "mode" "SI")])
13299
13300 (define_expand "rotlhi3"
13301   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13302         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13303                    (match_operand:QI 2 "nonmemory_operand" "")))
13304    (clobber (reg:CC FLAGS_REG))]
13305   "TARGET_HIMODE_MATH"
13306   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13307
13308 (define_insn "*rotlhi3_1_one_bit"
13309   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13310         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13311                    (match_operand:QI 2 "const1_operand" "")))
13312    (clobber (reg:CC FLAGS_REG))]
13313   "(TARGET_SHIFT1 || optimize_size)
13314    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13315   "rol{w}\t%0"
13316   [(set_attr "type" "rotate")
13317    (set (attr "length")
13318      (if_then_else (match_operand 0 "register_operand" "")
13319         (const_string "2")
13320         (const_string "*")))])
13321
13322 (define_insn "*rotlhi3_1"
13323   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13324         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13325                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13326    (clobber (reg:CC FLAGS_REG))]
13327   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13328   "@
13329    rol{w}\t{%2, %0|%0, %2}
13330    rol{w}\t{%b2, %0|%0, %b2}"
13331   [(set_attr "type" "rotate")
13332    (set_attr "mode" "HI")])
13333
13334 (define_split
13335  [(set (match_operand:HI 0 "register_operand" "")
13336        (rotate:HI (match_dup 0) (const_int 8)))
13337   (clobber (reg:CC FLAGS_REG))]
13338  "reload_completed"
13339  [(parallel [(set (strict_low_part (match_dup 0))
13340                   (bswap:HI (match_dup 0)))
13341              (clobber (reg:CC FLAGS_REG))])]
13342  "")
13343
13344 (define_expand "rotlqi3"
13345   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13346         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13347                    (match_operand:QI 2 "nonmemory_operand" "")))
13348    (clobber (reg:CC FLAGS_REG))]
13349   "TARGET_QIMODE_MATH"
13350   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13351
13352 (define_insn "*rotlqi3_1_one_bit_slp"
13353   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13354         (rotate:QI (match_dup 0)
13355                    (match_operand:QI 1 "const1_operand" "")))
13356    (clobber (reg:CC FLAGS_REG))]
13357   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13358    && (TARGET_SHIFT1 || optimize_size)"
13359   "rol{b}\t%0"
13360   [(set_attr "type" "rotate1")
13361    (set (attr "length")
13362      (if_then_else (match_operand 0 "register_operand" "")
13363         (const_string "2")
13364         (const_string "*")))])
13365
13366 (define_insn "*rotlqi3_1_one_bit"
13367   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13368         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13369                    (match_operand:QI 2 "const1_operand" "")))
13370    (clobber (reg:CC FLAGS_REG))]
13371   "(TARGET_SHIFT1 || optimize_size)
13372    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13373   "rol{b}\t%0"
13374   [(set_attr "type" "rotate")
13375    (set (attr "length")
13376      (if_then_else (match_operand 0 "register_operand" "")
13377         (const_string "2")
13378         (const_string "*")))])
13379
13380 (define_insn "*rotlqi3_1_slp"
13381   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13382         (rotate:QI (match_dup 0)
13383                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13384    (clobber (reg:CC FLAGS_REG))]
13385   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13386    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13387   "@
13388    rol{b}\t{%1, %0|%0, %1}
13389    rol{b}\t{%b1, %0|%0, %b1}"
13390   [(set_attr "type" "rotate1")
13391    (set_attr "mode" "QI")])
13392
13393 (define_insn "*rotlqi3_1"
13394   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13395         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13396                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13397    (clobber (reg:CC FLAGS_REG))]
13398   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13399   "@
13400    rol{b}\t{%2, %0|%0, %2}
13401    rol{b}\t{%b2, %0|%0, %b2}"
13402   [(set_attr "type" "rotate")
13403    (set_attr "mode" "QI")])
13404
13405 (define_expand "rotrdi3"
13406   [(set (match_operand:DI 0 "shiftdi_operand" "")
13407         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13408                    (match_operand:QI 2 "nonmemory_operand" "")))
13409    (clobber (reg:CC FLAGS_REG))]
13410  ""
13411 {
13412   if (TARGET_64BIT)
13413     {
13414       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13415       DONE;
13416     }
13417   if (!const_1_to_31_operand (operands[2], VOIDmode))
13418     FAIL;
13419   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13420   DONE;
13421 })
13422
13423 ;; Implement rotation using two double-precision shift instructions
13424 ;; and a scratch register.
13425 (define_insn_and_split "ix86_rotrdi3"
13426  [(set (match_operand:DI 0 "register_operand" "=r")
13427        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13428                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13429   (clobber (reg:CC FLAGS_REG))
13430   (clobber (match_scratch:SI 3 "=&r"))]
13431  "!TARGET_64BIT"
13432  ""
13433  "&& reload_completed"
13434  [(set (match_dup 3) (match_dup 4))
13435   (parallel
13436    [(set (match_dup 4)
13437          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13438                  (ashift:SI (match_dup 5)
13439                             (minus:QI (const_int 32) (match_dup 2)))))
13440     (clobber (reg:CC FLAGS_REG))])
13441   (parallel
13442    [(set (match_dup 5)
13443          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13444                  (ashift:SI (match_dup 3)
13445                             (minus:QI (const_int 32) (match_dup 2)))))
13446     (clobber (reg:CC FLAGS_REG))])]
13447  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13448
13449 (define_insn "*rotrdi3_1_one_bit_rex64"
13450   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13451         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13452                      (match_operand:QI 2 "const1_operand" "")))
13453    (clobber (reg:CC FLAGS_REG))]
13454   "TARGET_64BIT
13455    && (TARGET_SHIFT1 || optimize_size)
13456    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13457   "ror{q}\t%0"
13458   [(set_attr "type" "rotate")
13459    (set (attr "length")
13460      (if_then_else (match_operand:DI 0 "register_operand" "")
13461         (const_string "2")
13462         (const_string "*")))])
13463
13464 (define_insn "*rotrdi3_1_rex64"
13465   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13466         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13467                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13468    (clobber (reg:CC FLAGS_REG))]
13469   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13470   "@
13471    ror{q}\t{%2, %0|%0, %2}
13472    ror{q}\t{%b2, %0|%0, %b2}"
13473   [(set_attr "type" "rotate")
13474    (set_attr "mode" "DI")])
13475
13476 (define_expand "rotrsi3"
13477   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13478         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13479                      (match_operand:QI 2 "nonmemory_operand" "")))
13480    (clobber (reg:CC FLAGS_REG))]
13481   ""
13482   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13483
13484 (define_insn "*rotrsi3_1_one_bit"
13485   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13486         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13487                      (match_operand:QI 2 "const1_operand" "")))
13488    (clobber (reg:CC FLAGS_REG))]
13489   "(TARGET_SHIFT1 || optimize_size)
13490    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13491   "ror{l}\t%0"
13492   [(set_attr "type" "rotate")
13493    (set (attr "length")
13494      (if_then_else (match_operand:SI 0 "register_operand" "")
13495         (const_string "2")
13496         (const_string "*")))])
13497
13498 (define_insn "*rotrsi3_1_one_bit_zext"
13499   [(set (match_operand:DI 0 "register_operand" "=r")
13500         (zero_extend:DI
13501           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13502                        (match_operand:QI 2 "const1_operand" ""))))
13503    (clobber (reg:CC FLAGS_REG))]
13504   "TARGET_64BIT
13505    && (TARGET_SHIFT1 || optimize_size)
13506    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13507   "ror{l}\t%k0"
13508   [(set_attr "type" "rotate")
13509    (set (attr "length")
13510      (if_then_else (match_operand:SI 0 "register_operand" "")
13511         (const_string "2")
13512         (const_string "*")))])
13513
13514 (define_insn "*rotrsi3_1"
13515   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13516         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13517                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13518    (clobber (reg:CC FLAGS_REG))]
13519   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13520   "@
13521    ror{l}\t{%2, %0|%0, %2}
13522    ror{l}\t{%b2, %0|%0, %b2}"
13523   [(set_attr "type" "rotate")
13524    (set_attr "mode" "SI")])
13525
13526 (define_insn "*rotrsi3_1_zext"
13527   [(set (match_operand:DI 0 "register_operand" "=r,r")
13528         (zero_extend:DI
13529           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13530                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13531    (clobber (reg:CC FLAGS_REG))]
13532   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13533   "@
13534    ror{l}\t{%2, %k0|%k0, %2}
13535    ror{l}\t{%b2, %k0|%k0, %b2}"
13536   [(set_attr "type" "rotate")
13537    (set_attr "mode" "SI")])
13538
13539 (define_expand "rotrhi3"
13540   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13541         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13542                      (match_operand:QI 2 "nonmemory_operand" "")))
13543    (clobber (reg:CC FLAGS_REG))]
13544   "TARGET_HIMODE_MATH"
13545   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13546
13547 (define_insn "*rotrhi3_one_bit"
13548   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13549         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13550                      (match_operand:QI 2 "const1_operand" "")))
13551    (clobber (reg:CC FLAGS_REG))]
13552   "(TARGET_SHIFT1 || optimize_size)
13553    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13554   "ror{w}\t%0"
13555   [(set_attr "type" "rotate")
13556    (set (attr "length")
13557      (if_then_else (match_operand 0 "register_operand" "")
13558         (const_string "2")
13559         (const_string "*")))])
13560
13561 (define_insn "*rotrhi3_1"
13562   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13563         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13564                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13565    (clobber (reg:CC FLAGS_REG))]
13566   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13567   "@
13568    ror{w}\t{%2, %0|%0, %2}
13569    ror{w}\t{%b2, %0|%0, %b2}"
13570   [(set_attr "type" "rotate")
13571    (set_attr "mode" "HI")])
13572
13573 (define_split
13574  [(set (match_operand:HI 0 "register_operand" "")
13575        (rotatert:HI (match_dup 0) (const_int 8)))
13576   (clobber (reg:CC FLAGS_REG))]
13577  "reload_completed"
13578  [(parallel [(set (strict_low_part (match_dup 0))
13579                   (bswap:HI (match_dup 0)))
13580              (clobber (reg:CC FLAGS_REG))])]
13581  "")
13582
13583 (define_expand "rotrqi3"
13584   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13585         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13586                      (match_operand:QI 2 "nonmemory_operand" "")))
13587    (clobber (reg:CC FLAGS_REG))]
13588   "TARGET_QIMODE_MATH"
13589   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13590
13591 (define_insn "*rotrqi3_1_one_bit"
13592   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13593         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13594                      (match_operand:QI 2 "const1_operand" "")))
13595    (clobber (reg:CC FLAGS_REG))]
13596   "(TARGET_SHIFT1 || optimize_size)
13597    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13598   "ror{b}\t%0"
13599   [(set_attr "type" "rotate")
13600    (set (attr "length")
13601      (if_then_else (match_operand 0 "register_operand" "")
13602         (const_string "2")
13603         (const_string "*")))])
13604
13605 (define_insn "*rotrqi3_1_one_bit_slp"
13606   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13607         (rotatert:QI (match_dup 0)
13608                      (match_operand:QI 1 "const1_operand" "")))
13609    (clobber (reg:CC FLAGS_REG))]
13610   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13611    && (TARGET_SHIFT1 || optimize_size)"
13612   "ror{b}\t%0"
13613   [(set_attr "type" "rotate1")
13614    (set (attr "length")
13615      (if_then_else (match_operand 0 "register_operand" "")
13616         (const_string "2")
13617         (const_string "*")))])
13618
13619 (define_insn "*rotrqi3_1"
13620   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13621         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13622                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13623    (clobber (reg:CC FLAGS_REG))]
13624   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13625   "@
13626    ror{b}\t{%2, %0|%0, %2}
13627    ror{b}\t{%b2, %0|%0, %b2}"
13628   [(set_attr "type" "rotate")
13629    (set_attr "mode" "QI")])
13630
13631 (define_insn "*rotrqi3_1_slp"
13632   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13633         (rotatert:QI (match_dup 0)
13634                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13635    (clobber (reg:CC FLAGS_REG))]
13636   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13637    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13638   "@
13639    ror{b}\t{%1, %0|%0, %1}
13640    ror{b}\t{%b1, %0|%0, %b1}"
13641   [(set_attr "type" "rotate1")
13642    (set_attr "mode" "QI")])
13643 \f
13644 ;; Bit set / bit test instructions
13645
13646 (define_expand "extv"
13647   [(set (match_operand:SI 0 "register_operand" "")
13648         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13649                          (match_operand:SI 2 "const8_operand" "")
13650                          (match_operand:SI 3 "const8_operand" "")))]
13651   ""
13652 {
13653   /* Handle extractions from %ah et al.  */
13654   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13655     FAIL;
13656
13657   /* From mips.md: extract_bit_field doesn't verify that our source
13658      matches the predicate, so check it again here.  */
13659   if (! ext_register_operand (operands[1], VOIDmode))
13660     FAIL;
13661 })
13662
13663 (define_expand "extzv"
13664   [(set (match_operand:SI 0 "register_operand" "")
13665         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13666                          (match_operand:SI 2 "const8_operand" "")
13667                          (match_operand:SI 3 "const8_operand" "")))]
13668   ""
13669 {
13670   /* Handle extractions from %ah et al.  */
13671   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13672     FAIL;
13673
13674   /* From mips.md: extract_bit_field doesn't verify that our source
13675      matches the predicate, so check it again here.  */
13676   if (! ext_register_operand (operands[1], VOIDmode))
13677     FAIL;
13678 })
13679
13680 (define_expand "insv"
13681   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13682                       (match_operand 1 "const8_operand" "")
13683                       (match_operand 2 "const8_operand" ""))
13684         (match_operand 3 "register_operand" ""))]
13685   ""
13686 {
13687   /* Handle insertions to %ah et al.  */
13688   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13689     FAIL;
13690
13691   /* From mips.md: insert_bit_field doesn't verify that our source
13692      matches the predicate, so check it again here.  */
13693   if (! ext_register_operand (operands[0], VOIDmode))
13694     FAIL;
13695
13696   if (TARGET_64BIT)
13697     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13698   else
13699     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13700
13701   DONE;
13702 })
13703
13704 ;; %%% bts, btr, btc, bt.
13705 ;; In general these instructions are *slow* when applied to memory,
13706 ;; since they enforce atomic operation.  When applied to registers,
13707 ;; it depends on the cpu implementation.  They're never faster than
13708 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13709 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13710 ;; within the instruction itself, so operating on bits in the high
13711 ;; 32-bits of a register becomes easier.
13712 ;;
13713 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13714 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13715 ;; negdf respectively, so they can never be disabled entirely.
13716
13717 (define_insn "*btsq"
13718   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13719                          (const_int 1)
13720                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13721         (const_int 1))
13722    (clobber (reg:CC FLAGS_REG))]
13723   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13724   "bts{q} %1,%0"
13725   [(set_attr "type" "alu1")])
13726
13727 (define_insn "*btrq"
13728   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13729                          (const_int 1)
13730                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13731         (const_int 0))
13732    (clobber (reg:CC FLAGS_REG))]
13733   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13734   "btr{q} %1,%0"
13735   [(set_attr "type" "alu1")])
13736
13737 (define_insn "*btcq"
13738   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13739                          (const_int 1)
13740                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13741         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13742    (clobber (reg:CC FLAGS_REG))]
13743   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13744   "btc{q} %1,%0"
13745   [(set_attr "type" "alu1")])
13746
13747 ;; Allow Nocona to avoid these instructions if a register is available.
13748
13749 (define_peephole2
13750   [(match_scratch:DI 2 "r")
13751    (parallel [(set (zero_extract:DI
13752                      (match_operand:DI 0 "register_operand" "")
13753                      (const_int 1)
13754                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13755                    (const_int 1))
13756               (clobber (reg:CC FLAGS_REG))])]
13757   "TARGET_64BIT && !TARGET_USE_BT"
13758   [(const_int 0)]
13759 {
13760   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13761   rtx op1;
13762
13763   if (HOST_BITS_PER_WIDE_INT >= 64)
13764     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13765   else if (i < HOST_BITS_PER_WIDE_INT)
13766     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13767   else
13768     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13769
13770   op1 = immed_double_const (lo, hi, DImode);
13771   if (i >= 31)
13772     {
13773       emit_move_insn (operands[2], op1);
13774       op1 = operands[2];
13775     }
13776
13777   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13778   DONE;
13779 })
13780
13781 (define_peephole2
13782   [(match_scratch:DI 2 "r")
13783    (parallel [(set (zero_extract:DI
13784                      (match_operand:DI 0 "register_operand" "")
13785                      (const_int 1)
13786                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13787                    (const_int 0))
13788               (clobber (reg:CC FLAGS_REG))])]
13789   "TARGET_64BIT && !TARGET_USE_BT"
13790   [(const_int 0)]
13791 {
13792   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13793   rtx op1;
13794
13795   if (HOST_BITS_PER_WIDE_INT >= 64)
13796     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13797   else if (i < HOST_BITS_PER_WIDE_INT)
13798     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13799   else
13800     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13801
13802   op1 = immed_double_const (~lo, ~hi, DImode);
13803   if (i >= 32)
13804     {
13805       emit_move_insn (operands[2], op1);
13806       op1 = operands[2];
13807     }
13808
13809   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13810   DONE;
13811 })
13812
13813 (define_peephole2
13814   [(match_scratch:DI 2 "r")
13815    (parallel [(set (zero_extract:DI
13816                      (match_operand:DI 0 "register_operand" "")
13817                      (const_int 1)
13818                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13819               (not:DI (zero_extract:DI
13820                         (match_dup 0) (const_int 1) (match_dup 1))))
13821               (clobber (reg:CC FLAGS_REG))])]
13822   "TARGET_64BIT && !TARGET_USE_BT"
13823   [(const_int 0)]
13824 {
13825   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13826   rtx op1;
13827
13828   if (HOST_BITS_PER_WIDE_INT >= 64)
13829     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13830   else if (i < HOST_BITS_PER_WIDE_INT)
13831     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13832   else
13833     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13834
13835   op1 = immed_double_const (lo, hi, DImode);
13836   if (i >= 31)
13837     {
13838       emit_move_insn (operands[2], op1);
13839       op1 = operands[2];
13840     }
13841
13842   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13843   DONE;
13844 })
13845 \f
13846 ;; Store-flag instructions.
13847
13848 ;; For all sCOND expanders, also expand the compare or test insn that
13849 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13850
13851 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13852 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13853 ;; way, which can later delete the movzx if only QImode is needed.
13854
13855 (define_expand "s<code>"
13856   [(set (match_operand:QI 0 "register_operand" "")
13857         (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13858   ""
13859   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13860
13861 (define_expand "s<code>"
13862   [(set (match_operand:QI 0 "register_operand" "")
13863         (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13864   "TARGET_80387 || TARGET_SSE"
13865   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13866
13867 (define_insn "*setcc_1"
13868   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13869         (match_operator:QI 1 "ix86_comparison_operator"
13870           [(reg FLAGS_REG) (const_int 0)]))]
13871   ""
13872   "set%C1\t%0"
13873   [(set_attr "type" "setcc")
13874    (set_attr "mode" "QI")])
13875
13876 (define_insn "*setcc_2"
13877   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13878         (match_operator:QI 1 "ix86_comparison_operator"
13879           [(reg FLAGS_REG) (const_int 0)]))]
13880   ""
13881   "set%C1\t%0"
13882   [(set_attr "type" "setcc")
13883    (set_attr "mode" "QI")])
13884
13885 ;; In general it is not safe to assume too much about CCmode registers,
13886 ;; so simplify-rtx stops when it sees a second one.  Under certain
13887 ;; conditions this is safe on x86, so help combine not create
13888 ;;
13889 ;;      seta    %al
13890 ;;      testb   %al, %al
13891 ;;      sete    %al
13892
13893 (define_split
13894   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13895         (ne:QI (match_operator 1 "ix86_comparison_operator"
13896                  [(reg FLAGS_REG) (const_int 0)])
13897             (const_int 0)))]
13898   ""
13899   [(set (match_dup 0) (match_dup 1))]
13900 {
13901   PUT_MODE (operands[1], QImode);
13902 })
13903
13904 (define_split
13905   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13906         (ne:QI (match_operator 1 "ix86_comparison_operator"
13907                  [(reg FLAGS_REG) (const_int 0)])
13908             (const_int 0)))]
13909   ""
13910   [(set (match_dup 0) (match_dup 1))]
13911 {
13912   PUT_MODE (operands[1], QImode);
13913 })
13914
13915 (define_split
13916   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13917         (eq:QI (match_operator 1 "ix86_comparison_operator"
13918                  [(reg FLAGS_REG) (const_int 0)])
13919             (const_int 0)))]
13920   ""
13921   [(set (match_dup 0) (match_dup 1))]
13922 {
13923   rtx new_op1 = copy_rtx (operands[1]);
13924   operands[1] = new_op1;
13925   PUT_MODE (new_op1, QImode);
13926   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13927                                              GET_MODE (XEXP (new_op1, 0))));
13928
13929   /* Make sure that (a) the CCmode we have for the flags is strong
13930      enough for the reversed compare or (b) we have a valid FP compare.  */
13931   if (! ix86_comparison_operator (new_op1, VOIDmode))
13932     FAIL;
13933 })
13934
13935 (define_split
13936   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13937         (eq:QI (match_operator 1 "ix86_comparison_operator"
13938                  [(reg FLAGS_REG) (const_int 0)])
13939             (const_int 0)))]
13940   ""
13941   [(set (match_dup 0) (match_dup 1))]
13942 {
13943   rtx new_op1 = copy_rtx (operands[1]);
13944   operands[1] = new_op1;
13945   PUT_MODE (new_op1, QImode);
13946   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13947                                              GET_MODE (XEXP (new_op1, 0))));
13948
13949   /* Make sure that (a) the CCmode we have for the flags is strong
13950      enough for the reversed compare or (b) we have a valid FP compare.  */
13951   if (! ix86_comparison_operator (new_op1, VOIDmode))
13952     FAIL;
13953 })
13954
13955 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13956 ;; subsequent logical operations are used to imitate conditional moves.
13957 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13958 ;; it directly.
13959
13960 (define_insn "*sse_setcc<mode>"
13961   [(set (match_operand:MODEF 0 "register_operand" "=x")
13962         (match_operator:MODEF 1 "sse_comparison_operator"
13963           [(match_operand:MODEF 2 "register_operand" "0")
13964            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13965   "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
13966   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13967   [(set_attr "type" "ssecmp")
13968    (set_attr "mode" "<MODE>")])
13969
13970 (define_insn "*sse5_setcc<mode>"
13971   [(set (match_operand:MODEF 0 "register_operand" "=x")
13972         (match_operator:MODEF 1 "sse5_comparison_float_operator"
13973           [(match_operand:MODEF 2 "register_operand" "x")
13974            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13975   "TARGET_SSE5"
13976   "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13977   [(set_attr "type" "sse4arg")
13978    (set_attr "mode" "<MODE>")])
13979
13980 \f
13981 ;; Basic conditional jump instructions.
13982 ;; We ignore the overflow flag for signed branch instructions.
13983
13984 ;; For all bCOND expanders, also expand the compare or test insn that
13985 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13986
13987 (define_expand "b<code>"
13988   [(set (pc)
13989         (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
13990                                    (const_int 0))
13991                       (label_ref (match_operand 0 ""))
13992                       (pc)))]
13993   ""
13994   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
13995
13996 (define_expand "b<code>"
13997   [(set (pc)
13998         (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
13999                                   (const_int 0))
14000                       (label_ref (match_operand 0 ""))
14001                       (pc)))]
14002   "TARGET_80387 || TARGET_SSE_MATH"
14003   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14004
14005 (define_insn "*jcc_1"
14006   [(set (pc)
14007         (if_then_else (match_operator 1 "ix86_comparison_operator"
14008                                       [(reg FLAGS_REG) (const_int 0)])
14009                       (label_ref (match_operand 0 "" ""))
14010                       (pc)))]
14011   ""
14012   "%+j%C1\t%l0"
14013   [(set_attr "type" "ibr")
14014    (set_attr "modrm" "0")
14015    (set (attr "length")
14016            (if_then_else (and (ge (minus (match_dup 0) (pc))
14017                                   (const_int -126))
14018                               (lt (minus (match_dup 0) (pc))
14019                                   (const_int 128)))
14020              (const_int 2)
14021              (const_int 6)))])
14022
14023 (define_insn "*jcc_2"
14024   [(set (pc)
14025         (if_then_else (match_operator 1 "ix86_comparison_operator"
14026                                       [(reg FLAGS_REG) (const_int 0)])
14027                       (pc)
14028                       (label_ref (match_operand 0 "" ""))))]
14029   ""
14030   "%+j%c1\t%l0"
14031   [(set_attr "type" "ibr")
14032    (set_attr "modrm" "0")
14033    (set (attr "length")
14034            (if_then_else (and (ge (minus (match_dup 0) (pc))
14035                                   (const_int -126))
14036                               (lt (minus (match_dup 0) (pc))
14037                                   (const_int 128)))
14038              (const_int 2)
14039              (const_int 6)))])
14040
14041 ;; In general it is not safe to assume too much about CCmode registers,
14042 ;; so simplify-rtx stops when it sees a second one.  Under certain
14043 ;; conditions this is safe on x86, so help combine not create
14044 ;;
14045 ;;      seta    %al
14046 ;;      testb   %al, %al
14047 ;;      je      Lfoo
14048
14049 (define_split
14050   [(set (pc)
14051         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14052                                       [(reg FLAGS_REG) (const_int 0)])
14053                           (const_int 0))
14054                       (label_ref (match_operand 1 "" ""))
14055                       (pc)))]
14056   ""
14057   [(set (pc)
14058         (if_then_else (match_dup 0)
14059                       (label_ref (match_dup 1))
14060                       (pc)))]
14061 {
14062   PUT_MODE (operands[0], VOIDmode);
14063 })
14064
14065 (define_split
14066   [(set (pc)
14067         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14068                                       [(reg FLAGS_REG) (const_int 0)])
14069                           (const_int 0))
14070                       (label_ref (match_operand 1 "" ""))
14071                       (pc)))]
14072   ""
14073   [(set (pc)
14074         (if_then_else (match_dup 0)
14075                       (label_ref (match_dup 1))
14076                       (pc)))]
14077 {
14078   rtx new_op0 = copy_rtx (operands[0]);
14079   operands[0] = new_op0;
14080   PUT_MODE (new_op0, VOIDmode);
14081   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14082                                              GET_MODE (XEXP (new_op0, 0))));
14083
14084   /* Make sure that (a) the CCmode we have for the flags is strong
14085      enough for the reversed compare or (b) we have a valid FP compare.  */
14086   if (! ix86_comparison_operator (new_op0, VOIDmode))
14087     FAIL;
14088 })
14089
14090 ;; Define combination compare-and-branch fp compare instructions to use
14091 ;; during early optimization.  Splitting the operation apart early makes
14092 ;; for bad code when we want to reverse the operation.
14093
14094 (define_insn "*fp_jcc_1_mixed"
14095   [(set (pc)
14096         (if_then_else (match_operator 0 "comparison_operator"
14097                         [(match_operand 1 "register_operand" "f,x")
14098                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14099           (label_ref (match_operand 3 "" ""))
14100           (pc)))
14101    (clobber (reg:CCFP FPSR_REG))
14102    (clobber (reg:CCFP FLAGS_REG))]
14103   "TARGET_MIX_SSE_I387
14104    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14105    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14106    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14107   "#")
14108
14109 (define_insn "*fp_jcc_1_sse"
14110   [(set (pc)
14111         (if_then_else (match_operator 0 "comparison_operator"
14112                         [(match_operand 1 "register_operand" "x")
14113                          (match_operand 2 "nonimmediate_operand" "xm")])
14114           (label_ref (match_operand 3 "" ""))
14115           (pc)))
14116    (clobber (reg:CCFP FPSR_REG))
14117    (clobber (reg:CCFP FLAGS_REG))]
14118   "TARGET_SSE_MATH
14119    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14120    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14121    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14122   "#")
14123
14124 (define_insn "*fp_jcc_1_387"
14125   [(set (pc)
14126         (if_then_else (match_operator 0 "comparison_operator"
14127                         [(match_operand 1 "register_operand" "f")
14128                          (match_operand 2 "register_operand" "f")])
14129           (label_ref (match_operand 3 "" ""))
14130           (pc)))
14131    (clobber (reg:CCFP FPSR_REG))
14132    (clobber (reg:CCFP FLAGS_REG))]
14133   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14134    && TARGET_CMOVE
14135    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14136    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14137   "#")
14138
14139 (define_insn "*fp_jcc_2_mixed"
14140   [(set (pc)
14141         (if_then_else (match_operator 0 "comparison_operator"
14142                         [(match_operand 1 "register_operand" "f,x")
14143                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14144           (pc)
14145           (label_ref (match_operand 3 "" ""))))
14146    (clobber (reg:CCFP FPSR_REG))
14147    (clobber (reg:CCFP FLAGS_REG))]
14148   "TARGET_MIX_SSE_I387
14149    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14150    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14151    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14152   "#")
14153
14154 (define_insn "*fp_jcc_2_sse"
14155   [(set (pc)
14156         (if_then_else (match_operator 0 "comparison_operator"
14157                         [(match_operand 1 "register_operand" "x")
14158                          (match_operand 2 "nonimmediate_operand" "xm")])
14159           (pc)
14160           (label_ref (match_operand 3 "" ""))))
14161    (clobber (reg:CCFP FPSR_REG))
14162    (clobber (reg:CCFP FLAGS_REG))]
14163   "TARGET_SSE_MATH
14164    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14165    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14166    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14167   "#")
14168
14169 (define_insn "*fp_jcc_2_387"
14170   [(set (pc)
14171         (if_then_else (match_operator 0 "comparison_operator"
14172                         [(match_operand 1 "register_operand" "f")
14173                          (match_operand 2 "register_operand" "f")])
14174           (pc)
14175           (label_ref (match_operand 3 "" ""))))
14176    (clobber (reg:CCFP FPSR_REG))
14177    (clobber (reg:CCFP FLAGS_REG))]
14178   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14179    && TARGET_CMOVE
14180    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14181    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14182   "#")
14183
14184 (define_insn "*fp_jcc_3_387"
14185   [(set (pc)
14186         (if_then_else (match_operator 0 "comparison_operator"
14187                         [(match_operand 1 "register_operand" "f")
14188                          (match_operand 2 "nonimmediate_operand" "fm")])
14189           (label_ref (match_operand 3 "" ""))
14190           (pc)))
14191    (clobber (reg:CCFP FPSR_REG))
14192    (clobber (reg:CCFP FLAGS_REG))
14193    (clobber (match_scratch:HI 4 "=a"))]
14194   "TARGET_80387
14195    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14196    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14197    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14198    && SELECT_CC_MODE (GET_CODE (operands[0]),
14199                       operands[1], operands[2]) == CCFPmode
14200    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14201   "#")
14202
14203 (define_insn "*fp_jcc_4_387"
14204   [(set (pc)
14205         (if_then_else (match_operator 0 "comparison_operator"
14206                         [(match_operand 1 "register_operand" "f")
14207                          (match_operand 2 "nonimmediate_operand" "fm")])
14208           (pc)
14209           (label_ref (match_operand 3 "" ""))))
14210    (clobber (reg:CCFP FPSR_REG))
14211    (clobber (reg:CCFP FLAGS_REG))
14212    (clobber (match_scratch:HI 4 "=a"))]
14213   "TARGET_80387
14214    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14215    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14216    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14217    && SELECT_CC_MODE (GET_CODE (operands[0]),
14218                       operands[1], operands[2]) == CCFPmode
14219    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14220   "#")
14221
14222 (define_insn "*fp_jcc_5_387"
14223   [(set (pc)
14224         (if_then_else (match_operator 0 "comparison_operator"
14225                         [(match_operand 1 "register_operand" "f")
14226                          (match_operand 2 "register_operand" "f")])
14227           (label_ref (match_operand 3 "" ""))
14228           (pc)))
14229    (clobber (reg:CCFP FPSR_REG))
14230    (clobber (reg:CCFP FLAGS_REG))
14231    (clobber (match_scratch:HI 4 "=a"))]
14232   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14233    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14234    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14235   "#")
14236
14237 (define_insn "*fp_jcc_6_387"
14238   [(set (pc)
14239         (if_then_else (match_operator 0 "comparison_operator"
14240                         [(match_operand 1 "register_operand" "f")
14241                          (match_operand 2 "register_operand" "f")])
14242           (pc)
14243           (label_ref (match_operand 3 "" ""))))
14244    (clobber (reg:CCFP FPSR_REG))
14245    (clobber (reg:CCFP FLAGS_REG))
14246    (clobber (match_scratch:HI 4 "=a"))]
14247   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14248    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14249    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14250   "#")
14251
14252 (define_insn "*fp_jcc_7_387"
14253   [(set (pc)
14254         (if_then_else (match_operator 0 "comparison_operator"
14255                         [(match_operand 1 "register_operand" "f")
14256                          (match_operand 2 "const0_operand" "X")])
14257           (label_ref (match_operand 3 "" ""))
14258           (pc)))
14259    (clobber (reg:CCFP FPSR_REG))
14260    (clobber (reg:CCFP FLAGS_REG))
14261    (clobber (match_scratch:HI 4 "=a"))]
14262   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14263    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14264    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14265    && SELECT_CC_MODE (GET_CODE (operands[0]),
14266                       operands[1], operands[2]) == CCFPmode
14267    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14268   "#")
14269
14270 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14271 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14272 ;; with a precedence over other operators and is always put in the first
14273 ;; place. Swap condition and operands to match ficom instruction.
14274
14275 (define_insn "*fp_jcc_8<mode>_387"
14276   [(set (pc)
14277         (if_then_else (match_operator 0 "comparison_operator"
14278                         [(match_operator 1 "float_operator"
14279                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14280                            (match_operand 3 "register_operand" "f,f")])
14281           (label_ref (match_operand 4 "" ""))
14282           (pc)))
14283    (clobber (reg:CCFP FPSR_REG))
14284    (clobber (reg:CCFP FLAGS_REG))
14285    (clobber (match_scratch:HI 5 "=a,a"))]
14286   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14287    && TARGET_USE_<MODE>MODE_FIOP
14288    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14289    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14290    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14291    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14292   "#")
14293
14294 (define_split
14295   [(set (pc)
14296         (if_then_else (match_operator 0 "comparison_operator"
14297                         [(match_operand 1 "register_operand" "")
14298                          (match_operand 2 "nonimmediate_operand" "")])
14299           (match_operand 3 "" "")
14300           (match_operand 4 "" "")))
14301    (clobber (reg:CCFP FPSR_REG))
14302    (clobber (reg:CCFP FLAGS_REG))]
14303   "reload_completed"
14304   [(const_int 0)]
14305 {
14306   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14307                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14308   DONE;
14309 })
14310
14311 (define_split
14312   [(set (pc)
14313         (if_then_else (match_operator 0 "comparison_operator"
14314                         [(match_operand 1 "register_operand" "")
14315                          (match_operand 2 "general_operand" "")])
14316           (match_operand 3 "" "")
14317           (match_operand 4 "" "")))
14318    (clobber (reg:CCFP FPSR_REG))
14319    (clobber (reg:CCFP FLAGS_REG))
14320    (clobber (match_scratch:HI 5 "=a"))]
14321   "reload_completed"
14322   [(const_int 0)]
14323 {
14324   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14325                         operands[3], operands[4], operands[5], NULL_RTX);
14326   DONE;
14327 })
14328
14329 (define_split
14330   [(set (pc)
14331         (if_then_else (match_operator 0 "comparison_operator"
14332                         [(match_operator 1 "float_operator"
14333                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14334                            (match_operand 3 "register_operand" "")])
14335           (match_operand 4 "" "")
14336           (match_operand 5 "" "")))
14337    (clobber (reg:CCFP FPSR_REG))
14338    (clobber (reg:CCFP FLAGS_REG))
14339    (clobber (match_scratch:HI 6 "=a"))]
14340   "reload_completed"
14341   [(const_int 0)]
14342 {
14343   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14344   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14345                         operands[3], operands[7],
14346                         operands[4], operands[5], operands[6], NULL_RTX);
14347   DONE;
14348 })
14349
14350 ;; %%% Kill this when reload knows how to do it.
14351 (define_split
14352   [(set (pc)
14353         (if_then_else (match_operator 0 "comparison_operator"
14354                         [(match_operator 1 "float_operator"
14355                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14356                            (match_operand 3 "register_operand" "")])
14357           (match_operand 4 "" "")
14358           (match_operand 5 "" "")))
14359    (clobber (reg:CCFP FPSR_REG))
14360    (clobber (reg:CCFP FLAGS_REG))
14361    (clobber (match_scratch:HI 6 "=a"))]
14362   "reload_completed"
14363   [(const_int 0)]
14364 {
14365   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14366   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14367   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14368                         operands[3], operands[7],
14369                         operands[4], operands[5], operands[6], operands[2]);
14370   DONE;
14371 })
14372 \f
14373 ;; Unconditional and other jump instructions
14374
14375 (define_insn "jump"
14376   [(set (pc)
14377         (label_ref (match_operand 0 "" "")))]
14378   ""
14379   "jmp\t%l0"
14380   [(set_attr "type" "ibr")
14381    (set (attr "length")
14382            (if_then_else (and (ge (minus (match_dup 0) (pc))
14383                                   (const_int -126))
14384                               (lt (minus (match_dup 0) (pc))
14385                                   (const_int 128)))
14386              (const_int 2)
14387              (const_int 5)))
14388    (set_attr "modrm" "0")])
14389
14390 (define_expand "indirect_jump"
14391   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14392   ""
14393   "")
14394
14395 (define_insn "*indirect_jump"
14396   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14397   "!TARGET_64BIT"
14398   "jmp\t%A0"
14399   [(set_attr "type" "ibr")
14400    (set_attr "length_immediate" "0")])
14401
14402 (define_insn "*indirect_jump_rtx64"
14403   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14404   "TARGET_64BIT"
14405   "jmp\t%A0"
14406   [(set_attr "type" "ibr")
14407    (set_attr "length_immediate" "0")])
14408
14409 (define_expand "tablejump"
14410   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14411               (use (label_ref (match_operand 1 "" "")))])]
14412   ""
14413 {
14414   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14415      relative.  Convert the relative address to an absolute address.  */
14416   if (flag_pic)
14417     {
14418       rtx op0, op1;
14419       enum rtx_code code;
14420
14421       /* We can't use @GOTOFF for text labels on VxWorks;
14422          see gotoff_operand.  */
14423       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14424         {
14425           code = PLUS;
14426           op0 = operands[0];
14427           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14428         }
14429       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14430         {
14431           code = PLUS;
14432           op0 = operands[0];
14433           op1 = pic_offset_table_rtx;
14434         }
14435       else
14436         {
14437           code = MINUS;
14438           op0 = pic_offset_table_rtx;
14439           op1 = operands[0];
14440         }
14441
14442       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14443                                          OPTAB_DIRECT);
14444     }
14445 })
14446
14447 (define_insn "*tablejump_1"
14448   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14449    (use (label_ref (match_operand 1 "" "")))]
14450   "!TARGET_64BIT"
14451   "jmp\t%A0"
14452   [(set_attr "type" "ibr")
14453    (set_attr "length_immediate" "0")])
14454
14455 (define_insn "*tablejump_1_rtx64"
14456   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14457    (use (label_ref (match_operand 1 "" "")))]
14458   "TARGET_64BIT"
14459   "jmp\t%A0"
14460   [(set_attr "type" "ibr")
14461    (set_attr "length_immediate" "0")])
14462 \f
14463 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14464
14465 (define_peephole2
14466   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14467    (set (match_operand:QI 1 "register_operand" "")
14468         (match_operator:QI 2 "ix86_comparison_operator"
14469           [(reg FLAGS_REG) (const_int 0)]))
14470    (set (match_operand 3 "q_regs_operand" "")
14471         (zero_extend (match_dup 1)))]
14472   "(peep2_reg_dead_p (3, operands[1])
14473     || operands_match_p (operands[1], operands[3]))
14474    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14475   [(set (match_dup 4) (match_dup 0))
14476    (set (strict_low_part (match_dup 5))
14477         (match_dup 2))]
14478 {
14479   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14480   operands[5] = gen_lowpart (QImode, operands[3]);
14481   ix86_expand_clear (operands[3]);
14482 })
14483
14484 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14485
14486 (define_peephole2
14487   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14488    (set (match_operand:QI 1 "register_operand" "")
14489         (match_operator:QI 2 "ix86_comparison_operator"
14490           [(reg FLAGS_REG) (const_int 0)]))
14491    (parallel [(set (match_operand 3 "q_regs_operand" "")
14492                    (zero_extend (match_dup 1)))
14493               (clobber (reg:CC FLAGS_REG))])]
14494   "(peep2_reg_dead_p (3, operands[1])
14495     || operands_match_p (operands[1], operands[3]))
14496    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14497   [(set (match_dup 4) (match_dup 0))
14498    (set (strict_low_part (match_dup 5))
14499         (match_dup 2))]
14500 {
14501   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14502   operands[5] = gen_lowpart (QImode, operands[3]);
14503   ix86_expand_clear (operands[3]);
14504 })
14505 \f
14506 ;; Call instructions.
14507
14508 ;; The predicates normally associated with named expanders are not properly
14509 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14510 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14511
14512 ;; Call subroutine returning no value.
14513
14514 (define_expand "call_pop"
14515   [(parallel [(call (match_operand:QI 0 "" "")
14516                     (match_operand:SI 1 "" ""))
14517               (set (reg:SI SP_REG)
14518                    (plus:SI (reg:SI SP_REG)
14519                             (match_operand:SI 3 "" "")))])]
14520   "!TARGET_64BIT"
14521 {
14522   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14523   DONE;
14524 })
14525
14526 (define_insn "*call_pop_0"
14527   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14528          (match_operand:SI 1 "" ""))
14529    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14530                             (match_operand:SI 2 "immediate_operand" "")))]
14531   "!TARGET_64BIT"
14532 {
14533   if (SIBLING_CALL_P (insn))
14534     return "jmp\t%P0";
14535   else
14536     return "call\t%P0";
14537 }
14538   [(set_attr "type" "call")])
14539
14540 (define_insn "*call_pop_1"
14541   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14542          (match_operand:SI 1 "" ""))
14543    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14544                             (match_operand:SI 2 "immediate_operand" "i")))]
14545   "!TARGET_64BIT"
14546 {
14547   if (constant_call_address_operand (operands[0], Pmode))
14548     {
14549       if (SIBLING_CALL_P (insn))
14550         return "jmp\t%P0";
14551       else
14552         return "call\t%P0";
14553     }
14554   if (SIBLING_CALL_P (insn))
14555     return "jmp\t%A0";
14556   else
14557     return "call\t%A0";
14558 }
14559   [(set_attr "type" "call")])
14560
14561 (define_expand "call"
14562   [(call (match_operand:QI 0 "" "")
14563          (match_operand 1 "" ""))
14564    (use (match_operand 2 "" ""))]
14565   ""
14566 {
14567   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14568   DONE;
14569 })
14570
14571 (define_expand "sibcall"
14572   [(call (match_operand:QI 0 "" "")
14573          (match_operand 1 "" ""))
14574    (use (match_operand 2 "" ""))]
14575   ""
14576 {
14577   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14578   DONE;
14579 })
14580
14581 (define_insn "*call_0"
14582   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14583          (match_operand 1 "" ""))]
14584   ""
14585 {
14586   if (SIBLING_CALL_P (insn))
14587     return "jmp\t%P0";
14588   else
14589     return "call\t%P0";
14590 }
14591   [(set_attr "type" "call")])
14592
14593 (define_insn "*call_1"
14594   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14595          (match_operand 1 "" ""))]
14596   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14597 {
14598   if (constant_call_address_operand (operands[0], Pmode))
14599     return "call\t%P0";
14600   return "call\t%A0";
14601 }
14602   [(set_attr "type" "call")])
14603
14604 (define_insn "*sibcall_1"
14605   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14606          (match_operand 1 "" ""))]
14607   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14608 {
14609   if (constant_call_address_operand (operands[0], Pmode))
14610     return "jmp\t%P0";
14611   return "jmp\t%A0";
14612 }
14613   [(set_attr "type" "call")])
14614
14615 (define_insn "*call_1_rex64"
14616   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14617          (match_operand 1 "" ""))]
14618   "!SIBLING_CALL_P (insn) && TARGET_64BIT
14619    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14620 {
14621   if (constant_call_address_operand (operands[0], Pmode))
14622     return "call\t%P0";
14623   return "call\t%A0";
14624 }
14625   [(set_attr "type" "call")])
14626
14627 (define_insn "*call_1_rex64_large"
14628   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14629          (match_operand 1 "" ""))]
14630   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14631   "call\t%A0"
14632   [(set_attr "type" "call")])
14633
14634 (define_insn "*sibcall_1_rex64"
14635   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14636          (match_operand 1 "" ""))]
14637   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14638   "jmp\t%P0"
14639   [(set_attr "type" "call")])
14640
14641 (define_insn "*sibcall_1_rex64_v"
14642   [(call (mem:QI (reg:DI R11_REG))
14643          (match_operand 0 "" ""))]
14644   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14645   "jmp\t{*%%}r11"
14646   [(set_attr "type" "call")])
14647
14648
14649 ;; Call subroutine, returning value in operand 0
14650
14651 (define_expand "call_value_pop"
14652   [(parallel [(set (match_operand 0 "" "")
14653                    (call (match_operand:QI 1 "" "")
14654                          (match_operand:SI 2 "" "")))
14655               (set (reg:SI SP_REG)
14656                    (plus:SI (reg:SI SP_REG)
14657                             (match_operand:SI 4 "" "")))])]
14658   "!TARGET_64BIT"
14659 {
14660   ix86_expand_call (operands[0], operands[1], operands[2],
14661                     operands[3], operands[4], 0);
14662   DONE;
14663 })
14664
14665 (define_expand "call_value"
14666   [(set (match_operand 0 "" "")
14667         (call (match_operand:QI 1 "" "")
14668               (match_operand:SI 2 "" "")))
14669    (use (match_operand:SI 3 "" ""))]
14670   ;; Operand 2 not used on the i386.
14671   ""
14672 {
14673   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14674   DONE;
14675 })
14676
14677 (define_expand "sibcall_value"
14678   [(set (match_operand 0 "" "")
14679         (call (match_operand:QI 1 "" "")
14680               (match_operand:SI 2 "" "")))
14681    (use (match_operand:SI 3 "" ""))]
14682   ;; Operand 2 not used on the i386.
14683   ""
14684 {
14685   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14686   DONE;
14687 })
14688
14689 ;; Call subroutine returning any type.
14690
14691 (define_expand "untyped_call"
14692   [(parallel [(call (match_operand 0 "" "")
14693                     (const_int 0))
14694               (match_operand 1 "" "")
14695               (match_operand 2 "" "")])]
14696   ""
14697 {
14698   int i;
14699
14700   /* In order to give reg-stack an easier job in validating two
14701      coprocessor registers as containing a possible return value,
14702      simply pretend the untyped call returns a complex long double
14703      value.  */
14704
14705   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14706                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14707                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14708                     NULL, 0);
14709
14710   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14711     {
14712       rtx set = XVECEXP (operands[2], 0, i);
14713       emit_move_insn (SET_DEST (set), SET_SRC (set));
14714     }
14715
14716   /* The optimizer does not know that the call sets the function value
14717      registers we stored in the result block.  We avoid problems by
14718      claiming that all hard registers are used and clobbered at this
14719      point.  */
14720   emit_insn (gen_blockage ());
14721
14722   DONE;
14723 })
14724 \f
14725 ;; Prologue and epilogue instructions
14726
14727 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14728 ;; all of memory.  This blocks insns from being moved across this point.
14729
14730 (define_insn "blockage"
14731   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14732   ""
14733   ""
14734   [(set_attr "length" "0")])
14735
14736 ;; As USE insns aren't meaningful after reload, this is used instead
14737 ;; to prevent deleting instructions setting registers for PIC code
14738 (define_insn "prologue_use"
14739   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14740   ""
14741   ""
14742   [(set_attr "length" "0")])
14743
14744 ;; Insn emitted into the body of a function to return from a function.
14745 ;; This is only done if the function's epilogue is known to be simple.
14746 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14747
14748 (define_expand "return"
14749   [(return)]
14750   "ix86_can_use_return_insn_p ()"
14751 {
14752   if (crtl->args.pops_args)
14753     {
14754       rtx popc = GEN_INT (crtl->args.pops_args);
14755       emit_jump_insn (gen_return_pop_internal (popc));
14756       DONE;
14757     }
14758 })
14759
14760 (define_insn "return_internal"
14761   [(return)]
14762   "reload_completed"
14763   "ret"
14764   [(set_attr "length" "1")
14765    (set_attr "length_immediate" "0")
14766    (set_attr "modrm" "0")])
14767
14768 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14769 ;; instruction Athlon and K8 have.
14770
14771 (define_insn "return_internal_long"
14772   [(return)
14773    (unspec [(const_int 0)] UNSPEC_REP)]
14774   "reload_completed"
14775   "rep\;ret"
14776   [(set_attr "length" "1")
14777    (set_attr "length_immediate" "0")
14778    (set_attr "prefix_rep" "1")
14779    (set_attr "modrm" "0")])
14780
14781 (define_insn "return_pop_internal"
14782   [(return)
14783    (use (match_operand:SI 0 "const_int_operand" ""))]
14784   "reload_completed"
14785   "ret\t%0"
14786   [(set_attr "length" "3")
14787    (set_attr "length_immediate" "2")
14788    (set_attr "modrm" "0")])
14789
14790 (define_insn "return_indirect_internal"
14791   [(return)
14792    (use (match_operand:SI 0 "register_operand" "r"))]
14793   "reload_completed"
14794   "jmp\t%A0"
14795   [(set_attr "type" "ibr")
14796    (set_attr "length_immediate" "0")])
14797
14798 (define_insn "nop"
14799   [(const_int 0)]
14800   ""
14801   "nop"
14802   [(set_attr "length" "1")
14803    (set_attr "length_immediate" "0")
14804    (set_attr "modrm" "0")])
14805
14806 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14807 ;; branch prediction penalty for the third jump in a 16-byte
14808 ;; block on K8.
14809
14810 (define_insn "align"
14811   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14812   ""
14813 {
14814 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14815   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14816 #else
14817   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14818      The align insn is used to avoid 3 jump instructions in the row to improve
14819      branch prediction and the benefits hardly outweigh the cost of extra 8
14820      nops on the average inserted by full alignment pseudo operation.  */
14821 #endif
14822   return "";
14823 }
14824   [(set_attr "length" "16")])
14825
14826 (define_expand "prologue"
14827   [(const_int 0)]
14828   ""
14829   "ix86_expand_prologue (); DONE;")
14830
14831 (define_insn "set_got"
14832   [(set (match_operand:SI 0 "register_operand" "=r")
14833         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14834    (clobber (reg:CC FLAGS_REG))]
14835   "!TARGET_64BIT"
14836   { return output_set_got (operands[0], NULL_RTX); }
14837   [(set_attr "type" "multi")
14838    (set_attr "length" "12")])
14839
14840 (define_insn "set_got_labelled"
14841   [(set (match_operand:SI 0 "register_operand" "=r")
14842         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14843          UNSPEC_SET_GOT))
14844    (clobber (reg:CC FLAGS_REG))]
14845   "!TARGET_64BIT"
14846   { return output_set_got (operands[0], operands[1]); }
14847   [(set_attr "type" "multi")
14848    (set_attr "length" "12")])
14849
14850 (define_insn "set_got_rex64"
14851   [(set (match_operand:DI 0 "register_operand" "=r")
14852         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14853   "TARGET_64BIT"
14854   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14855   [(set_attr "type" "lea")
14856    (set_attr "length" "6")])
14857
14858 (define_insn "set_rip_rex64"
14859   [(set (match_operand:DI 0 "register_operand" "=r")
14860         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14861   "TARGET_64BIT"
14862   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
14863   [(set_attr "type" "lea")
14864    (set_attr "length" "6")])
14865
14866 (define_insn "set_got_offset_rex64"
14867   [(set (match_operand:DI 0 "register_operand" "=r")
14868         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
14869   "TARGET_64BIT"
14870   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
14871   [(set_attr "type" "imov")
14872    (set_attr "length" "11")])
14873
14874 (define_expand "epilogue"
14875   [(const_int 0)]
14876   ""
14877   "ix86_expand_epilogue (1); DONE;")
14878
14879 (define_expand "sibcall_epilogue"
14880   [(const_int 0)]
14881   ""
14882   "ix86_expand_epilogue (0); DONE;")
14883
14884 (define_expand "eh_return"
14885   [(use (match_operand 0 "register_operand" ""))]
14886   ""
14887 {
14888   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14889
14890   /* Tricky bit: we write the address of the handler to which we will
14891      be returning into someone else's stack frame, one word below the
14892      stack address we wish to restore.  */
14893   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14894   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14895   tmp = gen_rtx_MEM (Pmode, tmp);
14896   emit_move_insn (tmp, ra);
14897
14898   if (Pmode == SImode)
14899     emit_jump_insn (gen_eh_return_si (sa));
14900   else
14901     emit_jump_insn (gen_eh_return_di (sa));
14902   emit_barrier ();
14903   DONE;
14904 })
14905
14906 (define_insn_and_split "eh_return_si"
14907   [(set (pc)
14908         (unspec [(match_operand:SI 0 "register_operand" "c")]
14909                  UNSPEC_EH_RETURN))]
14910   "!TARGET_64BIT"
14911   "#"
14912   "reload_completed"
14913   [(const_int 0)]
14914   "ix86_expand_epilogue (2); DONE;")
14915
14916 (define_insn_and_split "eh_return_di"
14917   [(set (pc)
14918         (unspec [(match_operand:DI 0 "register_operand" "c")]
14919                  UNSPEC_EH_RETURN))]
14920   "TARGET_64BIT"
14921   "#"
14922   "reload_completed"
14923   [(const_int 0)]
14924   "ix86_expand_epilogue (2); DONE;")
14925
14926 (define_insn "leave"
14927   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14928    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14929    (clobber (mem:BLK (scratch)))]
14930   "!TARGET_64BIT"
14931   "leave"
14932   [(set_attr "type" "leave")])
14933
14934 (define_insn "leave_rex64"
14935   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14936    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14937    (clobber (mem:BLK (scratch)))]
14938   "TARGET_64BIT"
14939   "leave"
14940   [(set_attr "type" "leave")])
14941 \f
14942 (define_expand "ffssi2"
14943   [(parallel
14944      [(set (match_operand:SI 0 "register_operand" "")
14945            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14946       (clobber (match_scratch:SI 2 ""))
14947       (clobber (reg:CC FLAGS_REG))])]
14948   ""
14949 {
14950   if (TARGET_CMOVE)
14951     {
14952       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
14953       DONE;
14954     }
14955 })
14956
14957 (define_expand "ffs_cmove"
14958   [(set (match_dup 2) (const_int -1))
14959    (parallel [(set (reg:CCZ FLAGS_REG)
14960                    (compare:CCZ (match_operand:SI 1 "register_operand" "")
14961                                 (const_int 0)))
14962               (set (match_operand:SI 0 "nonimmediate_operand" "")
14963                    (ctz:SI (match_dup 1)))])
14964    (set (match_dup 0) (if_then_else:SI
14965                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14966                         (match_dup 2)
14967                         (match_dup 0)))
14968    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14969               (clobber (reg:CC FLAGS_REG))])]
14970   "TARGET_CMOVE"
14971   "operands[2] = gen_reg_rtx (SImode);")
14972
14973 (define_insn_and_split "*ffs_no_cmove"
14974   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14975         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14976    (clobber (match_scratch:SI 2 "=&q"))
14977    (clobber (reg:CC FLAGS_REG))]
14978   "!TARGET_CMOVE"
14979   "#"
14980   "&& reload_completed"
14981   [(parallel [(set (reg:CCZ FLAGS_REG)
14982                    (compare:CCZ (match_dup 1) (const_int 0)))
14983               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14984    (set (strict_low_part (match_dup 3))
14985         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14986    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14987               (clobber (reg:CC FLAGS_REG))])
14988    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14989               (clobber (reg:CC FLAGS_REG))])
14990    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14991               (clobber (reg:CC FLAGS_REG))])]
14992 {
14993   operands[3] = gen_lowpart (QImode, operands[2]);
14994   ix86_expand_clear (operands[2]);
14995 })
14996
14997 (define_insn "*ffssi_1"
14998   [(set (reg:CCZ FLAGS_REG)
14999         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15000                      (const_int 0)))
15001    (set (match_operand:SI 0 "register_operand" "=r")
15002         (ctz:SI (match_dup 1)))]
15003   ""
15004   "bsf{l}\t{%1, %0|%0, %1}"
15005   [(set_attr "prefix_0f" "1")])
15006
15007 (define_expand "ffsdi2"
15008   [(set (match_dup 2) (const_int -1))
15009    (parallel [(set (reg:CCZ FLAGS_REG)
15010                    (compare:CCZ (match_operand:DI 1 "register_operand" "")
15011                                 (const_int 0)))
15012               (set (match_operand:DI 0 "nonimmediate_operand" "")
15013                    (ctz:DI (match_dup 1)))])
15014    (set (match_dup 0) (if_then_else:DI
15015                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15016                         (match_dup 2)
15017                         (match_dup 0)))
15018    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15019               (clobber (reg:CC FLAGS_REG))])]
15020   "TARGET_64BIT"
15021   "operands[2] = gen_reg_rtx (DImode);")
15022
15023 (define_insn "*ffsdi_1"
15024   [(set (reg:CCZ FLAGS_REG)
15025         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15026                      (const_int 0)))
15027    (set (match_operand:DI 0 "register_operand" "=r")
15028         (ctz:DI (match_dup 1)))]
15029   "TARGET_64BIT"
15030   "bsf{q}\t{%1, %0|%0, %1}"
15031   [(set_attr "prefix_0f" "1")])
15032
15033 (define_insn "ctzsi2"
15034   [(set (match_operand:SI 0 "register_operand" "=r")
15035         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15036    (clobber (reg:CC FLAGS_REG))]
15037   ""
15038   "bsf{l}\t{%1, %0|%0, %1}"
15039   [(set_attr "prefix_0f" "1")])
15040
15041 (define_insn "ctzdi2"
15042   [(set (match_operand:DI 0 "register_operand" "=r")
15043         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15044    (clobber (reg:CC FLAGS_REG))]
15045   "TARGET_64BIT"
15046   "bsf{q}\t{%1, %0|%0, %1}"
15047   [(set_attr "prefix_0f" "1")])
15048
15049 (define_expand "clzsi2"
15050   [(parallel
15051      [(set (match_operand:SI 0 "register_operand" "")
15052            (minus:SI (const_int 31)
15053                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15054       (clobber (reg:CC FLAGS_REG))])
15055    (parallel
15056      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15057       (clobber (reg:CC FLAGS_REG))])]
15058   ""
15059 {
15060   if (TARGET_ABM)
15061     {
15062       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15063       DONE;
15064     }
15065 })
15066
15067 (define_insn "clzsi2_abm"
15068   [(set (match_operand:SI 0 "register_operand" "=r")
15069         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15070    (clobber (reg:CC FLAGS_REG))]
15071   "TARGET_ABM"
15072   "lzcnt{l}\t{%1, %0|%0, %1}"
15073   [(set_attr "prefix_rep" "1")
15074    (set_attr "type" "bitmanip")
15075    (set_attr "mode" "SI")])
15076
15077 (define_insn "*bsr"
15078   [(set (match_operand:SI 0 "register_operand" "=r")
15079         (minus:SI (const_int 31)
15080                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15081    (clobber (reg:CC FLAGS_REG))]
15082   ""
15083   "bsr{l}\t{%1, %0|%0, %1}"
15084   [(set_attr "prefix_0f" "1")
15085    (set_attr "mode" "SI")])
15086
15087 (define_insn "popcountsi2"
15088   [(set (match_operand:SI 0 "register_operand" "=r")
15089         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15090    (clobber (reg:CC FLAGS_REG))]
15091   "TARGET_POPCNT"
15092   "popcnt{l}\t{%1, %0|%0, %1}"
15093   [(set_attr "prefix_rep" "1")
15094    (set_attr "type" "bitmanip")
15095    (set_attr "mode" "SI")])
15096
15097 (define_insn "*popcountsi2_cmp"
15098   [(set (reg FLAGS_REG)
15099         (compare
15100           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15101           (const_int 0)))
15102    (set (match_operand:SI 0 "register_operand" "=r")
15103         (popcount:SI (match_dup 1)))]
15104   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15105   "popcnt{l}\t{%1, %0|%0, %1}"
15106   [(set_attr "prefix_rep" "1")
15107    (set_attr "type" "bitmanip")
15108    (set_attr "mode" "SI")])
15109
15110 (define_insn "*popcountsi2_cmp_zext"
15111   [(set (reg FLAGS_REG)
15112         (compare
15113           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15114           (const_int 0)))
15115    (set (match_operand:DI 0 "register_operand" "=r")
15116         (zero_extend:DI(popcount:SI (match_dup 1))))]
15117   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15118   "popcnt{l}\t{%1, %0|%0, %1}"
15119   [(set_attr "prefix_rep" "1")
15120    (set_attr "type" "bitmanip")
15121    (set_attr "mode" "SI")])
15122
15123 (define_expand "bswapsi2"
15124   [(set (match_operand:SI 0 "register_operand" "")
15125         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15126   ""
15127 {
15128   if (!TARGET_BSWAP)
15129     {
15130       rtx x = operands[0];
15131
15132       emit_move_insn (x, operands[1]);
15133       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15134       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15135       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15136       DONE;
15137     }
15138 })
15139
15140 (define_insn "*bswapsi_1"
15141   [(set (match_operand:SI 0 "register_operand" "=r")
15142         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15143   "TARGET_BSWAP"
15144   "bswap\t%0"
15145   [(set_attr "prefix_0f" "1")
15146    (set_attr "length" "2")])
15147
15148 (define_insn "*bswaphi_lowpart_1"
15149   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15150         (bswap:HI (match_dup 0)))
15151    (clobber (reg:CC FLAGS_REG))]
15152   "TARGET_USE_XCHGB || optimize_size"
15153   "@
15154     xchg{b}\t{%h0, %b0|%b0, %h0}
15155     rol{w}\t{$8, %0|%0, 8}"
15156   [(set_attr "length" "2,4")
15157    (set_attr "mode" "QI,HI")])
15158
15159 (define_insn "bswaphi_lowpart"
15160   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15161         (bswap:HI (match_dup 0)))
15162    (clobber (reg:CC FLAGS_REG))]
15163   ""
15164   "rol{w}\t{$8, %0|%0, 8}"
15165   [(set_attr "length" "4")
15166    (set_attr "mode" "HI")])
15167
15168 (define_insn "bswapdi2"
15169   [(set (match_operand:DI 0 "register_operand" "=r")
15170         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15171   "TARGET_64BIT"
15172   "bswap\t%0"
15173   [(set_attr "prefix_0f" "1")
15174    (set_attr "length" "3")])
15175
15176 (define_expand "clzdi2"
15177   [(parallel
15178      [(set (match_operand:DI 0 "register_operand" "")
15179            (minus:DI (const_int 63)
15180                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15181       (clobber (reg:CC FLAGS_REG))])
15182    (parallel
15183      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15184       (clobber (reg:CC FLAGS_REG))])]
15185   "TARGET_64BIT"
15186 {
15187   if (TARGET_ABM)
15188     {
15189       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15190       DONE;
15191     }
15192 })
15193
15194 (define_insn "clzdi2_abm"
15195   [(set (match_operand:DI 0 "register_operand" "=r")
15196         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15197    (clobber (reg:CC FLAGS_REG))]
15198   "TARGET_64BIT && TARGET_ABM"
15199   "lzcnt{q}\t{%1, %0|%0, %1}"
15200   [(set_attr "prefix_rep" "1")
15201    (set_attr "type" "bitmanip")
15202    (set_attr "mode" "DI")])
15203
15204 (define_insn "*bsr_rex64"
15205   [(set (match_operand:DI 0 "register_operand" "=r")
15206         (minus:DI (const_int 63)
15207                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15208    (clobber (reg:CC FLAGS_REG))]
15209   "TARGET_64BIT"
15210   "bsr{q}\t{%1, %0|%0, %1}"
15211   [(set_attr "prefix_0f" "1")
15212    (set_attr "mode" "DI")])
15213
15214 (define_insn "popcountdi2"
15215   [(set (match_operand:DI 0 "register_operand" "=r")
15216         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15217    (clobber (reg:CC FLAGS_REG))]
15218   "TARGET_64BIT && TARGET_POPCNT"
15219   "popcnt{q}\t{%1, %0|%0, %1}"
15220   [(set_attr "prefix_rep" "1")
15221    (set_attr "type" "bitmanip")
15222    (set_attr "mode" "DI")])
15223
15224 (define_insn "*popcountdi2_cmp"
15225   [(set (reg FLAGS_REG)
15226         (compare
15227           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15228           (const_int 0)))
15229    (set (match_operand:DI 0 "register_operand" "=r")
15230         (popcount:DI (match_dup 1)))]
15231   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15232   "popcnt{q}\t{%1, %0|%0, %1}"
15233   [(set_attr "prefix_rep" "1")
15234    (set_attr "type" "bitmanip")
15235    (set_attr "mode" "DI")])
15236
15237 (define_expand "clzhi2"
15238   [(parallel
15239      [(set (match_operand:HI 0 "register_operand" "")
15240            (minus:HI (const_int 15)
15241                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15242       (clobber (reg:CC FLAGS_REG))])
15243    (parallel
15244      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15245       (clobber (reg:CC FLAGS_REG))])]
15246   ""
15247 {
15248   if (TARGET_ABM)
15249     {
15250       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15251       DONE;
15252     }
15253 })
15254
15255 (define_insn "clzhi2_abm"
15256   [(set (match_operand:HI 0 "register_operand" "=r")
15257         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15258    (clobber (reg:CC FLAGS_REG))]
15259   "TARGET_ABM"
15260   "lzcnt{w}\t{%1, %0|%0, %1}"
15261   [(set_attr "prefix_rep" "1")
15262    (set_attr "type" "bitmanip")
15263    (set_attr "mode" "HI")])
15264
15265 (define_insn "*bsrhi"
15266   [(set (match_operand:HI 0 "register_operand" "=r")
15267         (minus:HI (const_int 15)
15268                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15269    (clobber (reg:CC FLAGS_REG))]
15270   ""
15271   "bsr{w}\t{%1, %0|%0, %1}"
15272   [(set_attr "prefix_0f" "1")
15273    (set_attr "mode" "HI")])
15274
15275 (define_insn "popcounthi2"
15276   [(set (match_operand:HI 0 "register_operand" "=r")
15277         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15278    (clobber (reg:CC FLAGS_REG))]
15279   "TARGET_POPCNT"
15280   "popcnt{w}\t{%1, %0|%0, %1}"
15281   [(set_attr "prefix_rep" "1")
15282    (set_attr "type" "bitmanip")
15283    (set_attr "mode" "HI")])
15284
15285 (define_insn "*popcounthi2_cmp"
15286   [(set (reg FLAGS_REG)
15287         (compare
15288           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15289           (const_int 0)))
15290    (set (match_operand:HI 0 "register_operand" "=r")
15291         (popcount:HI (match_dup 1)))]
15292   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15293   "popcnt{w}\t{%1, %0|%0, %1}"
15294   [(set_attr "prefix_rep" "1")
15295    (set_attr "type" "bitmanip")
15296    (set_attr "mode" "HI")])
15297
15298 (define_expand "paritydi2"
15299   [(set (match_operand:DI 0 "register_operand" "")
15300         (parity:DI (match_operand:DI 1 "register_operand" "")))]
15301   "! TARGET_POPCNT"
15302 {
15303   rtx scratch = gen_reg_rtx (QImode);
15304   rtx cond;
15305
15306   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15307                                 NULL_RTX, operands[1]));
15308
15309   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15310                          gen_rtx_REG (CCmode, FLAGS_REG),
15311                          const0_rtx);
15312   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15313
15314   if (TARGET_64BIT)
15315     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15316   else
15317     {
15318       rtx tmp = gen_reg_rtx (SImode);
15319
15320       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15321       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15322     }
15323   DONE;
15324 })
15325
15326 (define_insn_and_split "paritydi2_cmp"
15327   [(set (reg:CC FLAGS_REG)
15328         (parity:CC (match_operand:DI 3 "register_operand" "0")))
15329    (clobber (match_scratch:DI 0 "=r"))
15330    (clobber (match_scratch:SI 1 "=&r"))
15331    (clobber (match_scratch:HI 2 "=Q"))]
15332   "! TARGET_POPCNT"
15333   "#"
15334   "&& reload_completed"
15335   [(parallel
15336      [(set (match_dup 1)
15337            (xor:SI (match_dup 1) (match_dup 4)))
15338       (clobber (reg:CC FLAGS_REG))])
15339    (parallel
15340      [(set (reg:CC FLAGS_REG)
15341            (parity:CC (match_dup 1)))
15342       (clobber (match_dup 1))
15343       (clobber (match_dup 2))])]
15344 {
15345   operands[4] = gen_lowpart (SImode, operands[3]);
15346
15347   if (TARGET_64BIT)
15348     {
15349       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15350       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15351     }
15352   else
15353     operands[1] = gen_highpart (SImode, operands[3]);
15354 })
15355
15356 (define_expand "paritysi2"
15357   [(set (match_operand:SI 0 "register_operand" "")
15358         (parity:SI (match_operand:SI 1 "register_operand" "")))]
15359   "! TARGET_POPCNT"
15360 {
15361   rtx scratch = gen_reg_rtx (QImode);
15362   rtx cond;
15363
15364   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15365
15366   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15367                          gen_rtx_REG (CCmode, FLAGS_REG),
15368                          const0_rtx);
15369   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15370
15371   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15372   DONE;
15373 })
15374
15375 (define_insn_and_split "paritysi2_cmp"
15376   [(set (reg:CC FLAGS_REG)
15377         (parity:CC (match_operand:SI 2 "register_operand" "0")))
15378    (clobber (match_scratch:SI 0 "=r"))
15379    (clobber (match_scratch:HI 1 "=&Q"))]
15380   "! TARGET_POPCNT"
15381   "#"
15382   "&& reload_completed"
15383   [(parallel
15384      [(set (match_dup 1)
15385            (xor:HI (match_dup 1) (match_dup 3)))
15386       (clobber (reg:CC FLAGS_REG))])
15387    (parallel
15388      [(set (reg:CC FLAGS_REG)
15389            (parity:CC (match_dup 1)))
15390       (clobber (match_dup 1))])]
15391 {
15392   operands[3] = gen_lowpart (HImode, operands[2]);
15393
15394   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15395   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15396 })
15397
15398 (define_insn "*parityhi2_cmp"
15399   [(set (reg:CC FLAGS_REG)
15400         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15401    (clobber (match_scratch:HI 0 "=Q"))]
15402   "! TARGET_POPCNT"
15403   "xor{b}\t{%h0, %b0|%b0, %h0}"
15404   [(set_attr "length" "2")
15405    (set_attr "mode" "HI")])
15406
15407 (define_insn "*parityqi2_cmp"
15408   [(set (reg:CC FLAGS_REG)
15409         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15410   "! TARGET_POPCNT"
15411   "test{b}\t%0, %0"
15412   [(set_attr "length" "2")
15413    (set_attr "mode" "QI")])
15414 \f
15415 ;; Thread-local storage patterns for ELF.
15416 ;;
15417 ;; Note that these code sequences must appear exactly as shown
15418 ;; in order to allow linker relaxation.
15419
15420 (define_insn "*tls_global_dynamic_32_gnu"
15421   [(set (match_operand:SI 0 "register_operand" "=a")
15422         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15423                     (match_operand:SI 2 "tls_symbolic_operand" "")
15424                     (match_operand:SI 3 "call_insn_operand" "")]
15425                     UNSPEC_TLS_GD))
15426    (clobber (match_scratch:SI 4 "=d"))
15427    (clobber (match_scratch:SI 5 "=c"))
15428    (clobber (reg:CC FLAGS_REG))]
15429   "!TARGET_64BIT && TARGET_GNU_TLS"
15430   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15431   [(set_attr "type" "multi")
15432    (set_attr "length" "12")])
15433
15434 (define_insn "*tls_global_dynamic_32_sun"
15435   [(set (match_operand:SI 0 "register_operand" "=a")
15436         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15437                     (match_operand:SI 2 "tls_symbolic_operand" "")
15438                     (match_operand:SI 3 "call_insn_operand" "")]
15439                     UNSPEC_TLS_GD))
15440    (clobber (match_scratch:SI 4 "=d"))
15441    (clobber (match_scratch:SI 5 "=c"))
15442    (clobber (reg:CC FLAGS_REG))]
15443   "!TARGET_64BIT && TARGET_SUN_TLS"
15444   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15445         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15446   [(set_attr "type" "multi")
15447    (set_attr "length" "14")])
15448
15449 (define_expand "tls_global_dynamic_32"
15450   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15451                    (unspec:SI
15452                     [(match_dup 2)
15453                      (match_operand:SI 1 "tls_symbolic_operand" "")
15454                      (match_dup 3)]
15455                     UNSPEC_TLS_GD))
15456               (clobber (match_scratch:SI 4 ""))
15457               (clobber (match_scratch:SI 5 ""))
15458               (clobber (reg:CC FLAGS_REG))])]
15459   ""
15460 {
15461   if (flag_pic)
15462     operands[2] = pic_offset_table_rtx;
15463   else
15464     {
15465       operands[2] = gen_reg_rtx (Pmode);
15466       emit_insn (gen_set_got (operands[2]));
15467     }
15468   if (TARGET_GNU2_TLS)
15469     {
15470        emit_insn (gen_tls_dynamic_gnu2_32
15471                   (operands[0], operands[1], operands[2]));
15472        DONE;
15473     }
15474   operands[3] = ix86_tls_get_addr ();
15475 })
15476
15477 (define_insn "*tls_global_dynamic_64"
15478   [(set (match_operand:DI 0 "register_operand" "=a")
15479         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15480                  (match_operand:DI 3 "" "")))
15481    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15482               UNSPEC_TLS_GD)]
15483   "TARGET_64BIT"
15484   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15485   [(set_attr "type" "multi")
15486    (set_attr "length" "16")])
15487
15488 (define_expand "tls_global_dynamic_64"
15489   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15490                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15491               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15492                          UNSPEC_TLS_GD)])]
15493   ""
15494 {
15495   if (TARGET_GNU2_TLS)
15496     {
15497        emit_insn (gen_tls_dynamic_gnu2_64
15498                   (operands[0], operands[1]));
15499        DONE;
15500     }
15501   operands[2] = ix86_tls_get_addr ();
15502 })
15503
15504 (define_insn "*tls_local_dynamic_base_32_gnu"
15505   [(set (match_operand:SI 0 "register_operand" "=a")
15506         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15507                     (match_operand:SI 2 "call_insn_operand" "")]
15508                    UNSPEC_TLS_LD_BASE))
15509    (clobber (match_scratch:SI 3 "=d"))
15510    (clobber (match_scratch:SI 4 "=c"))
15511    (clobber (reg:CC FLAGS_REG))]
15512   "!TARGET_64BIT && TARGET_GNU_TLS"
15513   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15514   [(set_attr "type" "multi")
15515    (set_attr "length" "11")])
15516
15517 (define_insn "*tls_local_dynamic_base_32_sun"
15518   [(set (match_operand:SI 0 "register_operand" "=a")
15519         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15520                     (match_operand:SI 2 "call_insn_operand" "")]
15521                    UNSPEC_TLS_LD_BASE))
15522    (clobber (match_scratch:SI 3 "=d"))
15523    (clobber (match_scratch:SI 4 "=c"))
15524    (clobber (reg:CC FLAGS_REG))]
15525   "!TARGET_64BIT && TARGET_SUN_TLS"
15526   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15527         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15528   [(set_attr "type" "multi")
15529    (set_attr "length" "13")])
15530
15531 (define_expand "tls_local_dynamic_base_32"
15532   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15533                    (unspec:SI [(match_dup 1) (match_dup 2)]
15534                               UNSPEC_TLS_LD_BASE))
15535               (clobber (match_scratch:SI 3 ""))
15536               (clobber (match_scratch:SI 4 ""))
15537               (clobber (reg:CC FLAGS_REG))])]
15538   ""
15539 {
15540   if (flag_pic)
15541     operands[1] = pic_offset_table_rtx;
15542   else
15543     {
15544       operands[1] = gen_reg_rtx (Pmode);
15545       emit_insn (gen_set_got (operands[1]));
15546     }
15547   if (TARGET_GNU2_TLS)
15548     {
15549        emit_insn (gen_tls_dynamic_gnu2_32
15550                   (operands[0], ix86_tls_module_base (), operands[1]));
15551        DONE;
15552     }
15553   operands[2] = ix86_tls_get_addr ();
15554 })
15555
15556 (define_insn "*tls_local_dynamic_base_64"
15557   [(set (match_operand:DI 0 "register_operand" "=a")
15558         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15559                  (match_operand:DI 2 "" "")))
15560    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15561   "TARGET_64BIT"
15562   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15563   [(set_attr "type" "multi")
15564    (set_attr "length" "12")])
15565
15566 (define_expand "tls_local_dynamic_base_64"
15567   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15568                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15569               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15570   ""
15571 {
15572   if (TARGET_GNU2_TLS)
15573     {
15574        emit_insn (gen_tls_dynamic_gnu2_64
15575                   (operands[0], ix86_tls_module_base ()));
15576        DONE;
15577     }
15578   operands[1] = ix86_tls_get_addr ();
15579 })
15580
15581 ;; Local dynamic of a single variable is a lose.  Show combine how
15582 ;; to convert that back to global dynamic.
15583
15584 (define_insn_and_split "*tls_local_dynamic_32_once"
15585   [(set (match_operand:SI 0 "register_operand" "=a")
15586         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15587                              (match_operand:SI 2 "call_insn_operand" "")]
15588                             UNSPEC_TLS_LD_BASE)
15589                  (const:SI (unspec:SI
15590                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15591                             UNSPEC_DTPOFF))))
15592    (clobber (match_scratch:SI 4 "=d"))
15593    (clobber (match_scratch:SI 5 "=c"))
15594    (clobber (reg:CC FLAGS_REG))]
15595   ""
15596   "#"
15597   ""
15598   [(parallel [(set (match_dup 0)
15599                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15600                               UNSPEC_TLS_GD))
15601               (clobber (match_dup 4))
15602               (clobber (match_dup 5))
15603               (clobber (reg:CC FLAGS_REG))])]
15604   "")
15605
15606 ;; Load and add the thread base pointer from %gs:0.
15607
15608 (define_insn "*load_tp_si"
15609   [(set (match_operand:SI 0 "register_operand" "=r")
15610         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15611   "!TARGET_64BIT"
15612   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15613   [(set_attr "type" "imov")
15614    (set_attr "modrm" "0")
15615    (set_attr "length" "7")
15616    (set_attr "memory" "load")
15617    (set_attr "imm_disp" "false")])
15618
15619 (define_insn "*add_tp_si"
15620   [(set (match_operand:SI 0 "register_operand" "=r")
15621         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15622                  (match_operand:SI 1 "register_operand" "0")))
15623    (clobber (reg:CC FLAGS_REG))]
15624   "!TARGET_64BIT"
15625   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15626   [(set_attr "type" "alu")
15627    (set_attr "modrm" "0")
15628    (set_attr "length" "7")
15629    (set_attr "memory" "load")
15630    (set_attr "imm_disp" "false")])
15631
15632 (define_insn "*load_tp_di"
15633   [(set (match_operand:DI 0 "register_operand" "=r")
15634         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15635   "TARGET_64BIT"
15636   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15637   [(set_attr "type" "imov")
15638    (set_attr "modrm" "0")
15639    (set_attr "length" "7")
15640    (set_attr "memory" "load")
15641    (set_attr "imm_disp" "false")])
15642
15643 (define_insn "*add_tp_di"
15644   [(set (match_operand:DI 0 "register_operand" "=r")
15645         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15646                  (match_operand:DI 1 "register_operand" "0")))
15647    (clobber (reg:CC FLAGS_REG))]
15648   "TARGET_64BIT"
15649   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15650   [(set_attr "type" "alu")
15651    (set_attr "modrm" "0")
15652    (set_attr "length" "7")
15653    (set_attr "memory" "load")
15654    (set_attr "imm_disp" "false")])
15655
15656 ;; GNU2 TLS patterns can be split.
15657
15658 (define_expand "tls_dynamic_gnu2_32"
15659   [(set (match_dup 3)
15660         (plus:SI (match_operand:SI 2 "register_operand" "")
15661                  (const:SI
15662                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15663                              UNSPEC_TLSDESC))))
15664    (parallel
15665     [(set (match_operand:SI 0 "register_operand" "")
15666           (unspec:SI [(match_dup 1) (match_dup 3)
15667                       (match_dup 2) (reg:SI SP_REG)]
15668                       UNSPEC_TLSDESC))
15669      (clobber (reg:CC FLAGS_REG))])]
15670   "!TARGET_64BIT && TARGET_GNU2_TLS"
15671 {
15672   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15673   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15674 })
15675
15676 (define_insn "*tls_dynamic_lea_32"
15677   [(set (match_operand:SI 0 "register_operand" "=r")
15678         (plus:SI (match_operand:SI 1 "register_operand" "b")
15679                  (const:SI
15680                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15681                               UNSPEC_TLSDESC))))]
15682   "!TARGET_64BIT && TARGET_GNU2_TLS"
15683   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15684   [(set_attr "type" "lea")
15685    (set_attr "mode" "SI")
15686    (set_attr "length" "6")
15687    (set_attr "length_address" "4")])
15688
15689 (define_insn "*tls_dynamic_call_32"
15690   [(set (match_operand:SI 0 "register_operand" "=a")
15691         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15692                     (match_operand:SI 2 "register_operand" "0")
15693                     ;; we have to make sure %ebx still points to the GOT
15694                     (match_operand:SI 3 "register_operand" "b")
15695                     (reg:SI SP_REG)]
15696                    UNSPEC_TLSDESC))
15697    (clobber (reg:CC FLAGS_REG))]
15698   "!TARGET_64BIT && TARGET_GNU2_TLS"
15699   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15700   [(set_attr "type" "call")
15701    (set_attr "length" "2")
15702    (set_attr "length_address" "0")])
15703
15704 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15705   [(set (match_operand:SI 0 "register_operand" "=&a")
15706         (plus:SI
15707          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15708                      (match_operand:SI 4 "" "")
15709                      (match_operand:SI 2 "register_operand" "b")
15710                      (reg:SI SP_REG)]
15711                     UNSPEC_TLSDESC)
15712          (const:SI (unspec:SI
15713                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15714                     UNSPEC_DTPOFF))))
15715    (clobber (reg:CC FLAGS_REG))]
15716   "!TARGET_64BIT && TARGET_GNU2_TLS"
15717   "#"
15718   ""
15719   [(set (match_dup 0) (match_dup 5))]
15720 {
15721   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15722   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15723 })
15724
15725 (define_expand "tls_dynamic_gnu2_64"
15726   [(set (match_dup 2)
15727         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15728                    UNSPEC_TLSDESC))
15729    (parallel
15730     [(set (match_operand:DI 0 "register_operand" "")
15731           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15732                      UNSPEC_TLSDESC))
15733      (clobber (reg:CC FLAGS_REG))])]
15734   "TARGET_64BIT && TARGET_GNU2_TLS"
15735 {
15736   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15737   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15738 })
15739
15740 (define_insn "*tls_dynamic_lea_64"
15741   [(set (match_operand:DI 0 "register_operand" "=r")
15742         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15743                    UNSPEC_TLSDESC))]
15744   "TARGET_64BIT && TARGET_GNU2_TLS"
15745   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15746   [(set_attr "type" "lea")
15747    (set_attr "mode" "DI")
15748    (set_attr "length" "7")
15749    (set_attr "length_address" "4")])
15750
15751 (define_insn "*tls_dynamic_call_64"
15752   [(set (match_operand:DI 0 "register_operand" "=a")
15753         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15754                     (match_operand:DI 2 "register_operand" "0")
15755                     (reg:DI SP_REG)]
15756                    UNSPEC_TLSDESC))
15757    (clobber (reg:CC FLAGS_REG))]
15758   "TARGET_64BIT && TARGET_GNU2_TLS"
15759   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15760   [(set_attr "type" "call")
15761    (set_attr "length" "2")
15762    (set_attr "length_address" "0")])
15763
15764 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15765   [(set (match_operand:DI 0 "register_operand" "=&a")
15766         (plus:DI
15767          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15768                      (match_operand:DI 3 "" "")
15769                      (reg:DI SP_REG)]
15770                     UNSPEC_TLSDESC)
15771          (const:DI (unspec:DI
15772                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15773                     UNSPEC_DTPOFF))))
15774    (clobber (reg:CC FLAGS_REG))]
15775   "TARGET_64BIT && TARGET_GNU2_TLS"
15776   "#"
15777   ""
15778   [(set (match_dup 0) (match_dup 4))]
15779 {
15780   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15781   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15782 })
15783
15784 ;;
15785 \f
15786 ;; These patterns match the binary 387 instructions for addM3, subM3,
15787 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15788 ;; SFmode.  The first is the normal insn, the second the same insn but
15789 ;; with one operand a conversion, and the third the same insn but with
15790 ;; the other operand a conversion.  The conversion may be SFmode or
15791 ;; SImode if the target mode DFmode, but only SImode if the target mode
15792 ;; is SFmode.
15793
15794 ;; Gcc is slightly more smart about handling normal two address instructions
15795 ;; so use special patterns for add and mull.
15796
15797 (define_insn "*fop_sf_comm_mixed"
15798   [(set (match_operand:SF 0 "register_operand" "=f,x")
15799         (match_operator:SF 3 "binary_fp_operator"
15800                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15801                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15802   "TARGET_MIX_SSE_I387
15803    && COMMUTATIVE_ARITH_P (operands[3])
15804    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15805   "* return output_387_binary_op (insn, operands);"
15806   [(set (attr "type")
15807         (if_then_else (eq_attr "alternative" "1")
15808            (if_then_else (match_operand:SF 3 "mult_operator" "")
15809               (const_string "ssemul")
15810               (const_string "sseadd"))
15811            (if_then_else (match_operand:SF 3 "mult_operator" "")
15812               (const_string "fmul")
15813               (const_string "fop"))))
15814    (set_attr "mode" "SF")])
15815
15816 (define_insn "*fop_sf_comm_sse"
15817   [(set (match_operand:SF 0 "register_operand" "=x")
15818         (match_operator:SF 3 "binary_fp_operator"
15819                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15820                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15821   "TARGET_SSE_MATH
15822    && COMMUTATIVE_ARITH_P (operands[3])
15823    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15824   "* return output_387_binary_op (insn, operands);"
15825   [(set (attr "type")
15826         (if_then_else (match_operand:SF 3 "mult_operator" "")
15827            (const_string "ssemul")
15828            (const_string "sseadd")))
15829    (set_attr "mode" "SF")])
15830
15831 (define_insn "*fop_sf_comm_i387"
15832   [(set (match_operand:SF 0 "register_operand" "=f")
15833         (match_operator:SF 3 "binary_fp_operator"
15834                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15835                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15836   "TARGET_80387
15837    && COMMUTATIVE_ARITH_P (operands[3])
15838    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15839   "* return output_387_binary_op (insn, operands);"
15840   [(set (attr "type")
15841         (if_then_else (match_operand:SF 3 "mult_operator" "")
15842            (const_string "fmul")
15843            (const_string "fop")))
15844    (set_attr "mode" "SF")])
15845
15846 (define_insn "*fop_sf_1_mixed"
15847   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15848         (match_operator:SF 3 "binary_fp_operator"
15849                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15850                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15851   "TARGET_MIX_SSE_I387
15852    && !COMMUTATIVE_ARITH_P (operands[3])
15853    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15854   "* return output_387_binary_op (insn, operands);"
15855   [(set (attr "type")
15856         (cond [(and (eq_attr "alternative" "2")
15857                     (match_operand:SF 3 "mult_operator" ""))
15858                  (const_string "ssemul")
15859                (and (eq_attr "alternative" "2")
15860                     (match_operand:SF 3 "div_operator" ""))
15861                  (const_string "ssediv")
15862                (eq_attr "alternative" "2")
15863                  (const_string "sseadd")
15864                (match_operand:SF 3 "mult_operator" "")
15865                  (const_string "fmul")
15866                (match_operand:SF 3 "div_operator" "")
15867                  (const_string "fdiv")
15868               ]
15869               (const_string "fop")))
15870    (set_attr "mode" "SF")])
15871
15872 (define_insn "*rcpsf2_sse"
15873   [(set (match_operand:SF 0 "register_operand" "=x")
15874         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15875                    UNSPEC_RCP))]
15876   "TARGET_SSE_MATH"
15877   "rcpss\t{%1, %0|%0, %1}"
15878   [(set_attr "type" "sse")
15879    (set_attr "mode" "SF")])
15880
15881 (define_insn "*fop_sf_1_sse"
15882   [(set (match_operand:SF 0 "register_operand" "=x")
15883         (match_operator:SF 3 "binary_fp_operator"
15884                         [(match_operand:SF 1 "register_operand" "0")
15885                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15886   "TARGET_SSE_MATH
15887    && !COMMUTATIVE_ARITH_P (operands[3])"
15888   "* return output_387_binary_op (insn, operands);"
15889   [(set (attr "type")
15890         (cond [(match_operand:SF 3 "mult_operator" "")
15891                  (const_string "ssemul")
15892                (match_operand:SF 3 "div_operator" "")
15893                  (const_string "ssediv")
15894               ]
15895               (const_string "sseadd")))
15896    (set_attr "mode" "SF")])
15897
15898 ;; This pattern is not fully shadowed by the pattern above.
15899 (define_insn "*fop_sf_1_i387"
15900   [(set (match_operand:SF 0 "register_operand" "=f,f")
15901         (match_operator:SF 3 "binary_fp_operator"
15902                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15903                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15904   "TARGET_80387 && !TARGET_SSE_MATH
15905    && !COMMUTATIVE_ARITH_P (operands[3])
15906    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15907   "* return output_387_binary_op (insn, operands);"
15908   [(set (attr "type")
15909         (cond [(match_operand:SF 3 "mult_operator" "")
15910                  (const_string "fmul")
15911                (match_operand:SF 3 "div_operator" "")
15912                  (const_string "fdiv")
15913               ]
15914               (const_string "fop")))
15915    (set_attr "mode" "SF")])
15916
15917 ;; ??? Add SSE splitters for these!
15918 (define_insn "*fop_sf_2<mode>_i387"
15919   [(set (match_operand:SF 0 "register_operand" "=f,f")
15920         (match_operator:SF 3 "binary_fp_operator"
15921           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15922            (match_operand:SF 2 "register_operand" "0,0")]))]
15923   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15924   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15925   [(set (attr "type")
15926         (cond [(match_operand:SF 3 "mult_operator" "")
15927                  (const_string "fmul")
15928                (match_operand:SF 3 "div_operator" "")
15929                  (const_string "fdiv")
15930               ]
15931               (const_string "fop")))
15932    (set_attr "fp_int_src" "true")
15933    (set_attr "mode" "<MODE>")])
15934
15935 (define_insn "*fop_sf_3<mode>_i387"
15936   [(set (match_operand:SF 0 "register_operand" "=f,f")
15937         (match_operator:SF 3 "binary_fp_operator"
15938           [(match_operand:SF 1 "register_operand" "0,0")
15939            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15940   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15941   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15942   [(set (attr "type")
15943         (cond [(match_operand:SF 3 "mult_operator" "")
15944                  (const_string "fmul")
15945                (match_operand:SF 3 "div_operator" "")
15946                  (const_string "fdiv")
15947               ]
15948               (const_string "fop")))
15949    (set_attr "fp_int_src" "true")
15950    (set_attr "mode" "<MODE>")])
15951
15952 (define_insn "*fop_df_comm_mixed"
15953   [(set (match_operand:DF 0 "register_operand" "=f,x")
15954         (match_operator:DF 3 "binary_fp_operator"
15955           [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15956            (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15957   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15958    && COMMUTATIVE_ARITH_P (operands[3])
15959    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15960   "* return output_387_binary_op (insn, operands);"
15961   [(set (attr "type")
15962         (if_then_else (eq_attr "alternative" "1")
15963            (if_then_else (match_operand:DF 3 "mult_operator" "")
15964               (const_string "ssemul")
15965               (const_string "sseadd"))
15966            (if_then_else (match_operand:DF 3 "mult_operator" "")
15967               (const_string "fmul")
15968               (const_string "fop"))))
15969    (set_attr "mode" "DF")])
15970
15971 (define_insn "*fop_df_comm_sse"
15972   [(set (match_operand:DF 0 "register_operand" "=x")
15973         (match_operator:DF 3 "binary_fp_operator"
15974           [(match_operand:DF 1 "nonimmediate_operand" "%0")
15975            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15976   "TARGET_SSE2 && TARGET_SSE_MATH
15977    && COMMUTATIVE_ARITH_P (operands[3])
15978    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15979   "* return output_387_binary_op (insn, operands);"
15980   [(set (attr "type")
15981         (if_then_else (match_operand:DF 3 "mult_operator" "")
15982            (const_string "ssemul")
15983            (const_string "sseadd")))
15984    (set_attr "mode" "DF")])
15985
15986 (define_insn "*fop_df_comm_i387"
15987   [(set (match_operand:DF 0 "register_operand" "=f")
15988         (match_operator:DF 3 "binary_fp_operator"
15989                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15990                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15991   "TARGET_80387
15992    && COMMUTATIVE_ARITH_P (operands[3])
15993    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15994   "* return output_387_binary_op (insn, operands);"
15995   [(set (attr "type")
15996         (if_then_else (match_operand:DF 3 "mult_operator" "")
15997            (const_string "fmul")
15998            (const_string "fop")))
15999    (set_attr "mode" "DF")])
16000
16001 (define_insn "*fop_df_1_mixed"
16002   [(set (match_operand:DF 0 "register_operand" "=f,f,x")
16003         (match_operator:DF 3 "binary_fp_operator"
16004           [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
16005            (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
16006   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
16007    && !COMMUTATIVE_ARITH_P (operands[3])
16008    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16009   "* return output_387_binary_op (insn, operands);"
16010   [(set (attr "type")
16011         (cond [(and (eq_attr "alternative" "2")
16012                     (match_operand:DF 3 "mult_operator" ""))
16013                  (const_string "ssemul")
16014                (and (eq_attr "alternative" "2")
16015                     (match_operand:DF 3 "div_operator" ""))
16016                  (const_string "ssediv")
16017                (eq_attr "alternative" "2")
16018                  (const_string "sseadd")
16019                (match_operand:DF 3 "mult_operator" "")
16020                  (const_string "fmul")
16021                (match_operand:DF 3 "div_operator" "")
16022                  (const_string "fdiv")
16023               ]
16024               (const_string "fop")))
16025    (set_attr "mode" "DF")])
16026
16027 (define_insn "*fop_df_1_sse"
16028   [(set (match_operand:DF 0 "register_operand" "=x")
16029         (match_operator:DF 3 "binary_fp_operator"
16030           [(match_operand:DF 1 "register_operand" "0")
16031            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16032   "TARGET_SSE2 && TARGET_SSE_MATH
16033    && !COMMUTATIVE_ARITH_P (operands[3])"
16034   "* return output_387_binary_op (insn, operands);"
16035   [(set_attr "mode" "DF")
16036    (set (attr "type")
16037         (cond [(match_operand:DF 3 "mult_operator" "")
16038                  (const_string "ssemul")
16039                (match_operand:DF 3 "div_operator" "")
16040                  (const_string "ssediv")
16041               ]
16042               (const_string "sseadd")))])
16043
16044 ;; This pattern is not fully shadowed by the pattern above.
16045 (define_insn "*fop_df_1_i387"
16046   [(set (match_operand:DF 0 "register_operand" "=f,f")
16047         (match_operator:DF 3 "binary_fp_operator"
16048                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
16049                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
16050   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16051    && !COMMUTATIVE_ARITH_P (operands[3])
16052    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16053   "* return output_387_binary_op (insn, operands);"
16054   [(set (attr "type")
16055         (cond [(match_operand:DF 3 "mult_operator" "")
16056                  (const_string "fmul")
16057                (match_operand:DF 3 "div_operator" "")
16058                  (const_string "fdiv")
16059               ]
16060               (const_string "fop")))
16061    (set_attr "mode" "DF")])
16062
16063 ;; ??? Add SSE splitters for these!
16064 (define_insn "*fop_df_2<mode>_i387"
16065   [(set (match_operand:DF 0 "register_operand" "=f,f")
16066         (match_operator:DF 3 "binary_fp_operator"
16067            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16068             (match_operand:DF 2 "register_operand" "0,0")]))]
16069   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16070    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16071   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16072   [(set (attr "type")
16073         (cond [(match_operand:DF 3 "mult_operator" "")
16074                  (const_string "fmul")
16075                (match_operand:DF 3 "div_operator" "")
16076                  (const_string "fdiv")
16077               ]
16078               (const_string "fop")))
16079    (set_attr "fp_int_src" "true")
16080    (set_attr "mode" "<MODE>")])
16081
16082 (define_insn "*fop_df_3<mode>_i387"
16083   [(set (match_operand:DF 0 "register_operand" "=f,f")
16084         (match_operator:DF 3 "binary_fp_operator"
16085            [(match_operand:DF 1 "register_operand" "0,0")
16086             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16087   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16088    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16089   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16090   [(set (attr "type")
16091         (cond [(match_operand:DF 3 "mult_operator" "")
16092                  (const_string "fmul")
16093                (match_operand:DF 3 "div_operator" "")
16094                  (const_string "fdiv")
16095               ]
16096               (const_string "fop")))
16097    (set_attr "fp_int_src" "true")
16098    (set_attr "mode" "<MODE>")])
16099
16100 (define_insn "*fop_df_4_i387"
16101   [(set (match_operand:DF 0 "register_operand" "=f,f")
16102         (match_operator:DF 3 "binary_fp_operator"
16103            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16104             (match_operand:DF 2 "register_operand" "0,f")]))]
16105   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16106    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16107   "* return output_387_binary_op (insn, operands);"
16108   [(set (attr "type")
16109         (cond [(match_operand:DF 3 "mult_operator" "")
16110                  (const_string "fmul")
16111                (match_operand:DF 3 "div_operator" "")
16112                  (const_string "fdiv")
16113               ]
16114               (const_string "fop")))
16115    (set_attr "mode" "SF")])
16116
16117 (define_insn "*fop_df_5_i387"
16118   [(set (match_operand:DF 0 "register_operand" "=f,f")
16119         (match_operator:DF 3 "binary_fp_operator"
16120           [(match_operand:DF 1 "register_operand" "0,f")
16121            (float_extend:DF
16122             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16123   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16124   "* return output_387_binary_op (insn, operands);"
16125   [(set (attr "type")
16126         (cond [(match_operand:DF 3 "mult_operator" "")
16127                  (const_string "fmul")
16128                (match_operand:DF 3 "div_operator" "")
16129                  (const_string "fdiv")
16130               ]
16131               (const_string "fop")))
16132    (set_attr "mode" "SF")])
16133
16134 (define_insn "*fop_df_6_i387"
16135   [(set (match_operand:DF 0 "register_operand" "=f,f")
16136         (match_operator:DF 3 "binary_fp_operator"
16137           [(float_extend:DF
16138             (match_operand:SF 1 "register_operand" "0,f"))
16139            (float_extend:DF
16140             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16141   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16142   "* return output_387_binary_op (insn, operands);"
16143   [(set (attr "type")
16144         (cond [(match_operand:DF 3 "mult_operator" "")
16145                  (const_string "fmul")
16146                (match_operand:DF 3 "div_operator" "")
16147                  (const_string "fdiv")
16148               ]
16149               (const_string "fop")))
16150    (set_attr "mode" "SF")])
16151
16152 (define_insn "*fop_xf_comm_i387"
16153   [(set (match_operand:XF 0 "register_operand" "=f")
16154         (match_operator:XF 3 "binary_fp_operator"
16155                         [(match_operand:XF 1 "register_operand" "%0")
16156                          (match_operand:XF 2 "register_operand" "f")]))]
16157   "TARGET_80387
16158    && COMMUTATIVE_ARITH_P (operands[3])"
16159   "* return output_387_binary_op (insn, operands);"
16160   [(set (attr "type")
16161         (if_then_else (match_operand:XF 3 "mult_operator" "")
16162            (const_string "fmul")
16163            (const_string "fop")))
16164    (set_attr "mode" "XF")])
16165
16166 (define_insn "*fop_xf_1_i387"
16167   [(set (match_operand:XF 0 "register_operand" "=f,f")
16168         (match_operator:XF 3 "binary_fp_operator"
16169                         [(match_operand:XF 1 "register_operand" "0,f")
16170                          (match_operand:XF 2 "register_operand" "f,0")]))]
16171   "TARGET_80387
16172    && !COMMUTATIVE_ARITH_P (operands[3])"
16173   "* return output_387_binary_op (insn, operands);"
16174   [(set (attr "type")
16175         (cond [(match_operand:XF 3 "mult_operator" "")
16176                  (const_string "fmul")
16177                (match_operand:XF 3 "div_operator" "")
16178                  (const_string "fdiv")
16179               ]
16180               (const_string "fop")))
16181    (set_attr "mode" "XF")])
16182
16183 (define_insn "*fop_xf_2<mode>_i387"
16184   [(set (match_operand:XF 0 "register_operand" "=f,f")
16185         (match_operator:XF 3 "binary_fp_operator"
16186            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16187             (match_operand:XF 2 "register_operand" "0,0")]))]
16188   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16189   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16190   [(set (attr "type")
16191         (cond [(match_operand:XF 3 "mult_operator" "")
16192                  (const_string "fmul")
16193                (match_operand:XF 3 "div_operator" "")
16194                  (const_string "fdiv")
16195               ]
16196               (const_string "fop")))
16197    (set_attr "fp_int_src" "true")
16198    (set_attr "mode" "<MODE>")])
16199
16200 (define_insn "*fop_xf_3<mode>_i387"
16201   [(set (match_operand:XF 0 "register_operand" "=f,f")
16202         (match_operator:XF 3 "binary_fp_operator"
16203           [(match_operand:XF 1 "register_operand" "0,0")
16204            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16205   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16206   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16207   [(set (attr "type")
16208         (cond [(match_operand:XF 3 "mult_operator" "")
16209                  (const_string "fmul")
16210                (match_operand:XF 3 "div_operator" "")
16211                  (const_string "fdiv")
16212               ]
16213               (const_string "fop")))
16214    (set_attr "fp_int_src" "true")
16215    (set_attr "mode" "<MODE>")])
16216
16217 (define_insn "*fop_xf_4_i387"
16218   [(set (match_operand:XF 0 "register_operand" "=f,f")
16219         (match_operator:XF 3 "binary_fp_operator"
16220            [(float_extend:XF
16221               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16222             (match_operand:XF 2 "register_operand" "0,f")]))]
16223   "TARGET_80387"
16224   "* return output_387_binary_op (insn, operands);"
16225   [(set (attr "type")
16226         (cond [(match_operand:XF 3 "mult_operator" "")
16227                  (const_string "fmul")
16228                (match_operand:XF 3 "div_operator" "")
16229                  (const_string "fdiv")
16230               ]
16231               (const_string "fop")))
16232    (set_attr "mode" "SF")])
16233
16234 (define_insn "*fop_xf_5_i387"
16235   [(set (match_operand:XF 0 "register_operand" "=f,f")
16236         (match_operator:XF 3 "binary_fp_operator"
16237           [(match_operand:XF 1 "register_operand" "0,f")
16238            (float_extend:XF
16239              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16240   "TARGET_80387"
16241   "* return output_387_binary_op (insn, operands);"
16242   [(set (attr "type")
16243         (cond [(match_operand:XF 3 "mult_operator" "")
16244                  (const_string "fmul")
16245                (match_operand:XF 3 "div_operator" "")
16246                  (const_string "fdiv")
16247               ]
16248               (const_string "fop")))
16249    (set_attr "mode" "SF")])
16250
16251 (define_insn "*fop_xf_6_i387"
16252   [(set (match_operand:XF 0 "register_operand" "=f,f")
16253         (match_operator:XF 3 "binary_fp_operator"
16254           [(float_extend:XF
16255              (match_operand:MODEF 1 "register_operand" "0,f"))
16256            (float_extend:XF
16257              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16258   "TARGET_80387"
16259   "* return output_387_binary_op (insn, operands);"
16260   [(set (attr "type")
16261         (cond [(match_operand:XF 3 "mult_operator" "")
16262                  (const_string "fmul")
16263                (match_operand:XF 3 "div_operator" "")
16264                  (const_string "fdiv")
16265               ]
16266               (const_string "fop")))
16267    (set_attr "mode" "SF")])
16268
16269 (define_split
16270   [(set (match_operand 0 "register_operand" "")
16271         (match_operator 3 "binary_fp_operator"
16272            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16273             (match_operand 2 "register_operand" "")]))]
16274   "reload_completed
16275    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16276   [(const_int 0)]
16277 {
16278   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16279   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16280   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16281                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16282                                           GET_MODE (operands[3]),
16283                                           operands[4],
16284                                           operands[2])));
16285   ix86_free_from_memory (GET_MODE (operands[1]));
16286   DONE;
16287 })
16288
16289 (define_split
16290   [(set (match_operand 0 "register_operand" "")
16291         (match_operator 3 "binary_fp_operator"
16292            [(match_operand 1 "register_operand" "")
16293             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16294   "reload_completed
16295    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16296   [(const_int 0)]
16297 {
16298   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16299   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16300   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16301                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16302                                           GET_MODE (operands[3]),
16303                                           operands[1],
16304                                           operands[4])));
16305   ix86_free_from_memory (GET_MODE (operands[2]));
16306   DONE;
16307 })
16308 \f
16309 ;; FPU special functions.
16310
16311 ;; This pattern implements a no-op XFmode truncation for
16312 ;; all fancy i386 XFmode math functions.
16313
16314 (define_insn "truncxf<mode>2_i387_noop_unspec"
16315   [(set (match_operand:MODEF 0 "register_operand" "=f")
16316         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16317         UNSPEC_TRUNC_NOOP))]
16318   "TARGET_USE_FANCY_MATH_387"
16319   "* return output_387_reg_move (insn, operands);"
16320   [(set_attr "type" "fmov")
16321    (set_attr "mode" "<MODE>")])
16322
16323 (define_insn "sqrtxf2"
16324   [(set (match_operand:XF 0 "register_operand" "=f")
16325         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16326   "TARGET_USE_FANCY_MATH_387"
16327   "fsqrt"
16328   [(set_attr "type" "fpspc")
16329    (set_attr "mode" "XF")
16330    (set_attr "athlon_decode" "direct")
16331    (set_attr "amdfam10_decode" "direct")])
16332
16333 (define_insn "sqrt_extend<mode>xf2_i387"
16334   [(set (match_operand:XF 0 "register_operand" "=f")
16335         (sqrt:XF
16336           (float_extend:XF
16337             (match_operand:MODEF 1 "register_operand" "0"))))]
16338   "TARGET_USE_FANCY_MATH_387"
16339   "fsqrt"
16340   [(set_attr "type" "fpspc")
16341    (set_attr "mode" "XF")
16342    (set_attr "athlon_decode" "direct")
16343    (set_attr "amdfam10_decode" "direct")])
16344
16345 (define_insn "*rsqrtsf2_sse"
16346   [(set (match_operand:SF 0 "register_operand" "=x")
16347         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16348                    UNSPEC_RSQRT))]
16349   "TARGET_SSE_MATH"
16350   "rsqrtss\t{%1, %0|%0, %1}"
16351   [(set_attr "type" "sse")
16352    (set_attr "mode" "SF")])
16353
16354 (define_expand "rsqrtsf2"
16355   [(set (match_operand:SF 0 "register_operand" "")
16356         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16357                    UNSPEC_RSQRT))]
16358   "TARGET_SSE_MATH"
16359 {
16360   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16361   DONE;
16362 })
16363
16364 (define_insn "*sqrt<mode>2_sse"
16365   [(set (match_operand:MODEF 0 "register_operand" "=x")
16366         (sqrt:MODEF
16367           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16368   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16369   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16370   [(set_attr "type" "sse")
16371    (set_attr "mode" "<MODE>")
16372    (set_attr "athlon_decode" "*")
16373    (set_attr "amdfam10_decode" "*")])
16374
16375 (define_expand "sqrt<mode>2"
16376   [(set (match_operand:MODEF 0 "register_operand" "")
16377         (sqrt:MODEF
16378           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16379   "TARGET_USE_FANCY_MATH_387
16380    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16381 {
16382   if (<MODE>mode == SFmode
16383       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16384       && flag_finite_math_only && !flag_trapping_math
16385       && flag_unsafe_math_optimizations)
16386     {
16387       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16388       DONE;
16389     }
16390
16391   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16392     {
16393       rtx op0 = gen_reg_rtx (XFmode);
16394       rtx op1 = force_reg (<MODE>mode, operands[1]);
16395
16396       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16397       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16398       DONE;
16399    }
16400 })
16401
16402 (define_insn "fpremxf4_i387"
16403   [(set (match_operand:XF 0 "register_operand" "=f")
16404         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16405                     (match_operand:XF 3 "register_operand" "1")]
16406                    UNSPEC_FPREM_F))
16407    (set (match_operand:XF 1 "register_operand" "=u")
16408         (unspec:XF [(match_dup 2) (match_dup 3)]
16409                    UNSPEC_FPREM_U))
16410    (set (reg:CCFP FPSR_REG)
16411         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16412                      UNSPEC_C2_FLAG))]
16413   "TARGET_USE_FANCY_MATH_387"
16414   "fprem"
16415   [(set_attr "type" "fpspc")
16416    (set_attr "mode" "XF")])
16417
16418 (define_expand "fmodxf3"
16419   [(use (match_operand:XF 0 "register_operand" ""))
16420    (use (match_operand:XF 1 "general_operand" ""))
16421    (use (match_operand:XF 2 "general_operand" ""))]
16422   "TARGET_USE_FANCY_MATH_387"
16423 {
16424   rtx label = gen_label_rtx ();
16425
16426   rtx op1 = gen_reg_rtx (XFmode);
16427   rtx op2 = gen_reg_rtx (XFmode);
16428
16429   emit_move_insn (op1, operands[1]);
16430   emit_move_insn (op2, operands[2]);
16431
16432   emit_label (label);
16433   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16434   ix86_emit_fp_unordered_jump (label);
16435   LABEL_NUSES (label) = 1;
16436
16437   emit_move_insn (operands[0], op1);
16438   DONE;
16439 })
16440
16441 (define_expand "fmod<mode>3"
16442   [(use (match_operand:MODEF 0 "register_operand" ""))
16443    (use (match_operand:MODEF 1 "general_operand" ""))
16444    (use (match_operand:MODEF 2 "general_operand" ""))]
16445   "TARGET_USE_FANCY_MATH_387"
16446 {
16447   rtx label = gen_label_rtx ();
16448
16449   rtx op1 = gen_reg_rtx (XFmode);
16450   rtx op2 = gen_reg_rtx (XFmode);
16451
16452   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16453   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16454
16455   emit_label (label);
16456   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16457   ix86_emit_fp_unordered_jump (label);
16458   LABEL_NUSES (label) = 1;
16459
16460   /* Truncate the result properly for strict SSE math.  */
16461   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16462       && !TARGET_MIX_SSE_I387)
16463     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16464   else
16465     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16466
16467   DONE;
16468 })
16469
16470 (define_insn "fprem1xf4_i387"
16471   [(set (match_operand:XF 0 "register_operand" "=f")
16472         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16473                     (match_operand:XF 3 "register_operand" "1")]
16474                    UNSPEC_FPREM1_F))
16475    (set (match_operand:XF 1 "register_operand" "=u")
16476         (unspec:XF [(match_dup 2) (match_dup 3)]
16477                    UNSPEC_FPREM1_U))
16478    (set (reg:CCFP FPSR_REG)
16479         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16480                      UNSPEC_C2_FLAG))]
16481   "TARGET_USE_FANCY_MATH_387"
16482   "fprem1"
16483   [(set_attr "type" "fpspc")
16484    (set_attr "mode" "XF")])
16485
16486 (define_expand "remainderxf3"
16487   [(use (match_operand:XF 0 "register_operand" ""))
16488    (use (match_operand:XF 1 "general_operand" ""))
16489    (use (match_operand:XF 2 "general_operand" ""))]
16490   "TARGET_USE_FANCY_MATH_387"
16491 {
16492   rtx label = gen_label_rtx ();
16493
16494   rtx op1 = gen_reg_rtx (XFmode);
16495   rtx op2 = gen_reg_rtx (XFmode);
16496
16497   emit_move_insn (op1, operands[1]);
16498   emit_move_insn (op2, operands[2]);
16499
16500   emit_label (label);
16501   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16502   ix86_emit_fp_unordered_jump (label);
16503   LABEL_NUSES (label) = 1;
16504
16505   emit_move_insn (operands[0], op1);
16506   DONE;
16507 })
16508
16509 (define_expand "remainder<mode>3"
16510   [(use (match_operand:MODEF 0 "register_operand" ""))
16511    (use (match_operand:MODEF 1 "general_operand" ""))
16512    (use (match_operand:MODEF 2 "general_operand" ""))]
16513   "TARGET_USE_FANCY_MATH_387"
16514 {
16515   rtx label = gen_label_rtx ();
16516
16517   rtx op1 = gen_reg_rtx (XFmode);
16518   rtx op2 = gen_reg_rtx (XFmode);
16519
16520   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16521   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16522
16523   emit_label (label);
16524
16525   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16526   ix86_emit_fp_unordered_jump (label);
16527   LABEL_NUSES (label) = 1;
16528
16529   /* Truncate the result properly for strict SSE math.  */
16530   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16531       && !TARGET_MIX_SSE_I387)
16532     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16533   else
16534     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16535
16536   DONE;
16537 })
16538
16539 (define_insn "*sinxf2_i387"
16540   [(set (match_operand:XF 0 "register_operand" "=f")
16541         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16542   "TARGET_USE_FANCY_MATH_387
16543    && flag_unsafe_math_optimizations"
16544   "fsin"
16545   [(set_attr "type" "fpspc")
16546    (set_attr "mode" "XF")])
16547
16548 (define_insn "*sin_extend<mode>xf2_i387"
16549   [(set (match_operand:XF 0 "register_operand" "=f")
16550         (unspec:XF [(float_extend:XF
16551                       (match_operand:MODEF 1 "register_operand" "0"))]
16552                    UNSPEC_SIN))]
16553   "TARGET_USE_FANCY_MATH_387
16554    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16555        || TARGET_MIX_SSE_I387)
16556    && flag_unsafe_math_optimizations"
16557   "fsin"
16558   [(set_attr "type" "fpspc")
16559    (set_attr "mode" "XF")])
16560
16561 (define_insn "*cosxf2_i387"
16562   [(set (match_operand:XF 0 "register_operand" "=f")
16563         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16564   "TARGET_USE_FANCY_MATH_387
16565    && flag_unsafe_math_optimizations"
16566   "fcos"
16567   [(set_attr "type" "fpspc")
16568    (set_attr "mode" "XF")])
16569
16570 (define_insn "*cos_extend<mode>xf2_i387"
16571   [(set (match_operand:XF 0 "register_operand" "=f")
16572         (unspec:XF [(float_extend:XF
16573                       (match_operand:MODEF 1 "register_operand" "0"))]
16574                    UNSPEC_COS))]
16575   "TARGET_USE_FANCY_MATH_387
16576    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16577        || TARGET_MIX_SSE_I387)
16578    && flag_unsafe_math_optimizations"
16579   "fcos"
16580   [(set_attr "type" "fpspc")
16581    (set_attr "mode" "XF")])
16582
16583 ;; When sincos pattern is defined, sin and cos builtin functions will be
16584 ;; expanded to sincos pattern with one of its outputs left unused.
16585 ;; CSE pass will figure out if two sincos patterns can be combined,
16586 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16587 ;; depending on the unused output.
16588
16589 (define_insn "sincosxf3"
16590   [(set (match_operand:XF 0 "register_operand" "=f")
16591         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16592                    UNSPEC_SINCOS_COS))
16593    (set (match_operand:XF 1 "register_operand" "=u")
16594         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16595   "TARGET_USE_FANCY_MATH_387
16596    && flag_unsafe_math_optimizations"
16597   "fsincos"
16598   [(set_attr "type" "fpspc")
16599    (set_attr "mode" "XF")])
16600
16601 (define_split
16602   [(set (match_operand:XF 0 "register_operand" "")
16603         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16604                    UNSPEC_SINCOS_COS))
16605    (set (match_operand:XF 1 "register_operand" "")
16606         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16607   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16608    && !(reload_completed || reload_in_progress)"
16609   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16610   "")
16611
16612 (define_split
16613   [(set (match_operand:XF 0 "register_operand" "")
16614         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16615                    UNSPEC_SINCOS_COS))
16616    (set (match_operand:XF 1 "register_operand" "")
16617         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16618   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16619    && !(reload_completed || reload_in_progress)"
16620   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16621   "")
16622
16623 (define_insn "sincos_extend<mode>xf3_i387"
16624   [(set (match_operand:XF 0 "register_operand" "=f")
16625         (unspec:XF [(float_extend:XF
16626                       (match_operand:MODEF 2 "register_operand" "0"))]
16627                    UNSPEC_SINCOS_COS))
16628    (set (match_operand:XF 1 "register_operand" "=u")
16629         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16630   "TARGET_USE_FANCY_MATH_387
16631    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16632        || TARGET_MIX_SSE_I387)
16633    && flag_unsafe_math_optimizations"
16634   "fsincos"
16635   [(set_attr "type" "fpspc")
16636    (set_attr "mode" "XF")])
16637
16638 (define_split
16639   [(set (match_operand:XF 0 "register_operand" "")
16640         (unspec:XF [(float_extend:XF
16641                       (match_operand:MODEF 2 "register_operand" ""))]
16642                    UNSPEC_SINCOS_COS))
16643    (set (match_operand:XF 1 "register_operand" "")
16644         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16645   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16646    && !(reload_completed || reload_in_progress)"
16647   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16648   "")
16649
16650 (define_split
16651   [(set (match_operand:XF 0 "register_operand" "")
16652         (unspec:XF [(float_extend:XF
16653                       (match_operand:MODEF 2 "register_operand" ""))]
16654                    UNSPEC_SINCOS_COS))
16655    (set (match_operand:XF 1 "register_operand" "")
16656         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16657   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16658    && !(reload_completed || reload_in_progress)"
16659   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16660   "")
16661
16662 (define_expand "sincos<mode>3"
16663   [(use (match_operand:MODEF 0 "register_operand" ""))
16664    (use (match_operand:MODEF 1 "register_operand" ""))
16665    (use (match_operand:MODEF 2 "register_operand" ""))]
16666   "TARGET_USE_FANCY_MATH_387
16667    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16668        || TARGET_MIX_SSE_I387)
16669    && flag_unsafe_math_optimizations"
16670 {
16671   rtx op0 = gen_reg_rtx (XFmode);
16672   rtx op1 = gen_reg_rtx (XFmode);
16673
16674   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16675   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16676   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16677   DONE;
16678 })
16679
16680 (define_insn "fptanxf4_i387"
16681   [(set (match_operand:XF 0 "register_operand" "=f")
16682         (match_operand:XF 3 "const_double_operand" "F"))
16683    (set (match_operand:XF 1 "register_operand" "=u")
16684         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16685                    UNSPEC_TAN))]
16686   "TARGET_USE_FANCY_MATH_387
16687    && flag_unsafe_math_optimizations
16688    && standard_80387_constant_p (operands[3]) == 2"
16689   "fptan"
16690   [(set_attr "type" "fpspc")
16691    (set_attr "mode" "XF")])
16692
16693 (define_insn "fptan_extend<mode>xf4_i387"
16694   [(set (match_operand:MODEF 0 "register_operand" "=f")
16695         (match_operand:MODEF 3 "const_double_operand" "F"))
16696    (set (match_operand:XF 1 "register_operand" "=u")
16697         (unspec:XF [(float_extend:XF
16698                       (match_operand:MODEF 2 "register_operand" "0"))]
16699                    UNSPEC_TAN))]
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    && standard_80387_constant_p (operands[3]) == 2"
16705   "fptan"
16706   [(set_attr "type" "fpspc")
16707    (set_attr "mode" "XF")])
16708
16709 (define_expand "tanxf2"
16710   [(use (match_operand:XF 0 "register_operand" ""))
16711    (use (match_operand:XF 1 "register_operand" ""))]
16712   "TARGET_USE_FANCY_MATH_387
16713    && flag_unsafe_math_optimizations"
16714 {
16715   rtx one = gen_reg_rtx (XFmode);
16716   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16717
16718   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16719   DONE;
16720 })
16721
16722 (define_expand "tan<mode>2"
16723   [(use (match_operand:MODEF 0 "register_operand" ""))
16724    (use (match_operand:MODEF 1 "register_operand" ""))]
16725   "TARGET_USE_FANCY_MATH_387
16726    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16727        || TARGET_MIX_SSE_I387)
16728    && flag_unsafe_math_optimizations"
16729 {
16730   rtx op0 = gen_reg_rtx (XFmode);
16731
16732   rtx one = gen_reg_rtx (<MODE>mode);
16733   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16734
16735   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16736                                              operands[1], op2));
16737   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16738   DONE;
16739 })
16740
16741 (define_insn "*fpatanxf3_i387"
16742   [(set (match_operand:XF 0 "register_operand" "=f")
16743         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16744                     (match_operand:XF 2 "register_operand" "u")]
16745                    UNSPEC_FPATAN))
16746    (clobber (match_scratch:XF 3 "=2"))]
16747   "TARGET_USE_FANCY_MATH_387
16748    && flag_unsafe_math_optimizations"
16749   "fpatan"
16750   [(set_attr "type" "fpspc")
16751    (set_attr "mode" "XF")])
16752
16753 (define_insn "fpatan_extend<mode>xf3_i387"
16754   [(set (match_operand:XF 0 "register_operand" "=f")
16755         (unspec:XF [(float_extend:XF
16756                       (match_operand:MODEF 1 "register_operand" "0"))
16757                     (float_extend:XF
16758                       (match_operand:MODEF 2 "register_operand" "u"))]
16759                    UNSPEC_FPATAN))
16760    (clobber (match_scratch:XF 3 "=2"))]
16761   "TARGET_USE_FANCY_MATH_387
16762    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16763        || TARGET_MIX_SSE_I387)
16764    && flag_unsafe_math_optimizations"
16765   "fpatan"
16766   [(set_attr "type" "fpspc")
16767    (set_attr "mode" "XF")])
16768
16769 (define_expand "atan2xf3"
16770   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16771                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16772                                (match_operand:XF 1 "register_operand" "")]
16773                               UNSPEC_FPATAN))
16774               (clobber (match_scratch:XF 3 ""))])]
16775   "TARGET_USE_FANCY_MATH_387
16776    && flag_unsafe_math_optimizations"
16777   "")
16778
16779 (define_expand "atan2<mode>3"
16780   [(use (match_operand:MODEF 0 "register_operand" ""))
16781    (use (match_operand:MODEF 1 "register_operand" ""))
16782    (use (match_operand:MODEF 2 "register_operand" ""))]
16783   "TARGET_USE_FANCY_MATH_387
16784    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16785        || TARGET_MIX_SSE_I387)
16786    && flag_unsafe_math_optimizations"
16787 {
16788   rtx op0 = gen_reg_rtx (XFmode);
16789
16790   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16791   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16792   DONE;
16793 })
16794
16795 (define_expand "atanxf2"
16796   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16797                    (unspec:XF [(match_dup 2)
16798                                (match_operand:XF 1 "register_operand" "")]
16799                               UNSPEC_FPATAN))
16800               (clobber (match_scratch:XF 3 ""))])]
16801   "TARGET_USE_FANCY_MATH_387
16802    && flag_unsafe_math_optimizations"
16803 {
16804   operands[2] = gen_reg_rtx (XFmode);
16805   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16806 })
16807
16808 (define_expand "atan<mode>2"
16809   [(use (match_operand:MODEF 0 "register_operand" ""))
16810    (use (match_operand:MODEF 1 "register_operand" ""))]
16811   "TARGET_USE_FANCY_MATH_387
16812    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16813        || TARGET_MIX_SSE_I387)
16814    && flag_unsafe_math_optimizations"
16815 {
16816   rtx op0 = gen_reg_rtx (XFmode);
16817
16818   rtx op2 = gen_reg_rtx (<MODE>mode);
16819   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16820
16821   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16822   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16823   DONE;
16824 })
16825
16826 (define_expand "asinxf2"
16827   [(set (match_dup 2)
16828         (mult:XF (match_operand:XF 1 "register_operand" "")
16829                  (match_dup 1)))
16830    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16831    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16832    (parallel [(set (match_operand:XF 0 "register_operand" "")
16833                    (unspec:XF [(match_dup 5) (match_dup 1)]
16834                               UNSPEC_FPATAN))
16835               (clobber (match_scratch:XF 6 ""))])]
16836   "TARGET_USE_FANCY_MATH_387
16837    && flag_unsafe_math_optimizations && !optimize_size"
16838 {
16839   int i;
16840
16841   for (i = 2; i < 6; i++)
16842     operands[i] = gen_reg_rtx (XFmode);
16843
16844   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16845 })
16846
16847 (define_expand "asin<mode>2"
16848   [(use (match_operand:MODEF 0 "register_operand" ""))
16849    (use (match_operand:MODEF 1 "general_operand" ""))]
16850  "TARGET_USE_FANCY_MATH_387
16851    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16852        || TARGET_MIX_SSE_I387)
16853    && flag_unsafe_math_optimizations && !optimize_size"
16854 {
16855   rtx op0 = gen_reg_rtx (XFmode);
16856   rtx op1 = gen_reg_rtx (XFmode);
16857
16858   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16859   emit_insn (gen_asinxf2 (op0, op1));
16860   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16861   DONE;
16862 })
16863
16864 (define_expand "acosxf2"
16865   [(set (match_dup 2)
16866         (mult:XF (match_operand:XF 1 "register_operand" "")
16867                  (match_dup 1)))
16868    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16869    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16870    (parallel [(set (match_operand:XF 0 "register_operand" "")
16871                    (unspec:XF [(match_dup 1) (match_dup 5)]
16872                               UNSPEC_FPATAN))
16873               (clobber (match_scratch:XF 6 ""))])]
16874   "TARGET_USE_FANCY_MATH_387
16875    && flag_unsafe_math_optimizations && !optimize_size"
16876 {
16877   int i;
16878
16879   for (i = 2; i < 6; i++)
16880     operands[i] = gen_reg_rtx (XFmode);
16881
16882   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16883 })
16884
16885 (define_expand "acos<mode>2"
16886   [(use (match_operand:MODEF 0 "register_operand" ""))
16887    (use (match_operand:MODEF 1 "general_operand" ""))]
16888  "TARGET_USE_FANCY_MATH_387
16889    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16890        || TARGET_MIX_SSE_I387)
16891    && flag_unsafe_math_optimizations && !optimize_size"
16892 {
16893   rtx op0 = gen_reg_rtx (XFmode);
16894   rtx op1 = gen_reg_rtx (XFmode);
16895
16896   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16897   emit_insn (gen_acosxf2 (op0, op1));
16898   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16899   DONE;
16900 })
16901
16902 (define_insn "fyl2xxf3_i387"
16903   [(set (match_operand:XF 0 "register_operand" "=f")
16904         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16905                     (match_operand:XF 2 "register_operand" "u")]
16906                    UNSPEC_FYL2X))
16907    (clobber (match_scratch:XF 3 "=2"))]
16908   "TARGET_USE_FANCY_MATH_387
16909    && flag_unsafe_math_optimizations"
16910   "fyl2x"
16911   [(set_attr "type" "fpspc")
16912    (set_attr "mode" "XF")])
16913
16914 (define_insn "fyl2x_extend<mode>xf3_i387"
16915   [(set (match_operand:XF 0 "register_operand" "=f")
16916         (unspec:XF [(float_extend:XF
16917                       (match_operand:MODEF 1 "register_operand" "0"))
16918                     (match_operand:XF 2 "register_operand" "u")]
16919                    UNSPEC_FYL2X))
16920    (clobber (match_scratch:XF 3 "=2"))]
16921   "TARGET_USE_FANCY_MATH_387
16922    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16923        || TARGET_MIX_SSE_I387)
16924    && flag_unsafe_math_optimizations"
16925   "fyl2x"
16926   [(set_attr "type" "fpspc")
16927    (set_attr "mode" "XF")])
16928
16929 (define_expand "logxf2"
16930   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16931                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16932                                (match_dup 2)] UNSPEC_FYL2X))
16933               (clobber (match_scratch:XF 3 ""))])]
16934   "TARGET_USE_FANCY_MATH_387
16935    && flag_unsafe_math_optimizations"
16936 {
16937   operands[2] = gen_reg_rtx (XFmode);
16938   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16939 })
16940
16941 (define_expand "log<mode>2"
16942   [(use (match_operand:MODEF 0 "register_operand" ""))
16943    (use (match_operand:MODEF 1 "register_operand" ""))]
16944   "TARGET_USE_FANCY_MATH_387
16945    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16946        || TARGET_MIX_SSE_I387)
16947    && flag_unsafe_math_optimizations"
16948 {
16949   rtx op0 = gen_reg_rtx (XFmode);
16950
16951   rtx op2 = gen_reg_rtx (XFmode);
16952   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16953
16954   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16955   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16956   DONE;
16957 })
16958
16959 (define_expand "log10xf2"
16960   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16961                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16962                                (match_dup 2)] UNSPEC_FYL2X))
16963               (clobber (match_scratch:XF 3 ""))])]
16964   "TARGET_USE_FANCY_MATH_387
16965    && flag_unsafe_math_optimizations"
16966 {
16967   operands[2] = gen_reg_rtx (XFmode);
16968   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16969 })
16970
16971 (define_expand "log10<mode>2"
16972   [(use (match_operand:MODEF 0 "register_operand" ""))
16973    (use (match_operand:MODEF 1 "register_operand" ""))]
16974   "TARGET_USE_FANCY_MATH_387
16975    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16976        || TARGET_MIX_SSE_I387)
16977    && flag_unsafe_math_optimizations"
16978 {
16979   rtx op0 = gen_reg_rtx (XFmode);
16980
16981   rtx op2 = gen_reg_rtx (XFmode);
16982   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16983
16984   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16985   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16986   DONE;
16987 })
16988
16989 (define_expand "log2xf2"
16990   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16991                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16992                                (match_dup 2)] UNSPEC_FYL2X))
16993               (clobber (match_scratch:XF 3 ""))])]
16994   "TARGET_USE_FANCY_MATH_387
16995    && flag_unsafe_math_optimizations"
16996 {
16997   operands[2] = gen_reg_rtx (XFmode);
16998   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16999 })
17000
17001 (define_expand "log2<mode>2"
17002   [(use (match_operand:MODEF 0 "register_operand" ""))
17003    (use (match_operand:MODEF 1 "register_operand" ""))]
17004   "TARGET_USE_FANCY_MATH_387
17005    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17006        || TARGET_MIX_SSE_I387)
17007    && flag_unsafe_math_optimizations"
17008 {
17009   rtx op0 = gen_reg_rtx (XFmode);
17010
17011   rtx op2 = gen_reg_rtx (XFmode);
17012   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17013
17014   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17015   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17016   DONE;
17017 })
17018
17019 (define_insn "fyl2xp1xf3_i387"
17020   [(set (match_operand:XF 0 "register_operand" "=f")
17021         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17022                     (match_operand:XF 2 "register_operand" "u")]
17023                    UNSPEC_FYL2XP1))
17024    (clobber (match_scratch:XF 3 "=2"))]
17025   "TARGET_USE_FANCY_MATH_387
17026    && flag_unsafe_math_optimizations"
17027   "fyl2xp1"
17028   [(set_attr "type" "fpspc")
17029    (set_attr "mode" "XF")])
17030
17031 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17032   [(set (match_operand:XF 0 "register_operand" "=f")
17033         (unspec:XF [(float_extend:XF
17034                       (match_operand:MODEF 1 "register_operand" "0"))
17035                     (match_operand:XF 2 "register_operand" "u")]
17036                    UNSPEC_FYL2XP1))
17037    (clobber (match_scratch:XF 3 "=2"))]
17038   "TARGET_USE_FANCY_MATH_387
17039    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17040        || TARGET_MIX_SSE_I387)
17041    && flag_unsafe_math_optimizations"
17042   "fyl2xp1"
17043   [(set_attr "type" "fpspc")
17044    (set_attr "mode" "XF")])
17045
17046 (define_expand "log1pxf2"
17047   [(use (match_operand:XF 0 "register_operand" ""))
17048    (use (match_operand:XF 1 "register_operand" ""))]
17049   "TARGET_USE_FANCY_MATH_387
17050    && flag_unsafe_math_optimizations && !optimize_size"
17051 {
17052   ix86_emit_i387_log1p (operands[0], operands[1]);
17053   DONE;
17054 })
17055
17056 (define_expand "log1p<mode>2"
17057   [(use (match_operand:MODEF 0 "register_operand" ""))
17058    (use (match_operand:MODEF 1 "register_operand" ""))]
17059   "TARGET_USE_FANCY_MATH_387
17060    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17061        || TARGET_MIX_SSE_I387)
17062    && flag_unsafe_math_optimizations && !optimize_size"
17063 {
17064   rtx op0 = gen_reg_rtx (XFmode);
17065
17066   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17067
17068   ix86_emit_i387_log1p (op0, operands[1]);
17069   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17070   DONE;
17071 })
17072
17073 (define_insn "fxtractxf3_i387"
17074   [(set (match_operand:XF 0 "register_operand" "=f")
17075         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17076                    UNSPEC_XTRACT_FRACT))
17077    (set (match_operand:XF 1 "register_operand" "=u")
17078         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17079   "TARGET_USE_FANCY_MATH_387
17080    && flag_unsafe_math_optimizations"
17081   "fxtract"
17082   [(set_attr "type" "fpspc")
17083    (set_attr "mode" "XF")])
17084
17085 (define_insn "fxtract_extend<mode>xf3_i387"
17086   [(set (match_operand:XF 0 "register_operand" "=f")
17087         (unspec:XF [(float_extend:XF
17088                       (match_operand:MODEF 2 "register_operand" "0"))]
17089                    UNSPEC_XTRACT_FRACT))
17090    (set (match_operand:XF 1 "register_operand" "=u")
17091         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17092   "TARGET_USE_FANCY_MATH_387
17093    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17094        || TARGET_MIX_SSE_I387)
17095    && flag_unsafe_math_optimizations"
17096   "fxtract"
17097   [(set_attr "type" "fpspc")
17098    (set_attr "mode" "XF")])
17099
17100 (define_expand "logbxf2"
17101   [(parallel [(set (match_dup 2)
17102                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17103                               UNSPEC_XTRACT_FRACT))
17104               (set (match_operand:XF 0 "register_operand" "")
17105                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17106   "TARGET_USE_FANCY_MATH_387
17107    && flag_unsafe_math_optimizations"
17108 {
17109   operands[2] = gen_reg_rtx (XFmode);
17110 })
17111
17112 (define_expand "logb<mode>2"
17113   [(use (match_operand:MODEF 0 "register_operand" ""))
17114    (use (match_operand:MODEF 1 "register_operand" ""))]
17115   "TARGET_USE_FANCY_MATH_387
17116    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17117        || TARGET_MIX_SSE_I387)
17118    && flag_unsafe_math_optimizations"
17119 {
17120   rtx op0 = gen_reg_rtx (XFmode);
17121   rtx op1 = gen_reg_rtx (XFmode);
17122
17123   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17124   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17125   DONE;
17126 })
17127
17128 (define_expand "ilogbxf2"
17129   [(use (match_operand:SI 0 "register_operand" ""))
17130    (use (match_operand:XF 1 "register_operand" ""))]
17131   "TARGET_USE_FANCY_MATH_387
17132    && flag_unsafe_math_optimizations && !optimize_size"
17133 {
17134   rtx op0 = gen_reg_rtx (XFmode);
17135   rtx op1 = gen_reg_rtx (XFmode);
17136
17137   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17138   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17139   DONE;
17140 })
17141
17142 (define_expand "ilogb<mode>2"
17143   [(use (match_operand:SI 0 "register_operand" ""))
17144    (use (match_operand:MODEF 1 "register_operand" ""))]
17145   "TARGET_USE_FANCY_MATH_387
17146    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17147        || TARGET_MIX_SSE_I387)
17148    && flag_unsafe_math_optimizations && !optimize_size"
17149 {
17150   rtx op0 = gen_reg_rtx (XFmode);
17151   rtx op1 = gen_reg_rtx (XFmode);
17152
17153   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17154   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17155   DONE;
17156 })
17157
17158 (define_insn "*f2xm1xf2_i387"
17159   [(set (match_operand:XF 0 "register_operand" "=f")
17160         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17161                    UNSPEC_F2XM1))]
17162   "TARGET_USE_FANCY_MATH_387
17163    && flag_unsafe_math_optimizations"
17164   "f2xm1"
17165   [(set_attr "type" "fpspc")
17166    (set_attr "mode" "XF")])
17167
17168 (define_insn "*fscalexf4_i387"
17169   [(set (match_operand:XF 0 "register_operand" "=f")
17170         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17171                     (match_operand:XF 3 "register_operand" "1")]
17172                    UNSPEC_FSCALE_FRACT))
17173    (set (match_operand:XF 1 "register_operand" "=u")
17174         (unspec:XF [(match_dup 2) (match_dup 3)]
17175                    UNSPEC_FSCALE_EXP))]
17176   "TARGET_USE_FANCY_MATH_387
17177    && flag_unsafe_math_optimizations"
17178   "fscale"
17179   [(set_attr "type" "fpspc")
17180    (set_attr "mode" "XF")])
17181
17182 (define_expand "expNcorexf3"
17183   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17184                                (match_operand:XF 2 "register_operand" "")))
17185    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17186    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17187    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17188    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17189    (parallel [(set (match_operand:XF 0 "register_operand" "")
17190                    (unspec:XF [(match_dup 8) (match_dup 4)]
17191                               UNSPEC_FSCALE_FRACT))
17192               (set (match_dup 9)
17193                    (unspec:XF [(match_dup 8) (match_dup 4)]
17194                               UNSPEC_FSCALE_EXP))])]
17195   "TARGET_USE_FANCY_MATH_387
17196    && flag_unsafe_math_optimizations && !optimize_size"
17197 {
17198   int i;
17199
17200   for (i = 3; i < 10; i++)
17201     operands[i] = gen_reg_rtx (XFmode);
17202
17203   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17204 })
17205
17206 (define_expand "expxf2"
17207   [(use (match_operand:XF 0 "register_operand" ""))
17208    (use (match_operand:XF 1 "register_operand" ""))]
17209   "TARGET_USE_FANCY_MATH_387
17210    && flag_unsafe_math_optimizations && !optimize_size"
17211 {
17212   rtx op2 = gen_reg_rtx (XFmode);
17213   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17214
17215   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17216   DONE;
17217 })
17218
17219 (define_expand "exp<mode>2"
17220   [(use (match_operand:MODEF 0 "register_operand" ""))
17221    (use (match_operand:MODEF 1 "general_operand" ""))]
17222  "TARGET_USE_FANCY_MATH_387
17223    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17224        || TARGET_MIX_SSE_I387)
17225    && flag_unsafe_math_optimizations && !optimize_size"
17226 {
17227   rtx op0 = gen_reg_rtx (XFmode);
17228   rtx op1 = gen_reg_rtx (XFmode);
17229
17230   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17231   emit_insn (gen_expxf2 (op0, op1));
17232   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17233   DONE;
17234 })
17235
17236 (define_expand "exp10xf2"
17237   [(use (match_operand:XF 0 "register_operand" ""))
17238    (use (match_operand:XF 1 "register_operand" ""))]
17239   "TARGET_USE_FANCY_MATH_387
17240    && flag_unsafe_math_optimizations && !optimize_size"
17241 {
17242   rtx op2 = gen_reg_rtx (XFmode);
17243   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17244
17245   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17246   DONE;
17247 })
17248
17249 (define_expand "exp10<mode>2"
17250   [(use (match_operand:MODEF 0 "register_operand" ""))
17251    (use (match_operand:MODEF 1 "general_operand" ""))]
17252  "TARGET_USE_FANCY_MATH_387
17253    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17254        || TARGET_MIX_SSE_I387)
17255    && flag_unsafe_math_optimizations && !optimize_size"
17256 {
17257   rtx op0 = gen_reg_rtx (XFmode);
17258   rtx op1 = gen_reg_rtx (XFmode);
17259
17260   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17261   emit_insn (gen_exp10xf2 (op0, op1));
17262   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17263   DONE;
17264 })
17265
17266 (define_expand "exp2xf2"
17267   [(use (match_operand:XF 0 "register_operand" ""))
17268    (use (match_operand:XF 1 "register_operand" ""))]
17269   "TARGET_USE_FANCY_MATH_387
17270    && flag_unsafe_math_optimizations && !optimize_size"
17271 {
17272   rtx op2 = gen_reg_rtx (XFmode);
17273   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17274
17275   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17276   DONE;
17277 })
17278
17279 (define_expand "exp2<mode>2"
17280   [(use (match_operand:MODEF 0 "register_operand" ""))
17281    (use (match_operand:MODEF 1 "general_operand" ""))]
17282  "TARGET_USE_FANCY_MATH_387
17283    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17284        || TARGET_MIX_SSE_I387)
17285    && flag_unsafe_math_optimizations && !optimize_size"
17286 {
17287   rtx op0 = gen_reg_rtx (XFmode);
17288   rtx op1 = gen_reg_rtx (XFmode);
17289
17290   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17291   emit_insn (gen_exp2xf2 (op0, op1));
17292   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17293   DONE;
17294 })
17295
17296 (define_expand "expm1xf2"
17297   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17298                                (match_dup 2)))
17299    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17300    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17301    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17302    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17303    (parallel [(set (match_dup 7)
17304                    (unspec:XF [(match_dup 6) (match_dup 4)]
17305                               UNSPEC_FSCALE_FRACT))
17306               (set (match_dup 8)
17307                    (unspec:XF [(match_dup 6) (match_dup 4)]
17308                               UNSPEC_FSCALE_EXP))])
17309    (parallel [(set (match_dup 10)
17310                    (unspec:XF [(match_dup 9) (match_dup 8)]
17311                               UNSPEC_FSCALE_FRACT))
17312               (set (match_dup 11)
17313                    (unspec:XF [(match_dup 9) (match_dup 8)]
17314                               UNSPEC_FSCALE_EXP))])
17315    (set (match_dup 12) (minus:XF (match_dup 10)
17316                                  (float_extend:XF (match_dup 13))))
17317    (set (match_operand:XF 0 "register_operand" "")
17318         (plus:XF (match_dup 12) (match_dup 7)))]
17319   "TARGET_USE_FANCY_MATH_387
17320    && flag_unsafe_math_optimizations && !optimize_size"
17321 {
17322   int i;
17323
17324   for (i = 2; i < 13; i++)
17325     operands[i] = gen_reg_rtx (XFmode);
17326
17327   operands[13]
17328     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17329
17330   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17331 })
17332
17333 (define_expand "expm1<mode>2"
17334   [(use (match_operand:MODEF 0 "register_operand" ""))
17335    (use (match_operand:MODEF 1 "general_operand" ""))]
17336  "TARGET_USE_FANCY_MATH_387
17337    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17338        || TARGET_MIX_SSE_I387)
17339    && flag_unsafe_math_optimizations && !optimize_size"
17340 {
17341   rtx op0 = gen_reg_rtx (XFmode);
17342   rtx op1 = gen_reg_rtx (XFmode);
17343
17344   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17345   emit_insn (gen_expm1xf2 (op0, op1));
17346   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17347   DONE;
17348 })
17349
17350 (define_expand "ldexpxf3"
17351   [(set (match_dup 3)
17352         (float:XF (match_operand:SI 2 "register_operand" "")))
17353    (parallel [(set (match_operand:XF 0 " register_operand" "")
17354                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17355                                (match_dup 3)]
17356                               UNSPEC_FSCALE_FRACT))
17357               (set (match_dup 4)
17358                    (unspec:XF [(match_dup 1) (match_dup 3)]
17359                               UNSPEC_FSCALE_EXP))])]
17360   "TARGET_USE_FANCY_MATH_387
17361    && flag_unsafe_math_optimizations && !optimize_size"
17362 {
17363   operands[3] = gen_reg_rtx (XFmode);
17364   operands[4] = gen_reg_rtx (XFmode);
17365 })
17366
17367 (define_expand "ldexp<mode>3"
17368   [(use (match_operand:MODEF 0 "register_operand" ""))
17369    (use (match_operand:MODEF 1 "general_operand" ""))
17370    (use (match_operand:SI 2 "register_operand" ""))]
17371  "TARGET_USE_FANCY_MATH_387
17372    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17373        || TARGET_MIX_SSE_I387)
17374    && flag_unsafe_math_optimizations && !optimize_size"
17375 {
17376   rtx op0 = gen_reg_rtx (XFmode);
17377   rtx op1 = gen_reg_rtx (XFmode);
17378
17379   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17380   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17381   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17382   DONE;
17383 })
17384
17385 (define_expand "scalbxf3"
17386   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17387                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17388                                (match_operand:XF 2 "register_operand" "")]
17389                               UNSPEC_FSCALE_FRACT))
17390               (set (match_dup 3)
17391                    (unspec:XF [(match_dup 1) (match_dup 2)]
17392                               UNSPEC_FSCALE_EXP))])]
17393   "TARGET_USE_FANCY_MATH_387
17394    && flag_unsafe_math_optimizations && !optimize_size"
17395 {
17396   operands[3] = gen_reg_rtx (XFmode);
17397 })
17398
17399 (define_expand "scalb<mode>3"
17400   [(use (match_operand:MODEF 0 "register_operand" ""))
17401    (use (match_operand:MODEF 1 "general_operand" ""))
17402    (use (match_operand:MODEF 2 "register_operand" ""))]
17403  "TARGET_USE_FANCY_MATH_387
17404    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17405        || TARGET_MIX_SSE_I387)
17406    && flag_unsafe_math_optimizations && !optimize_size"
17407 {
17408   rtx op0 = gen_reg_rtx (XFmode);
17409   rtx op1 = gen_reg_rtx (XFmode);
17410   rtx op2 = gen_reg_rtx (XFmode);
17411
17412   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17413   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17414   emit_insn (gen_scalbxf3 (op0, op1, op2));
17415   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17416   DONE;
17417 })
17418 \f
17419
17420 (define_insn "sse4_1_round<mode>2"
17421   [(set (match_operand:MODEF 0 "register_operand" "=x")
17422         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17423                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
17424                       UNSPEC_ROUND))]
17425   "TARGET_ROUND"
17426   "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17427   [(set_attr "type" "ssecvt")
17428    (set_attr "prefix_extra" "1")
17429    (set_attr "mode" "<MODE>")])
17430
17431 (define_insn "rintxf2"
17432   [(set (match_operand:XF 0 "register_operand" "=f")
17433         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17434                    UNSPEC_FRNDINT))]
17435   "TARGET_USE_FANCY_MATH_387
17436    && flag_unsafe_math_optimizations"
17437   "frndint"
17438   [(set_attr "type" "fpspc")
17439    (set_attr "mode" "XF")])
17440
17441 (define_expand "rint<mode>2"
17442   [(use (match_operand:MODEF 0 "register_operand" ""))
17443    (use (match_operand:MODEF 1 "register_operand" ""))]
17444   "(TARGET_USE_FANCY_MATH_387
17445     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17446         || TARGET_MIX_SSE_I387)
17447     && flag_unsafe_math_optimizations)
17448    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17449        && !flag_trapping_math
17450        && (TARGET_ROUND || !optimize_size))"
17451 {
17452   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17453       && !flag_trapping_math
17454       && (TARGET_ROUND || !optimize_size))
17455     {
17456       if (TARGET_ROUND)
17457         emit_insn (gen_sse4_1_round<mode>2
17458                    (operands[0], operands[1], GEN_INT (0x04)));
17459       else
17460         ix86_expand_rint (operand0, operand1);
17461     }
17462   else
17463     {
17464       rtx op0 = gen_reg_rtx (XFmode);
17465       rtx op1 = gen_reg_rtx (XFmode);
17466
17467       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17468       emit_insn (gen_rintxf2 (op0, op1));
17469
17470       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17471     }
17472   DONE;
17473 })
17474
17475 (define_expand "round<mode>2"
17476   [(match_operand:MODEF 0 "register_operand" "")
17477    (match_operand:MODEF 1 "nonimmediate_operand" "")]
17478   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17479    && !flag_trapping_math && !flag_rounding_math
17480    && !optimize_size"
17481 {
17482   if (TARGET_64BIT || (<MODE>mode != DFmode))
17483     ix86_expand_round (operand0, operand1);
17484   else
17485     ix86_expand_rounddf_32 (operand0, operand1);
17486   DONE;
17487 })
17488
17489 (define_insn_and_split "*fistdi2_1"
17490   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17491         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17492                    UNSPEC_FIST))]
17493   "TARGET_USE_FANCY_MATH_387
17494    && !(reload_completed || reload_in_progress)"
17495   "#"
17496   "&& 1"
17497   [(const_int 0)]
17498 {
17499   if (memory_operand (operands[0], VOIDmode))
17500     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17501   else
17502     {
17503       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17504       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17505                                          operands[2]));
17506     }
17507   DONE;
17508 }
17509   [(set_attr "type" "fpspc")
17510    (set_attr "mode" "DI")])
17511
17512 (define_insn "fistdi2"
17513   [(set (match_operand:DI 0 "memory_operand" "=m")
17514         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17515                    UNSPEC_FIST))
17516    (clobber (match_scratch:XF 2 "=&1f"))]
17517   "TARGET_USE_FANCY_MATH_387"
17518   "* return output_fix_trunc (insn, operands, 0);"
17519   [(set_attr "type" "fpspc")
17520    (set_attr "mode" "DI")])
17521
17522 (define_insn "fistdi2_with_temp"
17523   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17524         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17525                    UNSPEC_FIST))
17526    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17527    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17528   "TARGET_USE_FANCY_MATH_387"
17529   "#"
17530   [(set_attr "type" "fpspc")
17531    (set_attr "mode" "DI")])
17532
17533 (define_split
17534   [(set (match_operand:DI 0 "register_operand" "")
17535         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17536                    UNSPEC_FIST))
17537    (clobber (match_operand:DI 2 "memory_operand" ""))
17538    (clobber (match_scratch 3 ""))]
17539   "reload_completed"
17540   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17541               (clobber (match_dup 3))])
17542    (set (match_dup 0) (match_dup 2))]
17543   "")
17544
17545 (define_split
17546   [(set (match_operand:DI 0 "memory_operand" "")
17547         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17548                    UNSPEC_FIST))
17549    (clobber (match_operand:DI 2 "memory_operand" ""))
17550    (clobber (match_scratch 3 ""))]
17551   "reload_completed"
17552   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17553               (clobber (match_dup 3))])]
17554   "")
17555
17556 (define_insn_and_split "*fist<mode>2_1"
17557   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17558         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17559                            UNSPEC_FIST))]
17560   "TARGET_USE_FANCY_MATH_387
17561    && !(reload_completed || reload_in_progress)"
17562   "#"
17563   "&& 1"
17564   [(const_int 0)]
17565 {
17566   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17567   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17568                                         operands[2]));
17569   DONE;
17570 }
17571   [(set_attr "type" "fpspc")
17572    (set_attr "mode" "<MODE>")])
17573
17574 (define_insn "fist<mode>2"
17575   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17576         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17577                            UNSPEC_FIST))]
17578   "TARGET_USE_FANCY_MATH_387"
17579   "* return output_fix_trunc (insn, operands, 0);"
17580   [(set_attr "type" "fpspc")
17581    (set_attr "mode" "<MODE>")])
17582
17583 (define_insn "fist<mode>2_with_temp"
17584   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17585         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17586                            UNSPEC_FIST))
17587    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17588   "TARGET_USE_FANCY_MATH_387"
17589   "#"
17590   [(set_attr "type" "fpspc")
17591    (set_attr "mode" "<MODE>")])
17592
17593 (define_split
17594   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17595         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17596                            UNSPEC_FIST))
17597    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17598   "reload_completed"
17599   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17600    (set (match_dup 0) (match_dup 2))]
17601   "")
17602
17603 (define_split
17604   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17605         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17606                            UNSPEC_FIST))
17607    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17608   "reload_completed"
17609   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17610   "")
17611
17612 (define_expand "lrintxf<mode>2"
17613   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17614      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17615                       UNSPEC_FIST))]
17616   "TARGET_USE_FANCY_MATH_387"
17617   "")
17618
17619 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17620   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17621      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17622                         UNSPEC_FIX_NOTRUNC))]
17623   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17624    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17625   "")
17626
17627 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17628   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17629    (match_operand:MODEF 1 "register_operand" "")]
17630   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17631    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17632    && !flag_trapping_math && !flag_rounding_math
17633    && !optimize_size"
17634 {
17635   ix86_expand_lround (operand0, operand1);
17636   DONE;
17637 })
17638
17639 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17640 (define_insn_and_split "frndintxf2_floor"
17641   [(set (match_operand:XF 0 "register_operand" "")
17642         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17643          UNSPEC_FRNDINT_FLOOR))
17644    (clobber (reg:CC FLAGS_REG))]
17645   "TARGET_USE_FANCY_MATH_387
17646    && flag_unsafe_math_optimizations
17647    && !(reload_completed || reload_in_progress)"
17648   "#"
17649   "&& 1"
17650   [(const_int 0)]
17651 {
17652   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17653
17654   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17655   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17656
17657   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17658                                         operands[2], operands[3]));
17659   DONE;
17660 }
17661   [(set_attr "type" "frndint")
17662    (set_attr "i387_cw" "floor")
17663    (set_attr "mode" "XF")])
17664
17665 (define_insn "frndintxf2_floor_i387"
17666   [(set (match_operand:XF 0 "register_operand" "=f")
17667         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17668          UNSPEC_FRNDINT_FLOOR))
17669    (use (match_operand:HI 2 "memory_operand" "m"))
17670    (use (match_operand:HI 3 "memory_operand" "m"))]
17671   "TARGET_USE_FANCY_MATH_387
17672    && flag_unsafe_math_optimizations"
17673   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17674   [(set_attr "type" "frndint")
17675    (set_attr "i387_cw" "floor")
17676    (set_attr "mode" "XF")])
17677
17678 (define_expand "floorxf2"
17679   [(use (match_operand:XF 0 "register_operand" ""))
17680    (use (match_operand:XF 1 "register_operand" ""))]
17681   "TARGET_USE_FANCY_MATH_387
17682    && flag_unsafe_math_optimizations && !optimize_size"
17683 {
17684   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17685   DONE;
17686 })
17687
17688 (define_expand "floor<mode>2"
17689   [(use (match_operand:MODEF 0 "register_operand" ""))
17690    (use (match_operand:MODEF 1 "register_operand" ""))]
17691   "(TARGET_USE_FANCY_MATH_387
17692     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17693         || TARGET_MIX_SSE_I387)
17694     && flag_unsafe_math_optimizations && !optimize_size)
17695    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17696        && !flag_trapping_math
17697        && (TARGET_ROUND || !optimize_size))"
17698 {
17699   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17700       && !flag_trapping_math
17701       && (TARGET_ROUND || !optimize_size))
17702     {
17703       if (TARGET_ROUND)
17704         emit_insn (gen_sse4_1_round<mode>2
17705                    (operands[0], operands[1], GEN_INT (0x01)));
17706       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17707         ix86_expand_floorceil (operand0, operand1, true);
17708       else
17709         ix86_expand_floorceildf_32 (operand0, operand1, true);
17710     }
17711   else
17712     {
17713       rtx op0 = gen_reg_rtx (XFmode);
17714       rtx op1 = gen_reg_rtx (XFmode);
17715
17716       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17717       emit_insn (gen_frndintxf2_floor (op0, op1));
17718
17719       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17720     }
17721   DONE;
17722 })
17723
17724 (define_insn_and_split "*fist<mode>2_floor_1"
17725   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17726         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17727          UNSPEC_FIST_FLOOR))
17728    (clobber (reg:CC FLAGS_REG))]
17729   "TARGET_USE_FANCY_MATH_387
17730    && flag_unsafe_math_optimizations
17731    && !(reload_completed || reload_in_progress)"
17732   "#"
17733   "&& 1"
17734   [(const_int 0)]
17735 {
17736   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17737
17738   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17739   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17740   if (memory_operand (operands[0], VOIDmode))
17741     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17742                                       operands[2], operands[3]));
17743   else
17744     {
17745       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17746       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17747                                                   operands[2], operands[3],
17748                                                   operands[4]));
17749     }
17750   DONE;
17751 }
17752   [(set_attr "type" "fistp")
17753    (set_attr "i387_cw" "floor")
17754    (set_attr "mode" "<MODE>")])
17755
17756 (define_insn "fistdi2_floor"
17757   [(set (match_operand:DI 0 "memory_operand" "=m")
17758         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17759          UNSPEC_FIST_FLOOR))
17760    (use (match_operand:HI 2 "memory_operand" "m"))
17761    (use (match_operand:HI 3 "memory_operand" "m"))
17762    (clobber (match_scratch:XF 4 "=&1f"))]
17763   "TARGET_USE_FANCY_MATH_387
17764    && flag_unsafe_math_optimizations"
17765   "* return output_fix_trunc (insn, operands, 0);"
17766   [(set_attr "type" "fistp")
17767    (set_attr "i387_cw" "floor")
17768    (set_attr "mode" "DI")])
17769
17770 (define_insn "fistdi2_floor_with_temp"
17771   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17772         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17773          UNSPEC_FIST_FLOOR))
17774    (use (match_operand:HI 2 "memory_operand" "m,m"))
17775    (use (match_operand:HI 3 "memory_operand" "m,m"))
17776    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17777    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17778   "TARGET_USE_FANCY_MATH_387
17779    && flag_unsafe_math_optimizations"
17780   "#"
17781   [(set_attr "type" "fistp")
17782    (set_attr "i387_cw" "floor")
17783    (set_attr "mode" "DI")])
17784
17785 (define_split
17786   [(set (match_operand:DI 0 "register_operand" "")
17787         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17788          UNSPEC_FIST_FLOOR))
17789    (use (match_operand:HI 2 "memory_operand" ""))
17790    (use (match_operand:HI 3 "memory_operand" ""))
17791    (clobber (match_operand:DI 4 "memory_operand" ""))
17792    (clobber (match_scratch 5 ""))]
17793   "reload_completed"
17794   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17795               (use (match_dup 2))
17796               (use (match_dup 3))
17797               (clobber (match_dup 5))])
17798    (set (match_dup 0) (match_dup 4))]
17799   "")
17800
17801 (define_split
17802   [(set (match_operand:DI 0 "memory_operand" "")
17803         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17804          UNSPEC_FIST_FLOOR))
17805    (use (match_operand:HI 2 "memory_operand" ""))
17806    (use (match_operand:HI 3 "memory_operand" ""))
17807    (clobber (match_operand:DI 4 "memory_operand" ""))
17808    (clobber (match_scratch 5 ""))]
17809   "reload_completed"
17810   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17811               (use (match_dup 2))
17812               (use (match_dup 3))
17813               (clobber (match_dup 5))])]
17814   "")
17815
17816 (define_insn "fist<mode>2_floor"
17817   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17818         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17819          UNSPEC_FIST_FLOOR))
17820    (use (match_operand:HI 2 "memory_operand" "m"))
17821    (use (match_operand:HI 3 "memory_operand" "m"))]
17822   "TARGET_USE_FANCY_MATH_387
17823    && flag_unsafe_math_optimizations"
17824   "* return output_fix_trunc (insn, operands, 0);"
17825   [(set_attr "type" "fistp")
17826    (set_attr "i387_cw" "floor")
17827    (set_attr "mode" "<MODE>")])
17828
17829 (define_insn "fist<mode>2_floor_with_temp"
17830   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17831         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17832          UNSPEC_FIST_FLOOR))
17833    (use (match_operand:HI 2 "memory_operand" "m,m"))
17834    (use (match_operand:HI 3 "memory_operand" "m,m"))
17835    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17836   "TARGET_USE_FANCY_MATH_387
17837    && flag_unsafe_math_optimizations"
17838   "#"
17839   [(set_attr "type" "fistp")
17840    (set_attr "i387_cw" "floor")
17841    (set_attr "mode" "<MODE>")])
17842
17843 (define_split
17844   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17845         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17846          UNSPEC_FIST_FLOOR))
17847    (use (match_operand:HI 2 "memory_operand" ""))
17848    (use (match_operand:HI 3 "memory_operand" ""))
17849    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17850   "reload_completed"
17851   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17852                                   UNSPEC_FIST_FLOOR))
17853               (use (match_dup 2))
17854               (use (match_dup 3))])
17855    (set (match_dup 0) (match_dup 4))]
17856   "")
17857
17858 (define_split
17859   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17860         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17861          UNSPEC_FIST_FLOOR))
17862    (use (match_operand:HI 2 "memory_operand" ""))
17863    (use (match_operand:HI 3 "memory_operand" ""))
17864    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17865   "reload_completed"
17866   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17867                                   UNSPEC_FIST_FLOOR))
17868               (use (match_dup 2))
17869               (use (match_dup 3))])]
17870   "")
17871
17872 (define_expand "lfloorxf<mode>2"
17873   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17874                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17875                     UNSPEC_FIST_FLOOR))
17876               (clobber (reg:CC FLAGS_REG))])]
17877   "TARGET_USE_FANCY_MATH_387
17878    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17879    && flag_unsafe_math_optimizations"
17880   "")
17881
17882 (define_expand "lfloor<mode>di2"
17883   [(match_operand:DI 0 "nonimmediate_operand" "")
17884    (match_operand:MODEF 1 "register_operand" "")]
17885   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17886    && !flag_trapping_math
17887    && !optimize_size"
17888 {
17889   ix86_expand_lfloorceil (operand0, operand1, true);
17890   DONE;
17891 })
17892
17893 (define_expand "lfloor<mode>si2"
17894   [(match_operand:SI 0 "nonimmediate_operand" "")
17895    (match_operand:MODEF 1 "register_operand" "")]
17896   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17897    && !flag_trapping_math
17898    && (!optimize_size || !TARGET_64BIT)"
17899 {
17900   ix86_expand_lfloorceil (operand0, operand1, true);
17901   DONE;
17902 })
17903
17904 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17905 (define_insn_and_split "frndintxf2_ceil"
17906   [(set (match_operand:XF 0 "register_operand" "")
17907         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17908          UNSPEC_FRNDINT_CEIL))
17909    (clobber (reg:CC FLAGS_REG))]
17910   "TARGET_USE_FANCY_MATH_387
17911    && flag_unsafe_math_optimizations
17912    && !(reload_completed || reload_in_progress)"
17913   "#"
17914   "&& 1"
17915   [(const_int 0)]
17916 {
17917   ix86_optimize_mode_switching[I387_CEIL] = 1;
17918
17919   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17920   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17921
17922   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17923                                        operands[2], operands[3]));
17924   DONE;
17925 }
17926   [(set_attr "type" "frndint")
17927    (set_attr "i387_cw" "ceil")
17928    (set_attr "mode" "XF")])
17929
17930 (define_insn "frndintxf2_ceil_i387"
17931   [(set (match_operand:XF 0 "register_operand" "=f")
17932         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17933          UNSPEC_FRNDINT_CEIL))
17934    (use (match_operand:HI 2 "memory_operand" "m"))
17935    (use (match_operand:HI 3 "memory_operand" "m"))]
17936   "TARGET_USE_FANCY_MATH_387
17937    && flag_unsafe_math_optimizations"
17938   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17939   [(set_attr "type" "frndint")
17940    (set_attr "i387_cw" "ceil")
17941    (set_attr "mode" "XF")])
17942
17943 (define_expand "ceilxf2"
17944   [(use (match_operand:XF 0 "register_operand" ""))
17945    (use (match_operand:XF 1 "register_operand" ""))]
17946   "TARGET_USE_FANCY_MATH_387
17947    && flag_unsafe_math_optimizations && !optimize_size"
17948 {
17949   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17950   DONE;
17951 })
17952
17953 (define_expand "ceil<mode>2"
17954   [(use (match_operand:MODEF 0 "register_operand" ""))
17955    (use (match_operand:MODEF 1 "register_operand" ""))]
17956   "(TARGET_USE_FANCY_MATH_387
17957     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17958         || TARGET_MIX_SSE_I387)
17959     && flag_unsafe_math_optimizations && !optimize_size)
17960    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17961        && !flag_trapping_math
17962        && (TARGET_ROUND || !optimize_size))"
17963 {
17964   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17965       && !flag_trapping_math
17966       && (TARGET_ROUND || !optimize_size))
17967     {
17968       if (TARGET_ROUND)
17969         emit_insn (gen_sse4_1_round<mode>2
17970                    (operands[0], operands[1], GEN_INT (0x02)));
17971       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17972         ix86_expand_floorceil (operand0, operand1, false);
17973       else
17974         ix86_expand_floorceildf_32 (operand0, operand1, false);
17975     }
17976   else
17977     {
17978       rtx op0 = gen_reg_rtx (XFmode);
17979       rtx op1 = gen_reg_rtx (XFmode);
17980
17981       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17982       emit_insn (gen_frndintxf2_ceil (op0, op1));
17983
17984       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17985     }
17986   DONE;
17987 })
17988
17989 (define_insn_and_split "*fist<mode>2_ceil_1"
17990   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17991         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17992          UNSPEC_FIST_CEIL))
17993    (clobber (reg:CC FLAGS_REG))]
17994   "TARGET_USE_FANCY_MATH_387
17995    && flag_unsafe_math_optimizations
17996    && !(reload_completed || reload_in_progress)"
17997   "#"
17998   "&& 1"
17999   [(const_int 0)]
18000 {
18001   ix86_optimize_mode_switching[I387_CEIL] = 1;
18002
18003   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18004   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18005   if (memory_operand (operands[0], VOIDmode))
18006     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18007                                      operands[2], operands[3]));
18008   else
18009     {
18010       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18011       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18012                                                  operands[2], operands[3],
18013                                                  operands[4]));
18014     }
18015   DONE;
18016 }
18017   [(set_attr "type" "fistp")
18018    (set_attr "i387_cw" "ceil")
18019    (set_attr "mode" "<MODE>")])
18020
18021 (define_insn "fistdi2_ceil"
18022   [(set (match_operand:DI 0 "memory_operand" "=m")
18023         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18024          UNSPEC_FIST_CEIL))
18025    (use (match_operand:HI 2 "memory_operand" "m"))
18026    (use (match_operand:HI 3 "memory_operand" "m"))
18027    (clobber (match_scratch:XF 4 "=&1f"))]
18028   "TARGET_USE_FANCY_MATH_387
18029    && flag_unsafe_math_optimizations"
18030   "* return output_fix_trunc (insn, operands, 0);"
18031   [(set_attr "type" "fistp")
18032    (set_attr "i387_cw" "ceil")
18033    (set_attr "mode" "DI")])
18034
18035 (define_insn "fistdi2_ceil_with_temp"
18036   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18037         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18038          UNSPEC_FIST_CEIL))
18039    (use (match_operand:HI 2 "memory_operand" "m,m"))
18040    (use (match_operand:HI 3 "memory_operand" "m,m"))
18041    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18042    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18043   "TARGET_USE_FANCY_MATH_387
18044    && flag_unsafe_math_optimizations"
18045   "#"
18046   [(set_attr "type" "fistp")
18047    (set_attr "i387_cw" "ceil")
18048    (set_attr "mode" "DI")])
18049
18050 (define_split
18051   [(set (match_operand:DI 0 "register_operand" "")
18052         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18053          UNSPEC_FIST_CEIL))
18054    (use (match_operand:HI 2 "memory_operand" ""))
18055    (use (match_operand:HI 3 "memory_operand" ""))
18056    (clobber (match_operand:DI 4 "memory_operand" ""))
18057    (clobber (match_scratch 5 ""))]
18058   "reload_completed"
18059   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18060               (use (match_dup 2))
18061               (use (match_dup 3))
18062               (clobber (match_dup 5))])
18063    (set (match_dup 0) (match_dup 4))]
18064   "")
18065
18066 (define_split
18067   [(set (match_operand:DI 0 "memory_operand" "")
18068         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18069          UNSPEC_FIST_CEIL))
18070    (use (match_operand:HI 2 "memory_operand" ""))
18071    (use (match_operand:HI 3 "memory_operand" ""))
18072    (clobber (match_operand:DI 4 "memory_operand" ""))
18073    (clobber (match_scratch 5 ""))]
18074   "reload_completed"
18075   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18076               (use (match_dup 2))
18077               (use (match_dup 3))
18078               (clobber (match_dup 5))])]
18079   "")
18080
18081 (define_insn "fist<mode>2_ceil"
18082   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18083         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18084          UNSPEC_FIST_CEIL))
18085    (use (match_operand:HI 2 "memory_operand" "m"))
18086    (use (match_operand:HI 3 "memory_operand" "m"))]
18087   "TARGET_USE_FANCY_MATH_387
18088    && flag_unsafe_math_optimizations"
18089   "* return output_fix_trunc (insn, operands, 0);"
18090   [(set_attr "type" "fistp")
18091    (set_attr "i387_cw" "ceil")
18092    (set_attr "mode" "<MODE>")])
18093
18094 (define_insn "fist<mode>2_ceil_with_temp"
18095   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18096         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18097          UNSPEC_FIST_CEIL))
18098    (use (match_operand:HI 2 "memory_operand" "m,m"))
18099    (use (match_operand:HI 3 "memory_operand" "m,m"))
18100    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18101   "TARGET_USE_FANCY_MATH_387
18102    && flag_unsafe_math_optimizations"
18103   "#"
18104   [(set_attr "type" "fistp")
18105    (set_attr "i387_cw" "ceil")
18106    (set_attr "mode" "<MODE>")])
18107
18108 (define_split
18109   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18110         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18111          UNSPEC_FIST_CEIL))
18112    (use (match_operand:HI 2 "memory_operand" ""))
18113    (use (match_operand:HI 3 "memory_operand" ""))
18114    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18115   "reload_completed"
18116   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18117                                   UNSPEC_FIST_CEIL))
18118               (use (match_dup 2))
18119               (use (match_dup 3))])
18120    (set (match_dup 0) (match_dup 4))]
18121   "")
18122
18123 (define_split
18124   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18125         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18126          UNSPEC_FIST_CEIL))
18127    (use (match_operand:HI 2 "memory_operand" ""))
18128    (use (match_operand:HI 3 "memory_operand" ""))
18129    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18130   "reload_completed"
18131   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18132                                   UNSPEC_FIST_CEIL))
18133               (use (match_dup 2))
18134               (use (match_dup 3))])]
18135   "")
18136
18137 (define_expand "lceilxf<mode>2"
18138   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18139                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18140                     UNSPEC_FIST_CEIL))
18141               (clobber (reg:CC FLAGS_REG))])]
18142   "TARGET_USE_FANCY_MATH_387
18143    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18144    && flag_unsafe_math_optimizations"
18145   "")
18146
18147 (define_expand "lceil<mode>di2"
18148   [(match_operand:DI 0 "nonimmediate_operand" "")
18149    (match_operand:MODEF 1 "register_operand" "")]
18150   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18151    && !flag_trapping_math"
18152 {
18153   ix86_expand_lfloorceil (operand0, operand1, false);
18154   DONE;
18155 })
18156
18157 (define_expand "lceil<mode>si2"
18158   [(match_operand:SI 0 "nonimmediate_operand" "")
18159    (match_operand:MODEF 1 "register_operand" "")]
18160   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18161    && !flag_trapping_math"
18162 {
18163   ix86_expand_lfloorceil (operand0, operand1, false);
18164   DONE;
18165 })
18166
18167 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18168 (define_insn_and_split "frndintxf2_trunc"
18169   [(set (match_operand:XF 0 "register_operand" "")
18170         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18171          UNSPEC_FRNDINT_TRUNC))
18172    (clobber (reg:CC FLAGS_REG))]
18173   "TARGET_USE_FANCY_MATH_387
18174    && flag_unsafe_math_optimizations
18175    && !(reload_completed || reload_in_progress)"
18176   "#"
18177   "&& 1"
18178   [(const_int 0)]
18179 {
18180   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18181
18182   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18183   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18184
18185   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18186                                         operands[2], operands[3]));
18187   DONE;
18188 }
18189   [(set_attr "type" "frndint")
18190    (set_attr "i387_cw" "trunc")
18191    (set_attr "mode" "XF")])
18192
18193 (define_insn "frndintxf2_trunc_i387"
18194   [(set (match_operand:XF 0 "register_operand" "=f")
18195         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18196          UNSPEC_FRNDINT_TRUNC))
18197    (use (match_operand:HI 2 "memory_operand" "m"))
18198    (use (match_operand:HI 3 "memory_operand" "m"))]
18199   "TARGET_USE_FANCY_MATH_387
18200    && flag_unsafe_math_optimizations"
18201   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18202   [(set_attr "type" "frndint")
18203    (set_attr "i387_cw" "trunc")
18204    (set_attr "mode" "XF")])
18205
18206 (define_expand "btruncxf2"
18207   [(use (match_operand:XF 0 "register_operand" ""))
18208    (use (match_operand:XF 1 "register_operand" ""))]
18209   "TARGET_USE_FANCY_MATH_387
18210    && flag_unsafe_math_optimizations && !optimize_size"
18211 {
18212   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18213   DONE;
18214 })
18215
18216 (define_expand "btrunc<mode>2"
18217   [(use (match_operand:MODEF 0 "register_operand" ""))
18218    (use (match_operand:MODEF 1 "register_operand" ""))]
18219   "(TARGET_USE_FANCY_MATH_387
18220     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18221         || TARGET_MIX_SSE_I387)
18222     && flag_unsafe_math_optimizations && !optimize_size)
18223    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18224        && !flag_trapping_math
18225        && (TARGET_ROUND || !optimize_size))"
18226 {
18227   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18228       && !flag_trapping_math
18229       && (TARGET_ROUND || !optimize_size))
18230     {
18231       if (TARGET_ROUND)
18232         emit_insn (gen_sse4_1_round<mode>2
18233                    (operands[0], operands[1], GEN_INT (0x03)));
18234       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18235         ix86_expand_trunc (operand0, operand1);
18236       else
18237         ix86_expand_truncdf_32 (operand0, operand1);
18238     }
18239   else
18240     {
18241       rtx op0 = gen_reg_rtx (XFmode);
18242       rtx op1 = gen_reg_rtx (XFmode);
18243
18244       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18245       emit_insn (gen_frndintxf2_trunc (op0, op1));
18246
18247       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18248     }
18249   DONE;
18250 })
18251
18252 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18253 (define_insn_and_split "frndintxf2_mask_pm"
18254   [(set (match_operand:XF 0 "register_operand" "")
18255         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18256          UNSPEC_FRNDINT_MASK_PM))
18257    (clobber (reg:CC FLAGS_REG))]
18258   "TARGET_USE_FANCY_MATH_387
18259    && flag_unsafe_math_optimizations
18260    && !(reload_completed || reload_in_progress)"
18261   "#"
18262   "&& 1"
18263   [(const_int 0)]
18264 {
18265   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18266
18267   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18268   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18269
18270   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18271                                           operands[2], operands[3]));
18272   DONE;
18273 }
18274   [(set_attr "type" "frndint")
18275    (set_attr "i387_cw" "mask_pm")
18276    (set_attr "mode" "XF")])
18277
18278 (define_insn "frndintxf2_mask_pm_i387"
18279   [(set (match_operand:XF 0 "register_operand" "=f")
18280         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18281          UNSPEC_FRNDINT_MASK_PM))
18282    (use (match_operand:HI 2 "memory_operand" "m"))
18283    (use (match_operand:HI 3 "memory_operand" "m"))]
18284   "TARGET_USE_FANCY_MATH_387
18285    && flag_unsafe_math_optimizations"
18286   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18287   [(set_attr "type" "frndint")
18288    (set_attr "i387_cw" "mask_pm")
18289    (set_attr "mode" "XF")])
18290
18291 (define_expand "nearbyintxf2"
18292   [(use (match_operand:XF 0 "register_operand" ""))
18293    (use (match_operand:XF 1 "register_operand" ""))]
18294   "TARGET_USE_FANCY_MATH_387
18295    && flag_unsafe_math_optimizations"
18296 {
18297   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18298
18299   DONE;
18300 })
18301
18302 (define_expand "nearbyint<mode>2"
18303   [(use (match_operand:MODEF 0 "register_operand" ""))
18304    (use (match_operand:MODEF 1 "register_operand" ""))]
18305   "TARGET_USE_FANCY_MATH_387
18306    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18307        || TARGET_MIX_SSE_I387)
18308    && flag_unsafe_math_optimizations"
18309 {
18310   rtx op0 = gen_reg_rtx (XFmode);
18311   rtx op1 = gen_reg_rtx (XFmode);
18312
18313   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18314   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18315
18316   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18317   DONE;
18318 })
18319
18320 (define_insn "fxam<mode>2_i387"
18321   [(set (match_operand:HI 0 "register_operand" "=a")
18322         (unspec:HI
18323           [(match_operand:X87MODEF 1 "register_operand" "f")]
18324           UNSPEC_FXAM))]
18325   "TARGET_USE_FANCY_MATH_387"
18326   "fxam\n\tfnstsw\t%0"
18327   [(set_attr "type" "multi")
18328    (set_attr "unit" "i387")
18329    (set_attr "mode" "<MODE>")])
18330
18331 (define_expand "isinf<mode>2"
18332   [(use (match_operand:SI 0 "register_operand" ""))
18333    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18334   "TARGET_USE_FANCY_MATH_387
18335    && TARGET_C99_FUNCTIONS
18336    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18337 {
18338   rtx mask = GEN_INT (0x45);
18339   rtx val = GEN_INT (0x05);
18340
18341   rtx cond;
18342
18343   rtx scratch = gen_reg_rtx (HImode);
18344   rtx res = gen_reg_rtx (QImode);
18345
18346   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18347   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18348   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18349   cond = gen_rtx_fmt_ee (EQ, QImode,
18350                          gen_rtx_REG (CCmode, FLAGS_REG),
18351                          const0_rtx);
18352   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18353   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18354   DONE;
18355 })
18356
18357 (define_expand "signbit<mode>2"
18358   [(use (match_operand:SI 0 "register_operand" ""))
18359    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18360   "TARGET_USE_FANCY_MATH_387
18361    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18362 {
18363   rtx mask = GEN_INT (0x0200);
18364
18365   rtx scratch = gen_reg_rtx (HImode);
18366
18367   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18368   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18369   DONE;
18370 })
18371 \f
18372 ;; Block operation instructions
18373
18374 (define_expand "movmemsi"
18375   [(use (match_operand:BLK 0 "memory_operand" ""))
18376    (use (match_operand:BLK 1 "memory_operand" ""))
18377    (use (match_operand:SI 2 "nonmemory_operand" ""))
18378    (use (match_operand:SI 3 "const_int_operand" ""))
18379    (use (match_operand:SI 4 "const_int_operand" ""))
18380    (use (match_operand:SI 5 "const_int_operand" ""))]
18381   ""
18382 {
18383  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18384                          operands[4], operands[5]))
18385    DONE;
18386  else
18387    FAIL;
18388 })
18389
18390 (define_expand "movmemdi"
18391   [(use (match_operand:BLK 0 "memory_operand" ""))
18392    (use (match_operand:BLK 1 "memory_operand" ""))
18393    (use (match_operand:DI 2 "nonmemory_operand" ""))
18394    (use (match_operand:DI 3 "const_int_operand" ""))
18395    (use (match_operand:SI 4 "const_int_operand" ""))
18396    (use (match_operand:SI 5 "const_int_operand" ""))]
18397   "TARGET_64BIT"
18398 {
18399  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18400                          operands[4], operands[5]))
18401    DONE;
18402  else
18403    FAIL;
18404 })
18405
18406 ;; Most CPUs don't like single string operations
18407 ;; Handle this case here to simplify previous expander.
18408
18409 (define_expand "strmov"
18410   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18411    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18412    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18413               (clobber (reg:CC FLAGS_REG))])
18414    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18415               (clobber (reg:CC FLAGS_REG))])]
18416   ""
18417 {
18418   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18419
18420   /* If .md ever supports :P for Pmode, these can be directly
18421      in the pattern above.  */
18422   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18423   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18424
18425   /* Can't use this if the user has appropriated esi or edi.  */
18426   if ((TARGET_SINGLE_STRINGOP || optimize_size)
18427       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18428     {
18429       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18430                                       operands[2], operands[3],
18431                                       operands[5], operands[6]));
18432       DONE;
18433     }
18434
18435   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18436 })
18437
18438 (define_expand "strmov_singleop"
18439   [(parallel [(set (match_operand 1 "memory_operand" "")
18440                    (match_operand 3 "memory_operand" ""))
18441               (set (match_operand 0 "register_operand" "")
18442                    (match_operand 4 "" ""))
18443               (set (match_operand 2 "register_operand" "")
18444                    (match_operand 5 "" ""))])]
18445   "TARGET_SINGLE_STRINGOP || optimize_size"
18446   "")
18447
18448 (define_insn "*strmovdi_rex_1"
18449   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18450         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18451    (set (match_operand:DI 0 "register_operand" "=D")
18452         (plus:DI (match_dup 2)
18453                  (const_int 8)))
18454    (set (match_operand:DI 1 "register_operand" "=S")
18455         (plus:DI (match_dup 3)
18456                  (const_int 8)))]
18457   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18458   "movsq"
18459   [(set_attr "type" "str")
18460    (set_attr "mode" "DI")
18461    (set_attr "memory" "both")])
18462
18463 (define_insn "*strmovsi_1"
18464   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18465         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18466    (set (match_operand:SI 0 "register_operand" "=D")
18467         (plus:SI (match_dup 2)
18468                  (const_int 4)))
18469    (set (match_operand:SI 1 "register_operand" "=S")
18470         (plus:SI (match_dup 3)
18471                  (const_int 4)))]
18472   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18473   "movs{l|d}"
18474   [(set_attr "type" "str")
18475    (set_attr "mode" "SI")
18476    (set_attr "memory" "both")])
18477
18478 (define_insn "*strmovsi_rex_1"
18479   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18480         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18481    (set (match_operand:DI 0 "register_operand" "=D")
18482         (plus:DI (match_dup 2)
18483                  (const_int 4)))
18484    (set (match_operand:DI 1 "register_operand" "=S")
18485         (plus:DI (match_dup 3)
18486                  (const_int 4)))]
18487   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18488   "movs{l|d}"
18489   [(set_attr "type" "str")
18490    (set_attr "mode" "SI")
18491    (set_attr "memory" "both")])
18492
18493 (define_insn "*strmovhi_1"
18494   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18495         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18496    (set (match_operand:SI 0 "register_operand" "=D")
18497         (plus:SI (match_dup 2)
18498                  (const_int 2)))
18499    (set (match_operand:SI 1 "register_operand" "=S")
18500         (plus:SI (match_dup 3)
18501                  (const_int 2)))]
18502   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18503   "movsw"
18504   [(set_attr "type" "str")
18505    (set_attr "memory" "both")
18506    (set_attr "mode" "HI")])
18507
18508 (define_insn "*strmovhi_rex_1"
18509   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18510         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18511    (set (match_operand:DI 0 "register_operand" "=D")
18512         (plus:DI (match_dup 2)
18513                  (const_int 2)))
18514    (set (match_operand:DI 1 "register_operand" "=S")
18515         (plus:DI (match_dup 3)
18516                  (const_int 2)))]
18517   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18518   "movsw"
18519   [(set_attr "type" "str")
18520    (set_attr "memory" "both")
18521    (set_attr "mode" "HI")])
18522
18523 (define_insn "*strmovqi_1"
18524   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18525         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18526    (set (match_operand:SI 0 "register_operand" "=D")
18527         (plus:SI (match_dup 2)
18528                  (const_int 1)))
18529    (set (match_operand:SI 1 "register_operand" "=S")
18530         (plus:SI (match_dup 3)
18531                  (const_int 1)))]
18532   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18533   "movsb"
18534   [(set_attr "type" "str")
18535    (set_attr "memory" "both")
18536    (set_attr "mode" "QI")])
18537
18538 (define_insn "*strmovqi_rex_1"
18539   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18540         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18541    (set (match_operand:DI 0 "register_operand" "=D")
18542         (plus:DI (match_dup 2)
18543                  (const_int 1)))
18544    (set (match_operand:DI 1 "register_operand" "=S")
18545         (plus:DI (match_dup 3)
18546                  (const_int 1)))]
18547   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18548   "movsb"
18549   [(set_attr "type" "str")
18550    (set_attr "memory" "both")
18551    (set_attr "mode" "QI")])
18552
18553 (define_expand "rep_mov"
18554   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18555               (set (match_operand 0 "register_operand" "")
18556                    (match_operand 5 "" ""))
18557               (set (match_operand 2 "register_operand" "")
18558                    (match_operand 6 "" ""))
18559               (set (match_operand 1 "memory_operand" "")
18560                    (match_operand 3 "memory_operand" ""))
18561               (use (match_dup 4))])]
18562   ""
18563   "")
18564
18565 (define_insn "*rep_movdi_rex64"
18566   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18567    (set (match_operand:DI 0 "register_operand" "=D")
18568         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18569                             (const_int 3))
18570                  (match_operand:DI 3 "register_operand" "0")))
18571    (set (match_operand:DI 1 "register_operand" "=S")
18572         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18573                  (match_operand:DI 4 "register_operand" "1")))
18574    (set (mem:BLK (match_dup 3))
18575         (mem:BLK (match_dup 4)))
18576    (use (match_dup 5))]
18577   "TARGET_64BIT"
18578   "rep movsq"
18579   [(set_attr "type" "str")
18580    (set_attr "prefix_rep" "1")
18581    (set_attr "memory" "both")
18582    (set_attr "mode" "DI")])
18583
18584 (define_insn "*rep_movsi"
18585   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18586    (set (match_operand:SI 0 "register_operand" "=D")
18587         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18588                             (const_int 2))
18589                  (match_operand:SI 3 "register_operand" "0")))
18590    (set (match_operand:SI 1 "register_operand" "=S")
18591         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18592                  (match_operand:SI 4 "register_operand" "1")))
18593    (set (mem:BLK (match_dup 3))
18594         (mem:BLK (match_dup 4)))
18595    (use (match_dup 5))]
18596   "!TARGET_64BIT"
18597   "rep movs{l|d}"
18598   [(set_attr "type" "str")
18599    (set_attr "prefix_rep" "1")
18600    (set_attr "memory" "both")
18601    (set_attr "mode" "SI")])
18602
18603 (define_insn "*rep_movsi_rex64"
18604   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18605    (set (match_operand:DI 0 "register_operand" "=D")
18606         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18607                             (const_int 2))
18608                  (match_operand:DI 3 "register_operand" "0")))
18609    (set (match_operand:DI 1 "register_operand" "=S")
18610         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18611                  (match_operand:DI 4 "register_operand" "1")))
18612    (set (mem:BLK (match_dup 3))
18613         (mem:BLK (match_dup 4)))
18614    (use (match_dup 5))]
18615   "TARGET_64BIT"
18616   "rep movs{l|d}"
18617   [(set_attr "type" "str")
18618    (set_attr "prefix_rep" "1")
18619    (set_attr "memory" "both")
18620    (set_attr "mode" "SI")])
18621
18622 (define_insn "*rep_movqi"
18623   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18624    (set (match_operand:SI 0 "register_operand" "=D")
18625         (plus:SI (match_operand:SI 3 "register_operand" "0")
18626                  (match_operand:SI 5 "register_operand" "2")))
18627    (set (match_operand:SI 1 "register_operand" "=S")
18628         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18629    (set (mem:BLK (match_dup 3))
18630         (mem:BLK (match_dup 4)))
18631    (use (match_dup 5))]
18632   "!TARGET_64BIT"
18633   "rep movsb"
18634   [(set_attr "type" "str")
18635    (set_attr "prefix_rep" "1")
18636    (set_attr "memory" "both")
18637    (set_attr "mode" "SI")])
18638
18639 (define_insn "*rep_movqi_rex64"
18640   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18641    (set (match_operand:DI 0 "register_operand" "=D")
18642         (plus:DI (match_operand:DI 3 "register_operand" "0")
18643                  (match_operand:DI 5 "register_operand" "2")))
18644    (set (match_operand:DI 1 "register_operand" "=S")
18645         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18646    (set (mem:BLK (match_dup 3))
18647         (mem:BLK (match_dup 4)))
18648    (use (match_dup 5))]
18649   "TARGET_64BIT"
18650   "rep movsb"
18651   [(set_attr "type" "str")
18652    (set_attr "prefix_rep" "1")
18653    (set_attr "memory" "both")
18654    (set_attr "mode" "SI")])
18655
18656 (define_expand "setmemsi"
18657    [(use (match_operand:BLK 0 "memory_operand" ""))
18658     (use (match_operand:SI 1 "nonmemory_operand" ""))
18659     (use (match_operand 2 "const_int_operand" ""))
18660     (use (match_operand 3 "const_int_operand" ""))
18661     (use (match_operand:SI 4 "const_int_operand" ""))
18662     (use (match_operand:SI 5 "const_int_operand" ""))]
18663   ""
18664 {
18665  if (ix86_expand_setmem (operands[0], operands[1],
18666                          operands[2], operands[3],
18667                          operands[4], operands[5]))
18668    DONE;
18669  else
18670    FAIL;
18671 })
18672
18673 (define_expand "setmemdi"
18674    [(use (match_operand:BLK 0 "memory_operand" ""))
18675     (use (match_operand:DI 1 "nonmemory_operand" ""))
18676     (use (match_operand 2 "const_int_operand" ""))
18677     (use (match_operand 3 "const_int_operand" ""))
18678     (use (match_operand 4 "const_int_operand" ""))
18679     (use (match_operand 5 "const_int_operand" ""))]
18680   "TARGET_64BIT"
18681 {
18682  if (ix86_expand_setmem (operands[0], operands[1],
18683                          operands[2], operands[3],
18684                          operands[4], operands[5]))
18685    DONE;
18686  else
18687    FAIL;
18688 })
18689
18690 ;; Most CPUs don't like single string operations
18691 ;; Handle this case here to simplify previous expander.
18692
18693 (define_expand "strset"
18694   [(set (match_operand 1 "memory_operand" "")
18695         (match_operand 2 "register_operand" ""))
18696    (parallel [(set (match_operand 0 "register_operand" "")
18697                    (match_dup 3))
18698               (clobber (reg:CC FLAGS_REG))])]
18699   ""
18700 {
18701   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18702     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18703
18704   /* If .md ever supports :P for Pmode, this can be directly
18705      in the pattern above.  */
18706   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18707                               GEN_INT (GET_MODE_SIZE (GET_MODE
18708                                                       (operands[2]))));
18709   if (TARGET_SINGLE_STRINGOP || optimize_size)
18710     {
18711       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18712                                       operands[3]));
18713       DONE;
18714     }
18715 })
18716
18717 (define_expand "strset_singleop"
18718   [(parallel [(set (match_operand 1 "memory_operand" "")
18719                    (match_operand 2 "register_operand" ""))
18720               (set (match_operand 0 "register_operand" "")
18721                    (match_operand 3 "" ""))])]
18722   "TARGET_SINGLE_STRINGOP || optimize_size"
18723   "")
18724
18725 (define_insn "*strsetdi_rex_1"
18726   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18727         (match_operand:DI 2 "register_operand" "a"))
18728    (set (match_operand:DI 0 "register_operand" "=D")
18729         (plus:DI (match_dup 1)
18730                  (const_int 8)))]
18731   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18732   "stosq"
18733   [(set_attr "type" "str")
18734    (set_attr "memory" "store")
18735    (set_attr "mode" "DI")])
18736
18737 (define_insn "*strsetsi_1"
18738   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18739         (match_operand:SI 2 "register_operand" "a"))
18740    (set (match_operand:SI 0 "register_operand" "=D")
18741         (plus:SI (match_dup 1)
18742                  (const_int 4)))]
18743   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18744   "stos{l|d}"
18745   [(set_attr "type" "str")
18746    (set_attr "memory" "store")
18747    (set_attr "mode" "SI")])
18748
18749 (define_insn "*strsetsi_rex_1"
18750   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18751         (match_operand:SI 2 "register_operand" "a"))
18752    (set (match_operand:DI 0 "register_operand" "=D")
18753         (plus:DI (match_dup 1)
18754                  (const_int 4)))]
18755   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18756   "stos{l|d}"
18757   [(set_attr "type" "str")
18758    (set_attr "memory" "store")
18759    (set_attr "mode" "SI")])
18760
18761 (define_insn "*strsethi_1"
18762   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18763         (match_operand:HI 2 "register_operand" "a"))
18764    (set (match_operand:SI 0 "register_operand" "=D")
18765         (plus:SI (match_dup 1)
18766                  (const_int 2)))]
18767   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18768   "stosw"
18769   [(set_attr "type" "str")
18770    (set_attr "memory" "store")
18771    (set_attr "mode" "HI")])
18772
18773 (define_insn "*strsethi_rex_1"
18774   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18775         (match_operand:HI 2 "register_operand" "a"))
18776    (set (match_operand:DI 0 "register_operand" "=D")
18777         (plus:DI (match_dup 1)
18778                  (const_int 2)))]
18779   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18780   "stosw"
18781   [(set_attr "type" "str")
18782    (set_attr "memory" "store")
18783    (set_attr "mode" "HI")])
18784
18785 (define_insn "*strsetqi_1"
18786   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18787         (match_operand:QI 2 "register_operand" "a"))
18788    (set (match_operand:SI 0 "register_operand" "=D")
18789         (plus:SI (match_dup 1)
18790                  (const_int 1)))]
18791   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18792   "stosb"
18793   [(set_attr "type" "str")
18794    (set_attr "memory" "store")
18795    (set_attr "mode" "QI")])
18796
18797 (define_insn "*strsetqi_rex_1"
18798   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18799         (match_operand:QI 2 "register_operand" "a"))
18800    (set (match_operand:DI 0 "register_operand" "=D")
18801         (plus:DI (match_dup 1)
18802                  (const_int 1)))]
18803   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18804   "stosb"
18805   [(set_attr "type" "str")
18806    (set_attr "memory" "store")
18807    (set_attr "mode" "QI")])
18808
18809 (define_expand "rep_stos"
18810   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18811               (set (match_operand 0 "register_operand" "")
18812                    (match_operand 4 "" ""))
18813               (set (match_operand 2 "memory_operand" "") (const_int 0))
18814               (use (match_operand 3 "register_operand" ""))
18815               (use (match_dup 1))])]
18816   ""
18817   "")
18818
18819 (define_insn "*rep_stosdi_rex64"
18820   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18821    (set (match_operand:DI 0 "register_operand" "=D")
18822         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18823                             (const_int 3))
18824                  (match_operand:DI 3 "register_operand" "0")))
18825    (set (mem:BLK (match_dup 3))
18826         (const_int 0))
18827    (use (match_operand:DI 2 "register_operand" "a"))
18828    (use (match_dup 4))]
18829   "TARGET_64BIT"
18830   "rep stosq"
18831   [(set_attr "type" "str")
18832    (set_attr "prefix_rep" "1")
18833    (set_attr "memory" "store")
18834    (set_attr "mode" "DI")])
18835
18836 (define_insn "*rep_stossi"
18837   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18838    (set (match_operand:SI 0 "register_operand" "=D")
18839         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18840                             (const_int 2))
18841                  (match_operand:SI 3 "register_operand" "0")))
18842    (set (mem:BLK (match_dup 3))
18843         (const_int 0))
18844    (use (match_operand:SI 2 "register_operand" "a"))
18845    (use (match_dup 4))]
18846   "!TARGET_64BIT"
18847   "rep stos{l|d}"
18848   [(set_attr "type" "str")
18849    (set_attr "prefix_rep" "1")
18850    (set_attr "memory" "store")
18851    (set_attr "mode" "SI")])
18852
18853 (define_insn "*rep_stossi_rex64"
18854   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18855    (set (match_operand:DI 0 "register_operand" "=D")
18856         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18857                             (const_int 2))
18858                  (match_operand:DI 3 "register_operand" "0")))
18859    (set (mem:BLK (match_dup 3))
18860         (const_int 0))
18861    (use (match_operand:SI 2 "register_operand" "a"))
18862    (use (match_dup 4))]
18863   "TARGET_64BIT"
18864   "rep stos{l|d}"
18865   [(set_attr "type" "str")
18866    (set_attr "prefix_rep" "1")
18867    (set_attr "memory" "store")
18868    (set_attr "mode" "SI")])
18869
18870 (define_insn "*rep_stosqi"
18871   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18872    (set (match_operand:SI 0 "register_operand" "=D")
18873         (plus:SI (match_operand:SI 3 "register_operand" "0")
18874                  (match_operand:SI 4 "register_operand" "1")))
18875    (set (mem:BLK (match_dup 3))
18876         (const_int 0))
18877    (use (match_operand:QI 2 "register_operand" "a"))
18878    (use (match_dup 4))]
18879   "!TARGET_64BIT"
18880   "rep stosb"
18881   [(set_attr "type" "str")
18882    (set_attr "prefix_rep" "1")
18883    (set_attr "memory" "store")
18884    (set_attr "mode" "QI")])
18885
18886 (define_insn "*rep_stosqi_rex64"
18887   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18888    (set (match_operand:DI 0 "register_operand" "=D")
18889         (plus:DI (match_operand:DI 3 "register_operand" "0")
18890                  (match_operand:DI 4 "register_operand" "1")))
18891    (set (mem:BLK (match_dup 3))
18892         (const_int 0))
18893    (use (match_operand:QI 2 "register_operand" "a"))
18894    (use (match_dup 4))]
18895   "TARGET_64BIT"
18896   "rep stosb"
18897   [(set_attr "type" "str")
18898    (set_attr "prefix_rep" "1")
18899    (set_attr "memory" "store")
18900    (set_attr "mode" "QI")])
18901
18902 (define_expand "cmpstrnsi"
18903   [(set (match_operand:SI 0 "register_operand" "")
18904         (compare:SI (match_operand:BLK 1 "general_operand" "")
18905                     (match_operand:BLK 2 "general_operand" "")))
18906    (use (match_operand 3 "general_operand" ""))
18907    (use (match_operand 4 "immediate_operand" ""))]
18908   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18909 {
18910   rtx addr1, addr2, out, outlow, count, countreg, align;
18911
18912   /* Can't use this if the user has appropriated esi or edi.  */
18913   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18914     FAIL;
18915
18916   out = operands[0];
18917   if (!REG_P (out))
18918     out = gen_reg_rtx (SImode);
18919
18920   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18921   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18922   if (addr1 != XEXP (operands[1], 0))
18923     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18924   if (addr2 != XEXP (operands[2], 0))
18925     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18926
18927   count = operands[3];
18928   countreg = ix86_zero_extend_to_Pmode (count);
18929
18930   /* %%% Iff we are testing strict equality, we can use known alignment
18931      to good advantage.  This may be possible with combine, particularly
18932      once cc0 is dead.  */
18933   align = operands[4];
18934
18935   if (CONST_INT_P (count))
18936     {
18937       if (INTVAL (count) == 0)
18938         {
18939           emit_move_insn (operands[0], const0_rtx);
18940           DONE;
18941         }
18942       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18943                                      operands[1], operands[2]));
18944     }
18945   else
18946     {
18947       if (TARGET_64BIT)
18948         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18949       else
18950         emit_insn (gen_cmpsi_1 (countreg, countreg));
18951       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18952                                   operands[1], operands[2]));
18953     }
18954
18955   outlow = gen_lowpart (QImode, out);
18956   emit_insn (gen_cmpintqi (outlow));
18957   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18958
18959   if (operands[0] != out)
18960     emit_move_insn (operands[0], out);
18961
18962   DONE;
18963 })
18964
18965 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18966
18967 (define_expand "cmpintqi"
18968   [(set (match_dup 1)
18969         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18970    (set (match_dup 2)
18971         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18972    (parallel [(set (match_operand:QI 0 "register_operand" "")
18973                    (minus:QI (match_dup 1)
18974                              (match_dup 2)))
18975               (clobber (reg:CC FLAGS_REG))])]
18976   ""
18977   "operands[1] = gen_reg_rtx (QImode);
18978    operands[2] = gen_reg_rtx (QImode);")
18979
18980 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18981 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18982
18983 (define_expand "cmpstrnqi_nz_1"
18984   [(parallel [(set (reg:CC FLAGS_REG)
18985                    (compare:CC (match_operand 4 "memory_operand" "")
18986                                (match_operand 5 "memory_operand" "")))
18987               (use (match_operand 2 "register_operand" ""))
18988               (use (match_operand:SI 3 "immediate_operand" ""))
18989               (clobber (match_operand 0 "register_operand" ""))
18990               (clobber (match_operand 1 "register_operand" ""))
18991               (clobber (match_dup 2))])]
18992   ""
18993   "")
18994
18995 (define_insn "*cmpstrnqi_nz_1"
18996   [(set (reg:CC FLAGS_REG)
18997         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18998                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18999    (use (match_operand:SI 6 "register_operand" "2"))
19000    (use (match_operand:SI 3 "immediate_operand" "i"))
19001    (clobber (match_operand:SI 0 "register_operand" "=S"))
19002    (clobber (match_operand:SI 1 "register_operand" "=D"))
19003    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19004   "!TARGET_64BIT"
19005   "repz cmpsb"
19006   [(set_attr "type" "str")
19007    (set_attr "mode" "QI")
19008    (set_attr "prefix_rep" "1")])
19009
19010 (define_insn "*cmpstrnqi_nz_rex_1"
19011   [(set (reg:CC FLAGS_REG)
19012         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19013                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19014    (use (match_operand:DI 6 "register_operand" "2"))
19015    (use (match_operand:SI 3 "immediate_operand" "i"))
19016    (clobber (match_operand:DI 0 "register_operand" "=S"))
19017    (clobber (match_operand:DI 1 "register_operand" "=D"))
19018    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19019   "TARGET_64BIT"
19020   "repz cmpsb"
19021   [(set_attr "type" "str")
19022    (set_attr "mode" "QI")
19023    (set_attr "prefix_rep" "1")])
19024
19025 ;; The same, but the count is not known to not be zero.
19026
19027 (define_expand "cmpstrnqi_1"
19028   [(parallel [(set (reg:CC FLAGS_REG)
19029                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19030                                      (const_int 0))
19031                   (compare:CC (match_operand 4 "memory_operand" "")
19032                               (match_operand 5 "memory_operand" ""))
19033                   (const_int 0)))
19034               (use (match_operand:SI 3 "immediate_operand" ""))
19035               (use (reg:CC FLAGS_REG))
19036               (clobber (match_operand 0 "register_operand" ""))
19037               (clobber (match_operand 1 "register_operand" ""))
19038               (clobber (match_dup 2))])]
19039   ""
19040   "")
19041
19042 (define_insn "*cmpstrnqi_1"
19043   [(set (reg:CC FLAGS_REG)
19044         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19045                              (const_int 0))
19046           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19047                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19048           (const_int 0)))
19049    (use (match_operand:SI 3 "immediate_operand" "i"))
19050    (use (reg:CC FLAGS_REG))
19051    (clobber (match_operand:SI 0 "register_operand" "=S"))
19052    (clobber (match_operand:SI 1 "register_operand" "=D"))
19053    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19054   "!TARGET_64BIT"
19055   "repz cmpsb"
19056   [(set_attr "type" "str")
19057    (set_attr "mode" "QI")
19058    (set_attr "prefix_rep" "1")])
19059
19060 (define_insn "*cmpstrnqi_rex_1"
19061   [(set (reg:CC FLAGS_REG)
19062         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19063                              (const_int 0))
19064           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19065                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19066           (const_int 0)))
19067    (use (match_operand:SI 3 "immediate_operand" "i"))
19068    (use (reg:CC FLAGS_REG))
19069    (clobber (match_operand:DI 0 "register_operand" "=S"))
19070    (clobber (match_operand:DI 1 "register_operand" "=D"))
19071    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19072   "TARGET_64BIT"
19073   "repz cmpsb"
19074   [(set_attr "type" "str")
19075    (set_attr "mode" "QI")
19076    (set_attr "prefix_rep" "1")])
19077
19078 (define_expand "strlensi"
19079   [(set (match_operand:SI 0 "register_operand" "")
19080         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19081                     (match_operand:QI 2 "immediate_operand" "")
19082                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19083   ""
19084 {
19085  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19086    DONE;
19087  else
19088    FAIL;
19089 })
19090
19091 (define_expand "strlendi"
19092   [(set (match_operand:DI 0 "register_operand" "")
19093         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19094                     (match_operand:QI 2 "immediate_operand" "")
19095                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19096   ""
19097 {
19098  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19099    DONE;
19100  else
19101    FAIL;
19102 })
19103
19104 (define_expand "strlenqi_1"
19105   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19106               (clobber (match_operand 1 "register_operand" ""))
19107               (clobber (reg:CC FLAGS_REG))])]
19108   ""
19109   "")
19110
19111 (define_insn "*strlenqi_1"
19112   [(set (match_operand:SI 0 "register_operand" "=&c")
19113         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19114                     (match_operand:QI 2 "register_operand" "a")
19115                     (match_operand:SI 3 "immediate_operand" "i")
19116                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19117    (clobber (match_operand:SI 1 "register_operand" "=D"))
19118    (clobber (reg:CC FLAGS_REG))]
19119   "!TARGET_64BIT"
19120   "repnz scasb"
19121   [(set_attr "type" "str")
19122    (set_attr "mode" "QI")
19123    (set_attr "prefix_rep" "1")])
19124
19125 (define_insn "*strlenqi_rex_1"
19126   [(set (match_operand:DI 0 "register_operand" "=&c")
19127         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19128                     (match_operand:QI 2 "register_operand" "a")
19129                     (match_operand:DI 3 "immediate_operand" "i")
19130                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19131    (clobber (match_operand:DI 1 "register_operand" "=D"))
19132    (clobber (reg:CC FLAGS_REG))]
19133   "TARGET_64BIT"
19134   "repnz scasb"
19135   [(set_attr "type" "str")
19136    (set_attr "mode" "QI")
19137    (set_attr "prefix_rep" "1")])
19138
19139 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19140 ;; handled in combine, but it is not currently up to the task.
19141 ;; When used for their truth value, the cmpstrn* expanders generate
19142 ;; code like this:
19143 ;;
19144 ;;   repz cmpsb
19145 ;;   seta       %al
19146 ;;   setb       %dl
19147 ;;   cmpb       %al, %dl
19148 ;;   jcc        label
19149 ;;
19150 ;; The intermediate three instructions are unnecessary.
19151
19152 ;; This one handles cmpstrn*_nz_1...
19153 (define_peephole2
19154   [(parallel[
19155      (set (reg:CC FLAGS_REG)
19156           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19157                       (mem:BLK (match_operand 5 "register_operand" ""))))
19158      (use (match_operand 6 "register_operand" ""))
19159      (use (match_operand:SI 3 "immediate_operand" ""))
19160      (clobber (match_operand 0 "register_operand" ""))
19161      (clobber (match_operand 1 "register_operand" ""))
19162      (clobber (match_operand 2 "register_operand" ""))])
19163    (set (match_operand:QI 7 "register_operand" "")
19164         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19165    (set (match_operand:QI 8 "register_operand" "")
19166         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19167    (set (reg FLAGS_REG)
19168         (compare (match_dup 7) (match_dup 8)))
19169   ]
19170   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19171   [(parallel[
19172      (set (reg:CC FLAGS_REG)
19173           (compare:CC (mem:BLK (match_dup 4))
19174                       (mem:BLK (match_dup 5))))
19175      (use (match_dup 6))
19176      (use (match_dup 3))
19177      (clobber (match_dup 0))
19178      (clobber (match_dup 1))
19179      (clobber (match_dup 2))])]
19180   "")
19181
19182 ;; ...and this one handles cmpstrn*_1.
19183 (define_peephole2
19184   [(parallel[
19185      (set (reg:CC FLAGS_REG)
19186           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19187                                (const_int 0))
19188             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19189                         (mem:BLK (match_operand 5 "register_operand" "")))
19190             (const_int 0)))
19191      (use (match_operand:SI 3 "immediate_operand" ""))
19192      (use (reg:CC FLAGS_REG))
19193      (clobber (match_operand 0 "register_operand" ""))
19194      (clobber (match_operand 1 "register_operand" ""))
19195      (clobber (match_operand 2 "register_operand" ""))])
19196    (set (match_operand:QI 7 "register_operand" "")
19197         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19198    (set (match_operand:QI 8 "register_operand" "")
19199         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19200    (set (reg FLAGS_REG)
19201         (compare (match_dup 7) (match_dup 8)))
19202   ]
19203   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19204   [(parallel[
19205      (set (reg:CC FLAGS_REG)
19206           (if_then_else:CC (ne (match_dup 6)
19207                                (const_int 0))
19208             (compare:CC (mem:BLK (match_dup 4))
19209                         (mem:BLK (match_dup 5)))
19210             (const_int 0)))
19211      (use (match_dup 3))
19212      (use (reg:CC FLAGS_REG))
19213      (clobber (match_dup 0))
19214      (clobber (match_dup 1))
19215      (clobber (match_dup 2))])]
19216   "")
19217
19218
19219 \f
19220 ;; Conditional move instructions.
19221
19222 (define_expand "movdicc"
19223   [(set (match_operand:DI 0 "register_operand" "")
19224         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19225                          (match_operand:DI 2 "general_operand" "")
19226                          (match_operand:DI 3 "general_operand" "")))]
19227   "TARGET_64BIT"
19228   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19229
19230 (define_insn "x86_movdicc_0_m1_rex64"
19231   [(set (match_operand:DI 0 "register_operand" "=r")
19232         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19233           (const_int -1)
19234           (const_int 0)))
19235    (clobber (reg:CC FLAGS_REG))]
19236   "TARGET_64BIT"
19237   "sbb{q}\t%0, %0"
19238   ; Since we don't have the proper number of operands for an alu insn,
19239   ; fill in all the blanks.
19240   [(set_attr "type" "alu")
19241    (set_attr "pent_pair" "pu")
19242    (set_attr "memory" "none")
19243    (set_attr "imm_disp" "false")
19244    (set_attr "mode" "DI")
19245    (set_attr "length_immediate" "0")])
19246
19247 (define_insn "*x86_movdicc_0_m1_se"
19248   [(set (match_operand:DI 0 "register_operand" "=r")
19249         (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19250                          (const_int 1)
19251                          (const_int 0)))
19252    (clobber (reg:CC FLAGS_REG))]
19253   ""
19254   "sbb{q}\t%0, %0"
19255   [(set_attr "type" "alu")
19256    (set_attr "pent_pair" "pu")
19257    (set_attr "memory" "none")
19258    (set_attr "imm_disp" "false")
19259    (set_attr "mode" "DI")
19260    (set_attr "length_immediate" "0")])
19261
19262 (define_insn "*movdicc_c_rex64"
19263   [(set (match_operand:DI 0 "register_operand" "=r,r")
19264         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19265                                 [(reg FLAGS_REG) (const_int 0)])
19266                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19267                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19268   "TARGET_64BIT && TARGET_CMOVE
19269    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19270   "@
19271    cmov%O2%C1\t{%2, %0|%0, %2}
19272    cmov%O2%c1\t{%3, %0|%0, %3}"
19273   [(set_attr "type" "icmov")
19274    (set_attr "mode" "DI")])
19275
19276 (define_expand "movsicc"
19277   [(set (match_operand:SI 0 "register_operand" "")
19278         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19279                          (match_operand:SI 2 "general_operand" "")
19280                          (match_operand:SI 3 "general_operand" "")))]
19281   ""
19282   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19283
19284 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19285 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19286 ;; So just document what we're doing explicitly.
19287
19288 (define_insn "x86_movsicc_0_m1"
19289   [(set (match_operand:SI 0 "register_operand" "=r")
19290         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19291           (const_int -1)
19292           (const_int 0)))
19293    (clobber (reg:CC FLAGS_REG))]
19294   ""
19295   "sbb{l}\t%0, %0"
19296   ; Since we don't have the proper number of operands for an alu insn,
19297   ; fill in all the blanks.
19298   [(set_attr "type" "alu")
19299    (set_attr "pent_pair" "pu")
19300    (set_attr "memory" "none")
19301    (set_attr "imm_disp" "false")
19302    (set_attr "mode" "SI")
19303    (set_attr "length_immediate" "0")])
19304
19305 (define_insn "*x86_movsicc_0_m1_se"
19306   [(set (match_operand:SI 0 "register_operand" "=r")
19307         (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19308                          (const_int 1)
19309                          (const_int 0)))
19310    (clobber (reg:CC FLAGS_REG))]
19311   ""
19312   "sbb{l}\t%0, %0"
19313   [(set_attr "type" "alu")
19314    (set_attr "pent_pair" "pu")
19315    (set_attr "memory" "none")
19316    (set_attr "imm_disp" "false")
19317    (set_attr "mode" "SI")
19318    (set_attr "length_immediate" "0")])
19319
19320 (define_insn "*movsicc_noc"
19321   [(set (match_operand:SI 0 "register_operand" "=r,r")
19322         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19323                                 [(reg FLAGS_REG) (const_int 0)])
19324                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19325                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19326   "TARGET_CMOVE
19327    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19328   "@
19329    cmov%O2%C1\t{%2, %0|%0, %2}
19330    cmov%O2%c1\t{%3, %0|%0, %3}"
19331   [(set_attr "type" "icmov")
19332    (set_attr "mode" "SI")])
19333
19334 (define_expand "movhicc"
19335   [(set (match_operand:HI 0 "register_operand" "")
19336         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19337                          (match_operand:HI 2 "general_operand" "")
19338                          (match_operand:HI 3 "general_operand" "")))]
19339   "TARGET_HIMODE_MATH"
19340   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19341
19342 (define_insn "*movhicc_noc"
19343   [(set (match_operand:HI 0 "register_operand" "=r,r")
19344         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19345                                 [(reg FLAGS_REG) (const_int 0)])
19346                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19347                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19348   "TARGET_CMOVE
19349    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19350   "@
19351    cmov%O2%C1\t{%2, %0|%0, %2}
19352    cmov%O2%c1\t{%3, %0|%0, %3}"
19353   [(set_attr "type" "icmov")
19354    (set_attr "mode" "HI")])
19355
19356 (define_expand "movqicc"
19357   [(set (match_operand:QI 0 "register_operand" "")
19358         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19359                          (match_operand:QI 2 "general_operand" "")
19360                          (match_operand:QI 3 "general_operand" "")))]
19361   "TARGET_QIMODE_MATH"
19362   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19363
19364 (define_insn_and_split "*movqicc_noc"
19365   [(set (match_operand:QI 0 "register_operand" "=r,r")
19366         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19367                                 [(match_operand 4 "flags_reg_operand" "")
19368                                  (const_int 0)])
19369                       (match_operand:QI 2 "register_operand" "r,0")
19370                       (match_operand:QI 3 "register_operand" "0,r")))]
19371   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19372   "#"
19373   "&& reload_completed"
19374   [(set (match_dup 0)
19375         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19376                       (match_dup 2)
19377                       (match_dup 3)))]
19378   "operands[0] = gen_lowpart (SImode, operands[0]);
19379    operands[2] = gen_lowpart (SImode, operands[2]);
19380    operands[3] = gen_lowpart (SImode, operands[3]);"
19381   [(set_attr "type" "icmov")
19382    (set_attr "mode" "SI")])
19383
19384 (define_expand "mov<mode>cc"
19385   [(set (match_operand:X87MODEF 0 "register_operand" "")
19386         (if_then_else:X87MODEF
19387           (match_operand 1 "comparison_operator" "")
19388           (match_operand:X87MODEF 2 "register_operand" "")
19389           (match_operand:X87MODEF 3 "register_operand" "")))]
19390   "(TARGET_80387 && TARGET_CMOVE)
19391    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19392   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19393
19394 (define_insn "*movsfcc_1_387"
19395   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19396         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19397                                 [(reg FLAGS_REG) (const_int 0)])
19398                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19399                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19400   "TARGET_80387 && TARGET_CMOVE
19401    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19402   "@
19403    fcmov%F1\t{%2, %0|%0, %2}
19404    fcmov%f1\t{%3, %0|%0, %3}
19405    cmov%O2%C1\t{%2, %0|%0, %2}
19406    cmov%O2%c1\t{%3, %0|%0, %3}"
19407   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19408    (set_attr "mode" "SF,SF,SI,SI")])
19409
19410 (define_insn "*movdfcc_1"
19411   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19412         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19413                                 [(reg FLAGS_REG) (const_int 0)])
19414                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19415                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19416   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19417    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19418   "@
19419    fcmov%F1\t{%2, %0|%0, %2}
19420    fcmov%f1\t{%3, %0|%0, %3}
19421    #
19422    #"
19423   [(set_attr "type" "fcmov,fcmov,multi,multi")
19424    (set_attr "mode" "DF")])
19425
19426 (define_insn "*movdfcc_1_rex64"
19427   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19428         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19429                                 [(reg FLAGS_REG) (const_int 0)])
19430                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19431                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19432   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19433    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19434   "@
19435    fcmov%F1\t{%2, %0|%0, %2}
19436    fcmov%f1\t{%3, %0|%0, %3}
19437    cmov%O2%C1\t{%2, %0|%0, %2}
19438    cmov%O2%c1\t{%3, %0|%0, %3}"
19439   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19440    (set_attr "mode" "DF")])
19441
19442 (define_split
19443   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19444         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19445                                 [(match_operand 4 "flags_reg_operand" "")
19446                                  (const_int 0)])
19447                       (match_operand:DF 2 "nonimmediate_operand" "")
19448                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19449   "!TARGET_64BIT && reload_completed"
19450   [(set (match_dup 2)
19451         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19452                       (match_dup 5)
19453                       (match_dup 6)))
19454    (set (match_dup 3)
19455         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19456                       (match_dup 7)
19457                       (match_dup 8)))]
19458   "split_di (&operands[2], 2, &operands[5], &operands[7]);
19459    split_di (&operands[0], 1, &operands[2], &operands[3]);")
19460
19461 (define_insn "*movxfcc_1"
19462   [(set (match_operand:XF 0 "register_operand" "=f,f")
19463         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19464                                 [(reg FLAGS_REG) (const_int 0)])
19465                       (match_operand:XF 2 "register_operand" "f,0")
19466                       (match_operand:XF 3 "register_operand" "0,f")))]
19467   "TARGET_80387 && TARGET_CMOVE"
19468   "@
19469    fcmov%F1\t{%2, %0|%0, %2}
19470    fcmov%f1\t{%3, %0|%0, %3}"
19471   [(set_attr "type" "fcmov")
19472    (set_attr "mode" "XF")])
19473
19474 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19475 ;; the scalar versions to have only XMM registers as operands.
19476
19477 ;; SSE5 conditional move
19478 (define_insn "*sse5_pcmov_<mode>"
19479   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19480         (if_then_else:MODEF
19481           (match_operand:MODEF 1 "register_operand" "x,0")
19482           (match_operand:MODEF 2 "register_operand" "0,x")
19483           (match_operand:MODEF 3 "register_operand" "x,x")))]
19484   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19485   "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19486   [(set_attr "type" "sse4arg")])
19487
19488 ;; These versions of the min/max patterns are intentionally ignorant of
19489 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19490 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19491 ;; are undefined in this condition, we're certain this is correct.
19492
19493 (define_insn "<code><mode>3"
19494   [(set (match_operand:MODEF 0 "register_operand" "=x")
19495         (smaxmin:MODEF
19496           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19497           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19498   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19499   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19500   [(set_attr "type" "sseadd")
19501    (set_attr "mode" "<MODE>")])
19502
19503 ;; These versions of the min/max patterns implement exactly the operations
19504 ;;   min = (op1 < op2 ? op1 : op2)
19505 ;;   max = (!(op1 < op2) ? op1 : op2)
19506 ;; Their operands are not commutative, and thus they may be used in the
19507 ;; presence of -0.0 and NaN.
19508
19509 (define_insn "*ieee_smin<mode>3"
19510   [(set (match_operand:MODEF 0 "register_operand" "=x")
19511         (unspec:MODEF
19512           [(match_operand:MODEF 1 "register_operand" "0")
19513            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19514          UNSPEC_IEEE_MIN))]
19515   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19516   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19517   [(set_attr "type" "sseadd")
19518    (set_attr "mode" "<MODE>")])
19519
19520 (define_insn "*ieee_smax<mode>3"
19521   [(set (match_operand:MODEF 0 "register_operand" "=x")
19522         (unspec:MODEF
19523           [(match_operand:MODEF 1 "register_operand" "0")
19524            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19525          UNSPEC_IEEE_MAX))]
19526   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19527   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19528   [(set_attr "type" "sseadd")
19529    (set_attr "mode" "<MODE>")])
19530
19531 ;; Make two stack loads independent:
19532 ;;   fld aa              fld aa
19533 ;;   fld %st(0)     ->   fld bb
19534 ;;   fmul bb             fmul %st(1), %st
19535 ;;
19536 ;; Actually we only match the last two instructions for simplicity.
19537 (define_peephole2
19538   [(set (match_operand 0 "fp_register_operand" "")
19539         (match_operand 1 "fp_register_operand" ""))
19540    (set (match_dup 0)
19541         (match_operator 2 "binary_fp_operator"
19542            [(match_dup 0)
19543             (match_operand 3 "memory_operand" "")]))]
19544   "REGNO (operands[0]) != REGNO (operands[1])"
19545   [(set (match_dup 0) (match_dup 3))
19546    (set (match_dup 0) (match_dup 4))]
19547
19548   ;; The % modifier is not operational anymore in peephole2's, so we have to
19549   ;; swap the operands manually in the case of addition and multiplication.
19550   "if (COMMUTATIVE_ARITH_P (operands[2]))
19551      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19552                                  operands[0], operands[1]);
19553    else
19554      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19555                                  operands[1], operands[0]);")
19556
19557 ;; Conditional addition patterns
19558 (define_expand "add<mode>cc"
19559   [(match_operand:SWI 0 "register_operand" "")
19560    (match_operand 1 "comparison_operator" "")
19561    (match_operand:SWI 2 "register_operand" "")
19562    (match_operand:SWI 3 "const_int_operand" "")]
19563   ""
19564   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19565
19566 \f
19567 ;; Misc patterns (?)
19568
19569 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19570 ;; Otherwise there will be nothing to keep
19571 ;;
19572 ;; [(set (reg ebp) (reg esp))]
19573 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19574 ;;  (clobber (eflags)]
19575 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19576 ;;
19577 ;; in proper program order.
19578 (define_insn "pro_epilogue_adjust_stack_1"
19579   [(set (match_operand:SI 0 "register_operand" "=r,r")
19580         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19581                  (match_operand:SI 2 "immediate_operand" "i,i")))
19582    (clobber (reg:CC FLAGS_REG))
19583    (clobber (mem:BLK (scratch)))]
19584   "!TARGET_64BIT"
19585 {
19586   switch (get_attr_type (insn))
19587     {
19588     case TYPE_IMOV:
19589       return "mov{l}\t{%1, %0|%0, %1}";
19590
19591     case TYPE_ALU:
19592       if (CONST_INT_P (operands[2])
19593           && (INTVAL (operands[2]) == 128
19594               || (INTVAL (operands[2]) < 0
19595                   && INTVAL (operands[2]) != -128)))
19596         {
19597           operands[2] = GEN_INT (-INTVAL (operands[2]));
19598           return "sub{l}\t{%2, %0|%0, %2}";
19599         }
19600       return "add{l}\t{%2, %0|%0, %2}";
19601
19602     case TYPE_LEA:
19603       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19604       return "lea{l}\t{%a2, %0|%0, %a2}";
19605
19606     default:
19607       gcc_unreachable ();
19608     }
19609 }
19610   [(set (attr "type")
19611         (cond [(eq_attr "alternative" "0")
19612                  (const_string "alu")
19613                (match_operand:SI 2 "const0_operand" "")
19614                  (const_string "imov")
19615               ]
19616               (const_string "lea")))
19617    (set_attr "mode" "SI")])
19618
19619 (define_insn "pro_epilogue_adjust_stack_rex64"
19620   [(set (match_operand:DI 0 "register_operand" "=r,r")
19621         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19622                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19623    (clobber (reg:CC FLAGS_REG))
19624    (clobber (mem:BLK (scratch)))]
19625   "TARGET_64BIT"
19626 {
19627   switch (get_attr_type (insn))
19628     {
19629     case TYPE_IMOV:
19630       return "mov{q}\t{%1, %0|%0, %1}";
19631
19632     case TYPE_ALU:
19633       if (CONST_INT_P (operands[2])
19634           /* Avoid overflows.  */
19635           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19636           && (INTVAL (operands[2]) == 128
19637               || (INTVAL (operands[2]) < 0
19638                   && INTVAL (operands[2]) != -128)))
19639         {
19640           operands[2] = GEN_INT (-INTVAL (operands[2]));
19641           return "sub{q}\t{%2, %0|%0, %2}";
19642         }
19643       return "add{q}\t{%2, %0|%0, %2}";
19644
19645     case TYPE_LEA:
19646       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19647       return "lea{q}\t{%a2, %0|%0, %a2}";
19648
19649     default:
19650       gcc_unreachable ();
19651     }
19652 }
19653   [(set (attr "type")
19654         (cond [(eq_attr "alternative" "0")
19655                  (const_string "alu")
19656                (match_operand:DI 2 "const0_operand" "")
19657                  (const_string "imov")
19658               ]
19659               (const_string "lea")))
19660    (set_attr "mode" "DI")])
19661
19662 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19663   [(set (match_operand:DI 0 "register_operand" "=r,r")
19664         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19665                  (match_operand:DI 3 "immediate_operand" "i,i")))
19666    (use (match_operand:DI 2 "register_operand" "r,r"))
19667    (clobber (reg:CC FLAGS_REG))
19668    (clobber (mem:BLK (scratch)))]
19669   "TARGET_64BIT"
19670 {
19671   switch (get_attr_type (insn))
19672     {
19673     case TYPE_ALU:
19674       return "add{q}\t{%2, %0|%0, %2}";
19675
19676     case TYPE_LEA:
19677       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19678       return "lea{q}\t{%a2, %0|%0, %a2}";
19679
19680     default:
19681       gcc_unreachable ();
19682     }
19683 }
19684   [(set_attr "type" "alu,lea")
19685    (set_attr "mode" "DI")])
19686
19687 (define_insn "allocate_stack_worker_32"
19688   [(set (match_operand:SI 0 "register_operand" "+a")
19689         (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19690    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19691    (clobber (reg:CC FLAGS_REG))]
19692   "!TARGET_64BIT && TARGET_STACK_PROBE"
19693   "call\t___chkstk"
19694   [(set_attr "type" "multi")
19695    (set_attr "length" "5")])
19696
19697 (define_insn "allocate_stack_worker_64"
19698   [(set (match_operand:DI 0 "register_operand" "=a")
19699         (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19700    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19701    (clobber (reg:DI R10_REG))
19702    (clobber (reg:DI R11_REG))
19703    (clobber (reg:CC FLAGS_REG))]
19704   "TARGET_64BIT && TARGET_STACK_PROBE"
19705   "call\t___chkstk"
19706   [(set_attr "type" "multi")
19707    (set_attr "length" "5")])
19708
19709 (define_expand "allocate_stack"
19710   [(match_operand 0 "register_operand" "")
19711    (match_operand 1 "general_operand" "")]
19712   "TARGET_STACK_PROBE"
19713 {
19714   rtx x;
19715
19716 #ifndef CHECK_STACK_LIMIT
19717 #define CHECK_STACK_LIMIT 0
19718 #endif
19719
19720   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19721       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19722     {
19723       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19724                                stack_pointer_rtx, 0, OPTAB_DIRECT);
19725       if (x != stack_pointer_rtx)
19726         emit_move_insn (stack_pointer_rtx, x);
19727     }
19728   else
19729     {
19730       x = copy_to_mode_reg (Pmode, operands[1]);
19731       if (TARGET_64BIT)
19732         x = gen_allocate_stack_worker_64 (x);
19733       else
19734         x = gen_allocate_stack_worker_32 (x);
19735       emit_insn (x);
19736     }
19737
19738   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19739   DONE;
19740 })
19741
19742 (define_expand "builtin_setjmp_receiver"
19743   [(label_ref (match_operand 0 "" ""))]
19744   "!TARGET_64BIT && flag_pic"
19745 {
19746   if (TARGET_MACHO)
19747     {
19748       rtx xops[3];
19749       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19750       rtx label_rtx = gen_label_rtx ();
19751       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19752       xops[0] = xops[1] = picreg;
19753       xops[2] = gen_rtx_CONST (SImode,
19754                   gen_rtx_MINUS (SImode,
19755                     gen_rtx_LABEL_REF (SImode, label_rtx),
19756                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19757       ix86_expand_binary_operator (MINUS, SImode, xops);
19758     }
19759   else
19760     emit_insn (gen_set_got (pic_offset_table_rtx));
19761   DONE;
19762 })
19763 \f
19764 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19765
19766 (define_split
19767   [(set (match_operand 0 "register_operand" "")
19768         (match_operator 3 "promotable_binary_operator"
19769            [(match_operand 1 "register_operand" "")
19770             (match_operand 2 "aligned_operand" "")]))
19771    (clobber (reg:CC FLAGS_REG))]
19772   "! TARGET_PARTIAL_REG_STALL && reload_completed
19773    && ((GET_MODE (operands[0]) == HImode
19774         && ((!optimize_size && !TARGET_FAST_PREFIX)
19775             /* ??? next two lines just !satisfies_constraint_K (...) */
19776             || !CONST_INT_P (operands[2])
19777             || satisfies_constraint_K (operands[2])))
19778        || (GET_MODE (operands[0]) == QImode
19779            && (TARGET_PROMOTE_QImode || optimize_size)))"
19780   [(parallel [(set (match_dup 0)
19781                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19782               (clobber (reg:CC FLAGS_REG))])]
19783   "operands[0] = gen_lowpart (SImode, operands[0]);
19784    operands[1] = gen_lowpart (SImode, operands[1]);
19785    if (GET_CODE (operands[3]) != ASHIFT)
19786      operands[2] = gen_lowpart (SImode, operands[2]);
19787    PUT_MODE (operands[3], SImode);")
19788
19789 ; Promote the QImode tests, as i386 has encoding of the AND
19790 ; instruction with 32-bit sign-extended immediate and thus the
19791 ; instruction size is unchanged, except in the %eax case for
19792 ; which it is increased by one byte, hence the ! optimize_size.
19793 (define_split
19794   [(set (match_operand 0 "flags_reg_operand" "")
19795         (match_operator 2 "compare_operator"
19796           [(and (match_operand 3 "aligned_operand" "")
19797                 (match_operand 4 "const_int_operand" ""))
19798            (const_int 0)]))
19799    (set (match_operand 1 "register_operand" "")
19800         (and (match_dup 3) (match_dup 4)))]
19801   "! TARGET_PARTIAL_REG_STALL && reload_completed
19802    && ! optimize_size
19803    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19804        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19805    /* Ensure that the operand will remain sign-extended immediate.  */
19806    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19807   [(parallel [(set (match_dup 0)
19808                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19809                                     (const_int 0)]))
19810               (set (match_dup 1)
19811                    (and:SI (match_dup 3) (match_dup 4)))])]
19812 {
19813   operands[4]
19814     = gen_int_mode (INTVAL (operands[4])
19815                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19816   operands[1] = gen_lowpart (SImode, operands[1]);
19817   operands[3] = gen_lowpart (SImode, operands[3]);
19818 })
19819
19820 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19821 ; the TEST instruction with 32-bit sign-extended immediate and thus
19822 ; the instruction size would at least double, which is not what we
19823 ; want even with ! optimize_size.
19824 (define_split
19825   [(set (match_operand 0 "flags_reg_operand" "")
19826         (match_operator 1 "compare_operator"
19827           [(and (match_operand:HI 2 "aligned_operand" "")
19828                 (match_operand:HI 3 "const_int_operand" ""))
19829            (const_int 0)]))]
19830   "! TARGET_PARTIAL_REG_STALL && reload_completed
19831    && ! TARGET_FAST_PREFIX
19832    && ! optimize_size
19833    /* Ensure that the operand will remain sign-extended immediate.  */
19834    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19835   [(set (match_dup 0)
19836         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19837                          (const_int 0)]))]
19838 {
19839   operands[3]
19840     = gen_int_mode (INTVAL (operands[3])
19841                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19842   operands[2] = gen_lowpart (SImode, operands[2]);
19843 })
19844
19845 (define_split
19846   [(set (match_operand 0 "register_operand" "")
19847         (neg (match_operand 1 "register_operand" "")))
19848    (clobber (reg:CC FLAGS_REG))]
19849   "! TARGET_PARTIAL_REG_STALL && reload_completed
19850    && (GET_MODE (operands[0]) == HImode
19851        || (GET_MODE (operands[0]) == QImode
19852            && (TARGET_PROMOTE_QImode || optimize_size)))"
19853   [(parallel [(set (match_dup 0)
19854                    (neg:SI (match_dup 1)))
19855               (clobber (reg:CC FLAGS_REG))])]
19856   "operands[0] = gen_lowpart (SImode, operands[0]);
19857    operands[1] = gen_lowpart (SImode, operands[1]);")
19858
19859 (define_split
19860   [(set (match_operand 0 "register_operand" "")
19861         (not (match_operand 1 "register_operand" "")))]
19862   "! TARGET_PARTIAL_REG_STALL && reload_completed
19863    && (GET_MODE (operands[0]) == HImode
19864        || (GET_MODE (operands[0]) == QImode
19865            && (TARGET_PROMOTE_QImode || optimize_size)))"
19866   [(set (match_dup 0)
19867         (not:SI (match_dup 1)))]
19868   "operands[0] = gen_lowpart (SImode, operands[0]);
19869    operands[1] = gen_lowpart (SImode, operands[1]);")
19870
19871 (define_split
19872   [(set (match_operand 0 "register_operand" "")
19873         (if_then_else (match_operator 1 "comparison_operator"
19874                                 [(reg FLAGS_REG) (const_int 0)])
19875                       (match_operand 2 "register_operand" "")
19876                       (match_operand 3 "register_operand" "")))]
19877   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19878    && (GET_MODE (operands[0]) == HImode
19879        || (GET_MODE (operands[0]) == QImode
19880            && (TARGET_PROMOTE_QImode || optimize_size)))"
19881   [(set (match_dup 0)
19882         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19883   "operands[0] = gen_lowpart (SImode, operands[0]);
19884    operands[2] = gen_lowpart (SImode, operands[2]);
19885    operands[3] = gen_lowpart (SImode, operands[3]);")
19886
19887 \f
19888 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19889 ;; transform a complex memory operation into two memory to register operations.
19890
19891 ;; Don't push memory operands
19892 (define_peephole2
19893   [(set (match_operand:SI 0 "push_operand" "")
19894         (match_operand:SI 1 "memory_operand" ""))
19895    (match_scratch:SI 2 "r")]
19896   "!optimize_size && !TARGET_PUSH_MEMORY
19897    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19898   [(set (match_dup 2) (match_dup 1))
19899    (set (match_dup 0) (match_dup 2))]
19900   "")
19901
19902 (define_peephole2
19903   [(set (match_operand:DI 0 "push_operand" "")
19904         (match_operand:DI 1 "memory_operand" ""))
19905    (match_scratch:DI 2 "r")]
19906   "!optimize_size && !TARGET_PUSH_MEMORY
19907    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19908   [(set (match_dup 2) (match_dup 1))
19909    (set (match_dup 0) (match_dup 2))]
19910   "")
19911
19912 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19913 ;; SImode pushes.
19914 (define_peephole2
19915   [(set (match_operand:SF 0 "push_operand" "")
19916         (match_operand:SF 1 "memory_operand" ""))
19917    (match_scratch:SF 2 "r")]
19918   "!optimize_size && !TARGET_PUSH_MEMORY
19919    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19920   [(set (match_dup 2) (match_dup 1))
19921    (set (match_dup 0) (match_dup 2))]
19922   "")
19923
19924 (define_peephole2
19925   [(set (match_operand:HI 0 "push_operand" "")
19926         (match_operand:HI 1 "memory_operand" ""))
19927    (match_scratch:HI 2 "r")]
19928   "!optimize_size && !TARGET_PUSH_MEMORY
19929    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19930   [(set (match_dup 2) (match_dup 1))
19931    (set (match_dup 0) (match_dup 2))]
19932   "")
19933
19934 (define_peephole2
19935   [(set (match_operand:QI 0 "push_operand" "")
19936         (match_operand:QI 1 "memory_operand" ""))
19937    (match_scratch:QI 2 "q")]
19938   "!optimize_size && !TARGET_PUSH_MEMORY
19939    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19940   [(set (match_dup 2) (match_dup 1))
19941    (set (match_dup 0) (match_dup 2))]
19942   "")
19943
19944 ;; Don't move an immediate directly to memory when the instruction
19945 ;; gets too big.
19946 (define_peephole2
19947   [(match_scratch:SI 1 "r")
19948    (set (match_operand:SI 0 "memory_operand" "")
19949         (const_int 0))]
19950   "! optimize_size
19951    && ! TARGET_USE_MOV0
19952    && TARGET_SPLIT_LONG_MOVES
19953    && get_attr_length (insn) >= ix86_cost->large_insn
19954    && peep2_regno_dead_p (0, FLAGS_REG)"
19955   [(parallel [(set (match_dup 1) (const_int 0))
19956               (clobber (reg:CC FLAGS_REG))])
19957    (set (match_dup 0) (match_dup 1))]
19958   "")
19959
19960 (define_peephole2
19961   [(match_scratch:HI 1 "r")
19962    (set (match_operand:HI 0 "memory_operand" "")
19963         (const_int 0))]
19964   "! optimize_size
19965    && ! TARGET_USE_MOV0
19966    && TARGET_SPLIT_LONG_MOVES
19967    && get_attr_length (insn) >= ix86_cost->large_insn
19968    && peep2_regno_dead_p (0, FLAGS_REG)"
19969   [(parallel [(set (match_dup 2) (const_int 0))
19970               (clobber (reg:CC FLAGS_REG))])
19971    (set (match_dup 0) (match_dup 1))]
19972   "operands[2] = gen_lowpart (SImode, operands[1]);")
19973
19974 (define_peephole2
19975   [(match_scratch:QI 1 "q")
19976    (set (match_operand:QI 0 "memory_operand" "")
19977         (const_int 0))]
19978   "! optimize_size
19979    && ! TARGET_USE_MOV0
19980    && TARGET_SPLIT_LONG_MOVES
19981    && get_attr_length (insn) >= ix86_cost->large_insn
19982    && peep2_regno_dead_p (0, FLAGS_REG)"
19983   [(parallel [(set (match_dup 2) (const_int 0))
19984               (clobber (reg:CC FLAGS_REG))])
19985    (set (match_dup 0) (match_dup 1))]
19986   "operands[2] = gen_lowpart (SImode, operands[1]);")
19987
19988 (define_peephole2
19989   [(match_scratch:SI 2 "r")
19990    (set (match_operand:SI 0 "memory_operand" "")
19991         (match_operand:SI 1 "immediate_operand" ""))]
19992   "! optimize_size
19993    && TARGET_SPLIT_LONG_MOVES
19994    && get_attr_length (insn) >= ix86_cost->large_insn"
19995   [(set (match_dup 2) (match_dup 1))
19996    (set (match_dup 0) (match_dup 2))]
19997   "")
19998
19999 (define_peephole2
20000   [(match_scratch:HI 2 "r")
20001    (set (match_operand:HI 0 "memory_operand" "")
20002         (match_operand:HI 1 "immediate_operand" ""))]
20003   "! optimize_size
20004    && TARGET_SPLIT_LONG_MOVES
20005    && get_attr_length (insn) >= ix86_cost->large_insn"
20006   [(set (match_dup 2) (match_dup 1))
20007    (set (match_dup 0) (match_dup 2))]
20008   "")
20009
20010 (define_peephole2
20011   [(match_scratch:QI 2 "q")
20012    (set (match_operand:QI 0 "memory_operand" "")
20013         (match_operand:QI 1 "immediate_operand" ""))]
20014   "! optimize_size
20015    && TARGET_SPLIT_LONG_MOVES
20016    && get_attr_length (insn) >= ix86_cost->large_insn"
20017   [(set (match_dup 2) (match_dup 1))
20018    (set (match_dup 0) (match_dup 2))]
20019   "")
20020
20021 ;; Don't compare memory with zero, load and use a test instead.
20022 (define_peephole2
20023   [(set (match_operand 0 "flags_reg_operand" "")
20024         (match_operator 1 "compare_operator"
20025           [(match_operand:SI 2 "memory_operand" "")
20026            (const_int 0)]))
20027    (match_scratch:SI 3 "r")]
20028   " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20029   [(set (match_dup 3) (match_dup 2))
20030    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20031   "")
20032
20033 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20034 ;; Don't split NOTs with a displacement operand, because resulting XOR
20035 ;; will not be pairable anyway.
20036 ;;
20037 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20038 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20039 ;; so this split helps here as well.
20040 ;;
20041 ;; Note: Can't do this as a regular split because we can't get proper
20042 ;; lifetime information then.
20043
20044 (define_peephole2
20045   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20046         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20047   "!optimize_size
20048    && ((TARGET_NOT_UNPAIRABLE
20049         && (!MEM_P (operands[0])
20050             || !memory_displacement_operand (operands[0], SImode)))
20051        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20052    && peep2_regno_dead_p (0, FLAGS_REG)"
20053   [(parallel [(set (match_dup 0)
20054                    (xor:SI (match_dup 1) (const_int -1)))
20055               (clobber (reg:CC FLAGS_REG))])]
20056   "")
20057
20058 (define_peephole2
20059   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20060         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20061   "!optimize_size
20062    && ((TARGET_NOT_UNPAIRABLE
20063         && (!MEM_P (operands[0])
20064             || !memory_displacement_operand (operands[0], HImode)))
20065        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20066    && peep2_regno_dead_p (0, FLAGS_REG)"
20067   [(parallel [(set (match_dup 0)
20068                    (xor:HI (match_dup 1) (const_int -1)))
20069               (clobber (reg:CC FLAGS_REG))])]
20070   "")
20071
20072 (define_peephole2
20073   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20074         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20075   "!optimize_size
20076    && ((TARGET_NOT_UNPAIRABLE
20077         && (!MEM_P (operands[0])
20078             || !memory_displacement_operand (operands[0], QImode)))
20079        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20080    && peep2_regno_dead_p (0, FLAGS_REG)"
20081   [(parallel [(set (match_dup 0)
20082                    (xor:QI (match_dup 1) (const_int -1)))
20083               (clobber (reg:CC FLAGS_REG))])]
20084   "")
20085
20086 ;; Non pairable "test imm, reg" instructions can be translated to
20087 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20088 ;; byte opcode instead of two, have a short form for byte operands),
20089 ;; so do it for other CPUs as well.  Given that the value was dead,
20090 ;; this should not create any new dependencies.  Pass on the sub-word
20091 ;; versions if we're concerned about partial register stalls.
20092
20093 (define_peephole2
20094   [(set (match_operand 0 "flags_reg_operand" "")
20095         (match_operator 1 "compare_operator"
20096           [(and:SI (match_operand:SI 2 "register_operand" "")
20097                    (match_operand:SI 3 "immediate_operand" ""))
20098            (const_int 0)]))]
20099   "ix86_match_ccmode (insn, CCNOmode)
20100    && (true_regnum (operands[2]) != AX_REG
20101        || satisfies_constraint_K (operands[3]))
20102    && peep2_reg_dead_p (1, operands[2])"
20103   [(parallel
20104      [(set (match_dup 0)
20105            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20106                             (const_int 0)]))
20107       (set (match_dup 2)
20108            (and:SI (match_dup 2) (match_dup 3)))])]
20109   "")
20110
20111 ;; We don't need to handle HImode case, because it will be promoted to SImode
20112 ;; on ! TARGET_PARTIAL_REG_STALL
20113
20114 (define_peephole2
20115   [(set (match_operand 0 "flags_reg_operand" "")
20116         (match_operator 1 "compare_operator"
20117           [(and:QI (match_operand:QI 2 "register_operand" "")
20118                    (match_operand:QI 3 "immediate_operand" ""))
20119            (const_int 0)]))]
20120   "! TARGET_PARTIAL_REG_STALL
20121    && ix86_match_ccmode (insn, CCNOmode)
20122    && true_regnum (operands[2]) != AX_REG
20123    && peep2_reg_dead_p (1, operands[2])"
20124   [(parallel
20125      [(set (match_dup 0)
20126            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20127                             (const_int 0)]))
20128       (set (match_dup 2)
20129            (and:QI (match_dup 2) (match_dup 3)))])]
20130   "")
20131
20132 (define_peephole2
20133   [(set (match_operand 0 "flags_reg_operand" "")
20134         (match_operator 1 "compare_operator"
20135           [(and:SI
20136              (zero_extract:SI
20137                (match_operand 2 "ext_register_operand" "")
20138                (const_int 8)
20139                (const_int 8))
20140              (match_operand 3 "const_int_operand" ""))
20141            (const_int 0)]))]
20142   "! TARGET_PARTIAL_REG_STALL
20143    && ix86_match_ccmode (insn, CCNOmode)
20144    && true_regnum (operands[2]) != AX_REG
20145    && peep2_reg_dead_p (1, operands[2])"
20146   [(parallel [(set (match_dup 0)
20147                    (match_op_dup 1
20148                      [(and:SI
20149                         (zero_extract:SI
20150                           (match_dup 2)
20151                           (const_int 8)
20152                           (const_int 8))
20153                         (match_dup 3))
20154                       (const_int 0)]))
20155               (set (zero_extract:SI (match_dup 2)
20156                                     (const_int 8)
20157                                     (const_int 8))
20158                    (and:SI
20159                      (zero_extract:SI
20160                        (match_dup 2)
20161                        (const_int 8)
20162                        (const_int 8))
20163                      (match_dup 3)))])]
20164   "")
20165
20166 ;; Don't do logical operations with memory inputs.
20167 (define_peephole2
20168   [(match_scratch:SI 2 "r")
20169    (parallel [(set (match_operand:SI 0 "register_operand" "")
20170                    (match_operator:SI 3 "arith_or_logical_operator"
20171                      [(match_dup 0)
20172                       (match_operand:SI 1 "memory_operand" "")]))
20173               (clobber (reg:CC FLAGS_REG))])]
20174   "! optimize_size && ! TARGET_READ_MODIFY"
20175   [(set (match_dup 2) (match_dup 1))
20176    (parallel [(set (match_dup 0)
20177                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20178               (clobber (reg:CC FLAGS_REG))])]
20179   "")
20180
20181 (define_peephole2
20182   [(match_scratch:SI 2 "r")
20183    (parallel [(set (match_operand:SI 0 "register_operand" "")
20184                    (match_operator:SI 3 "arith_or_logical_operator"
20185                      [(match_operand:SI 1 "memory_operand" "")
20186                       (match_dup 0)]))
20187               (clobber (reg:CC FLAGS_REG))])]
20188   "! optimize_size && ! TARGET_READ_MODIFY"
20189   [(set (match_dup 2) (match_dup 1))
20190    (parallel [(set (match_dup 0)
20191                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20192               (clobber (reg:CC FLAGS_REG))])]
20193   "")
20194
20195 ; Don't do logical operations with memory outputs
20196 ;
20197 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20198 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20199 ; the same decoder scheduling characteristics as the original.
20200
20201 (define_peephole2
20202   [(match_scratch:SI 2 "r")
20203    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20204                    (match_operator:SI 3 "arith_or_logical_operator"
20205                      [(match_dup 0)
20206                       (match_operand:SI 1 "nonmemory_operand" "")]))
20207               (clobber (reg:CC FLAGS_REG))])]
20208   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20209   [(set (match_dup 2) (match_dup 0))
20210    (parallel [(set (match_dup 2)
20211                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20212               (clobber (reg:CC FLAGS_REG))])
20213    (set (match_dup 0) (match_dup 2))]
20214   "")
20215
20216 (define_peephole2
20217   [(match_scratch:SI 2 "r")
20218    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20219                    (match_operator:SI 3 "arith_or_logical_operator"
20220                      [(match_operand:SI 1 "nonmemory_operand" "")
20221                       (match_dup 0)]))
20222               (clobber (reg:CC FLAGS_REG))])]
20223   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20224   [(set (match_dup 2) (match_dup 0))
20225    (parallel [(set (match_dup 2)
20226                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20227               (clobber (reg:CC FLAGS_REG))])
20228    (set (match_dup 0) (match_dup 2))]
20229   "")
20230
20231 ;; Attempt to always use XOR for zeroing registers.
20232 (define_peephole2
20233   [(set (match_operand 0 "register_operand" "")
20234         (match_operand 1 "const0_operand" ""))]
20235   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20236    && (! TARGET_USE_MOV0 || optimize_size)
20237    && GENERAL_REG_P (operands[0])
20238    && peep2_regno_dead_p (0, FLAGS_REG)"
20239   [(parallel [(set (match_dup 0) (const_int 0))
20240               (clobber (reg:CC FLAGS_REG))])]
20241 {
20242   operands[0] = gen_lowpart (word_mode, operands[0]);
20243 })
20244
20245 (define_peephole2
20246   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20247         (const_int 0))]
20248   "(GET_MODE (operands[0]) == QImode
20249     || GET_MODE (operands[0]) == HImode)
20250    && (! TARGET_USE_MOV0 || optimize_size)
20251    && peep2_regno_dead_p (0, FLAGS_REG)"
20252   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20253               (clobber (reg:CC FLAGS_REG))])])
20254
20255 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20256 (define_peephole2
20257   [(set (match_operand 0 "register_operand" "")
20258         (const_int -1))]
20259   "(GET_MODE (operands[0]) == HImode
20260     || GET_MODE (operands[0]) == SImode
20261     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20262    && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20263    && peep2_regno_dead_p (0, FLAGS_REG)"
20264   [(parallel [(set (match_dup 0) (const_int -1))
20265               (clobber (reg:CC FLAGS_REG))])]
20266   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20267                               operands[0]);")
20268
20269 ;; Attempt to convert simple leas to adds. These can be created by
20270 ;; move expanders.
20271 (define_peephole2
20272   [(set (match_operand:SI 0 "register_operand" "")
20273         (plus:SI (match_dup 0)
20274                  (match_operand:SI 1 "nonmemory_operand" "")))]
20275   "peep2_regno_dead_p (0, FLAGS_REG)"
20276   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20277               (clobber (reg:CC FLAGS_REG))])]
20278   "")
20279
20280 (define_peephole2
20281   [(set (match_operand:SI 0 "register_operand" "")
20282         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20283                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20284   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20285   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20286               (clobber (reg:CC FLAGS_REG))])]
20287   "operands[2] = gen_lowpart (SImode, operands[2]);")
20288
20289 (define_peephole2
20290   [(set (match_operand:DI 0 "register_operand" "")
20291         (plus:DI (match_dup 0)
20292                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20293   "peep2_regno_dead_p (0, FLAGS_REG)"
20294   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20295               (clobber (reg:CC FLAGS_REG))])]
20296   "")
20297
20298 (define_peephole2
20299   [(set (match_operand:SI 0 "register_operand" "")
20300         (mult:SI (match_dup 0)
20301                  (match_operand:SI 1 "const_int_operand" "")))]
20302   "exact_log2 (INTVAL (operands[1])) >= 0
20303    && peep2_regno_dead_p (0, FLAGS_REG)"
20304   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20305               (clobber (reg:CC FLAGS_REG))])]
20306   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20307
20308 (define_peephole2
20309   [(set (match_operand:DI 0 "register_operand" "")
20310         (mult:DI (match_dup 0)
20311                  (match_operand:DI 1 "const_int_operand" "")))]
20312   "exact_log2 (INTVAL (operands[1])) >= 0
20313    && peep2_regno_dead_p (0, FLAGS_REG)"
20314   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20315               (clobber (reg:CC FLAGS_REG))])]
20316   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20317
20318 (define_peephole2
20319   [(set (match_operand:SI 0 "register_operand" "")
20320         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20321                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20322   "exact_log2 (INTVAL (operands[2])) >= 0
20323    && REGNO (operands[0]) == REGNO (operands[1])
20324    && peep2_regno_dead_p (0, FLAGS_REG)"
20325   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20326               (clobber (reg:CC FLAGS_REG))])]
20327   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20328
20329 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20330 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20331 ;; many CPUs it is also faster, since special hardware to avoid esp
20332 ;; dependencies is present.
20333
20334 ;; While some of these conversions may be done using splitters, we use peepholes
20335 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20336
20337 ;; Convert prologue esp subtractions to push.
20338 ;; We need register to push.  In order to keep verify_flow_info happy we have
20339 ;; two choices
20340 ;; - use scratch and clobber it in order to avoid dependencies
20341 ;; - use already live register
20342 ;; We can't use the second way right now, since there is no reliable way how to
20343 ;; verify that given register is live.  First choice will also most likely in
20344 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20345 ;; call clobbered registers are dead.  We may want to use base pointer as an
20346 ;; alternative when no register is available later.
20347
20348 (define_peephole2
20349   [(match_scratch:SI 0 "r")
20350    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20351               (clobber (reg:CC FLAGS_REG))
20352               (clobber (mem:BLK (scratch)))])]
20353   "optimize_size || !TARGET_SUB_ESP_4"
20354   [(clobber (match_dup 0))
20355    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20356               (clobber (mem:BLK (scratch)))])])
20357
20358 (define_peephole2
20359   [(match_scratch:SI 0 "r")
20360    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20361               (clobber (reg:CC FLAGS_REG))
20362               (clobber (mem:BLK (scratch)))])]
20363   "optimize_size || !TARGET_SUB_ESP_8"
20364   [(clobber (match_dup 0))
20365    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20366    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20367               (clobber (mem:BLK (scratch)))])])
20368
20369 ;; Convert esp subtractions to push.
20370 (define_peephole2
20371   [(match_scratch:SI 0 "r")
20372    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20373               (clobber (reg:CC FLAGS_REG))])]
20374   "optimize_size || !TARGET_SUB_ESP_4"
20375   [(clobber (match_dup 0))
20376    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20377
20378 (define_peephole2
20379   [(match_scratch:SI 0 "r")
20380    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20381               (clobber (reg:CC FLAGS_REG))])]
20382   "optimize_size || !TARGET_SUB_ESP_8"
20383   [(clobber (match_dup 0))
20384    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20385    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20386
20387 ;; Convert epilogue deallocator to pop.
20388 (define_peephole2
20389   [(match_scratch:SI 0 "r")
20390    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20391               (clobber (reg:CC FLAGS_REG))
20392               (clobber (mem:BLK (scratch)))])]
20393   "optimize_size || !TARGET_ADD_ESP_4"
20394   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20395               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20396               (clobber (mem:BLK (scratch)))])]
20397   "")
20398
20399 ;; Two pops case is tricky, since pop causes dependency on destination register.
20400 ;; We use two registers if available.
20401 (define_peephole2
20402   [(match_scratch:SI 0 "r")
20403    (match_scratch:SI 1 "r")
20404    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20405               (clobber (reg:CC FLAGS_REG))
20406               (clobber (mem:BLK (scratch)))])]
20407   "optimize_size || !TARGET_ADD_ESP_8"
20408   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20409               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20410               (clobber (mem:BLK (scratch)))])
20411    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20412               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20413   "")
20414
20415 (define_peephole2
20416   [(match_scratch:SI 0 "r")
20417    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20418               (clobber (reg:CC FLAGS_REG))
20419               (clobber (mem:BLK (scratch)))])]
20420   "optimize_size"
20421   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20422               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20423               (clobber (mem:BLK (scratch)))])
20424    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20425               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20426   "")
20427
20428 ;; Convert esp additions to pop.
20429 (define_peephole2
20430   [(match_scratch:SI 0 "r")
20431    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20432               (clobber (reg:CC FLAGS_REG))])]
20433   ""
20434   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20435               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20436   "")
20437
20438 ;; Two pops case is tricky, since pop causes dependency on destination register.
20439 ;; We use two registers if available.
20440 (define_peephole2
20441   [(match_scratch:SI 0 "r")
20442    (match_scratch:SI 1 "r")
20443    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20444               (clobber (reg:CC FLAGS_REG))])]
20445   ""
20446   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20447               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20448    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20449               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20450   "")
20451
20452 (define_peephole2
20453   [(match_scratch:SI 0 "r")
20454    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20455               (clobber (reg:CC FLAGS_REG))])]
20456   "optimize_size"
20457   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20458               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20459    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20460               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20461   "")
20462 \f
20463 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20464 ;; required and register dies.  Similarly for 128 to plus -128.
20465 (define_peephole2
20466   [(set (match_operand 0 "flags_reg_operand" "")
20467         (match_operator 1 "compare_operator"
20468           [(match_operand 2 "register_operand" "")
20469            (match_operand 3 "const_int_operand" "")]))]
20470   "(INTVAL (operands[3]) == -1
20471     || INTVAL (operands[3]) == 1
20472     || INTVAL (operands[3]) == 128)
20473    && ix86_match_ccmode (insn, CCGCmode)
20474    && peep2_reg_dead_p (1, operands[2])"
20475   [(parallel [(set (match_dup 0)
20476                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20477               (clobber (match_dup 2))])]
20478   "")
20479 \f
20480 (define_peephole2
20481   [(match_scratch:DI 0 "r")
20482    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20483               (clobber (reg:CC FLAGS_REG))
20484               (clobber (mem:BLK (scratch)))])]
20485   "optimize_size || !TARGET_SUB_ESP_4"
20486   [(clobber (match_dup 0))
20487    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20488               (clobber (mem:BLK (scratch)))])])
20489
20490 (define_peephole2
20491   [(match_scratch:DI 0 "r")
20492    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20493               (clobber (reg:CC FLAGS_REG))
20494               (clobber (mem:BLK (scratch)))])]
20495   "optimize_size || !TARGET_SUB_ESP_8"
20496   [(clobber (match_dup 0))
20497    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20498    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20499               (clobber (mem:BLK (scratch)))])])
20500
20501 ;; Convert esp subtractions to push.
20502 (define_peephole2
20503   [(match_scratch:DI 0 "r")
20504    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20505               (clobber (reg:CC FLAGS_REG))])]
20506   "optimize_size || !TARGET_SUB_ESP_4"
20507   [(clobber (match_dup 0))
20508    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20509
20510 (define_peephole2
20511   [(match_scratch:DI 0 "r")
20512    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20513               (clobber (reg:CC FLAGS_REG))])]
20514   "optimize_size || !TARGET_SUB_ESP_8"
20515   [(clobber (match_dup 0))
20516    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20517    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20518
20519 ;; Convert epilogue deallocator to pop.
20520 (define_peephole2
20521   [(match_scratch:DI 0 "r")
20522    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20523               (clobber (reg:CC FLAGS_REG))
20524               (clobber (mem:BLK (scratch)))])]
20525   "optimize_size || !TARGET_ADD_ESP_4"
20526   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20527               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20528               (clobber (mem:BLK (scratch)))])]
20529   "")
20530
20531 ;; Two pops case is tricky, since pop causes dependency on destination register.
20532 ;; We use two registers if available.
20533 (define_peephole2
20534   [(match_scratch:DI 0 "r")
20535    (match_scratch:DI 1 "r")
20536    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20537               (clobber (reg:CC FLAGS_REG))
20538               (clobber (mem:BLK (scratch)))])]
20539   "optimize_size || !TARGET_ADD_ESP_8"
20540   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20541               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20542               (clobber (mem:BLK (scratch)))])
20543    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20544               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20545   "")
20546
20547 (define_peephole2
20548   [(match_scratch:DI 0 "r")
20549    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20550               (clobber (reg:CC FLAGS_REG))
20551               (clobber (mem:BLK (scratch)))])]
20552   "optimize_size"
20553   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20554               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20555               (clobber (mem:BLK (scratch)))])
20556    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20557               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20558   "")
20559
20560 ;; Convert esp additions to pop.
20561 (define_peephole2
20562   [(match_scratch:DI 0 "r")
20563    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20564               (clobber (reg:CC FLAGS_REG))])]
20565   ""
20566   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20567               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20568   "")
20569
20570 ;; Two pops case is tricky, since pop causes dependency on destination register.
20571 ;; We use two registers if available.
20572 (define_peephole2
20573   [(match_scratch:DI 0 "r")
20574    (match_scratch:DI 1 "r")
20575    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20576               (clobber (reg:CC FLAGS_REG))])]
20577   ""
20578   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20579               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20580    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20581               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20582   "")
20583
20584 (define_peephole2
20585   [(match_scratch:DI 0 "r")
20586    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20587               (clobber (reg:CC FLAGS_REG))])]
20588   "optimize_size"
20589   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20590               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20591    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20592               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20593   "")
20594 \f
20595 ;; Convert imul by three, five and nine into lea
20596 (define_peephole2
20597   [(parallel
20598     [(set (match_operand:SI 0 "register_operand" "")
20599           (mult:SI (match_operand:SI 1 "register_operand" "")
20600                    (match_operand:SI 2 "const_int_operand" "")))
20601      (clobber (reg:CC FLAGS_REG))])]
20602   "INTVAL (operands[2]) == 3
20603    || INTVAL (operands[2]) == 5
20604    || INTVAL (operands[2]) == 9"
20605   [(set (match_dup 0)
20606         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20607                  (match_dup 1)))]
20608   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20609
20610 (define_peephole2
20611   [(parallel
20612     [(set (match_operand:SI 0 "register_operand" "")
20613           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20614                    (match_operand:SI 2 "const_int_operand" "")))
20615      (clobber (reg:CC FLAGS_REG))])]
20616   "!optimize_size
20617    && (INTVAL (operands[2]) == 3
20618        || INTVAL (operands[2]) == 5
20619        || INTVAL (operands[2]) == 9)"
20620   [(set (match_dup 0) (match_dup 1))
20621    (set (match_dup 0)
20622         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20623                  (match_dup 0)))]
20624   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20625
20626 (define_peephole2
20627   [(parallel
20628     [(set (match_operand:DI 0 "register_operand" "")
20629           (mult:DI (match_operand:DI 1 "register_operand" "")
20630                    (match_operand:DI 2 "const_int_operand" "")))
20631      (clobber (reg:CC FLAGS_REG))])]
20632   "TARGET_64BIT
20633    && (INTVAL (operands[2]) == 3
20634        || INTVAL (operands[2]) == 5
20635        || INTVAL (operands[2]) == 9)"
20636   [(set (match_dup 0)
20637         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20638                  (match_dup 1)))]
20639   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20640
20641 (define_peephole2
20642   [(parallel
20643     [(set (match_operand:DI 0 "register_operand" "")
20644           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20645                    (match_operand:DI 2 "const_int_operand" "")))
20646      (clobber (reg:CC FLAGS_REG))])]
20647   "TARGET_64BIT
20648    && !optimize_size
20649    && (INTVAL (operands[2]) == 3
20650        || INTVAL (operands[2]) == 5
20651        || INTVAL (operands[2]) == 9)"
20652   [(set (match_dup 0) (match_dup 1))
20653    (set (match_dup 0)
20654         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20655                  (match_dup 0)))]
20656   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20657
20658 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20659 ;; imul $32bit_imm, reg, reg is direct decoded.
20660 (define_peephole2
20661   [(match_scratch:DI 3 "r")
20662    (parallel [(set (match_operand:DI 0 "register_operand" "")
20663                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20664                             (match_operand:DI 2 "immediate_operand" "")))
20665               (clobber (reg:CC FLAGS_REG))])]
20666   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20667    && !satisfies_constraint_K (operands[2])"
20668   [(set (match_dup 3) (match_dup 1))
20669    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20670               (clobber (reg:CC FLAGS_REG))])]
20671 "")
20672
20673 (define_peephole2
20674   [(match_scratch:SI 3 "r")
20675    (parallel [(set (match_operand:SI 0 "register_operand" "")
20676                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20677                             (match_operand:SI 2 "immediate_operand" "")))
20678               (clobber (reg:CC FLAGS_REG))])]
20679   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20680    && !satisfies_constraint_K (operands[2])"
20681   [(set (match_dup 3) (match_dup 1))
20682    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20683               (clobber (reg:CC FLAGS_REG))])]
20684 "")
20685
20686 (define_peephole2
20687   [(match_scratch:SI 3 "r")
20688    (parallel [(set (match_operand:DI 0 "register_operand" "")
20689                    (zero_extend:DI
20690                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20691                               (match_operand:SI 2 "immediate_operand" ""))))
20692               (clobber (reg:CC FLAGS_REG))])]
20693   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20694    && !satisfies_constraint_K (operands[2])"
20695   [(set (match_dup 3) (match_dup 1))
20696    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20697               (clobber (reg:CC FLAGS_REG))])]
20698 "")
20699
20700 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20701 ;; Convert it into imul reg, reg
20702 ;; It would be better to force assembler to encode instruction using long
20703 ;; immediate, but there is apparently no way to do so.
20704 (define_peephole2
20705   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20706                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20707                             (match_operand:DI 2 "const_int_operand" "")))
20708               (clobber (reg:CC FLAGS_REG))])
20709    (match_scratch:DI 3 "r")]
20710   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20711    && satisfies_constraint_K (operands[2])"
20712   [(set (match_dup 3) (match_dup 2))
20713    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20714               (clobber (reg:CC FLAGS_REG))])]
20715 {
20716   if (!rtx_equal_p (operands[0], operands[1]))
20717     emit_move_insn (operands[0], operands[1]);
20718 })
20719
20720 (define_peephole2
20721   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20722                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20723                             (match_operand:SI 2 "const_int_operand" "")))
20724               (clobber (reg:CC FLAGS_REG))])
20725    (match_scratch:SI 3 "r")]
20726   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20727    && satisfies_constraint_K (operands[2])"
20728   [(set (match_dup 3) (match_dup 2))
20729    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20730               (clobber (reg:CC FLAGS_REG))])]
20731 {
20732   if (!rtx_equal_p (operands[0], operands[1]))
20733     emit_move_insn (operands[0], operands[1]);
20734 })
20735
20736 (define_peephole2
20737   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20738                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20739                             (match_operand:HI 2 "immediate_operand" "")))
20740               (clobber (reg:CC FLAGS_REG))])
20741    (match_scratch:HI 3 "r")]
20742   "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20743   [(set (match_dup 3) (match_dup 2))
20744    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20745               (clobber (reg:CC FLAGS_REG))])]
20746 {
20747   if (!rtx_equal_p (operands[0], operands[1]))
20748     emit_move_insn (operands[0], operands[1]);
20749 })
20750
20751 ;; After splitting up read-modify operations, array accesses with memory
20752 ;; operands might end up in form:
20753 ;;  sall    $2, %eax
20754 ;;  movl    4(%esp), %edx
20755 ;;  addl    %edx, %eax
20756 ;; instead of pre-splitting:
20757 ;;  sall    $2, %eax
20758 ;;  addl    4(%esp), %eax
20759 ;; Turn it into:
20760 ;;  movl    4(%esp), %edx
20761 ;;  leal    (%edx,%eax,4), %eax
20762
20763 (define_peephole2
20764   [(parallel [(set (match_operand 0 "register_operand" "")
20765                    (ashift (match_operand 1 "register_operand" "")
20766                            (match_operand 2 "const_int_operand" "")))
20767                (clobber (reg:CC FLAGS_REG))])
20768    (set (match_operand 3 "register_operand")
20769         (match_operand 4 "x86_64_general_operand" ""))
20770    (parallel [(set (match_operand 5 "register_operand" "")
20771                    (plus (match_operand 6 "register_operand" "")
20772                          (match_operand 7 "register_operand" "")))
20773                    (clobber (reg:CC FLAGS_REG))])]
20774   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20775    /* Validate MODE for lea.  */
20776    && ((!TARGET_PARTIAL_REG_STALL
20777         && (GET_MODE (operands[0]) == QImode
20778             || GET_MODE (operands[0]) == HImode))
20779        || GET_MODE (operands[0]) == SImode
20780        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20781    /* We reorder load and the shift.  */
20782    && !rtx_equal_p (operands[1], operands[3])
20783    && !reg_overlap_mentioned_p (operands[0], operands[4])
20784    /* Last PLUS must consist of operand 0 and 3.  */
20785    && !rtx_equal_p (operands[0], operands[3])
20786    && (rtx_equal_p (operands[3], operands[6])
20787        || rtx_equal_p (operands[3], operands[7]))
20788    && (rtx_equal_p (operands[0], operands[6])
20789        || rtx_equal_p (operands[0], operands[7]))
20790    /* The intermediate operand 0 must die or be same as output.  */
20791    && (rtx_equal_p (operands[0], operands[5])
20792        || peep2_reg_dead_p (3, operands[0]))"
20793   [(set (match_dup 3) (match_dup 4))
20794    (set (match_dup 0) (match_dup 1))]
20795 {
20796   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20797   int scale = 1 << INTVAL (operands[2]);
20798   rtx index = gen_lowpart (Pmode, operands[1]);
20799   rtx base = gen_lowpart (Pmode, operands[3]);
20800   rtx dest = gen_lowpart (mode, operands[5]);
20801
20802   operands[1] = gen_rtx_PLUS (Pmode, base,
20803                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20804   if (mode != Pmode)
20805     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20806   operands[0] = dest;
20807 })
20808 \f
20809 ;; Call-value patterns last so that the wildcard operand does not
20810 ;; disrupt insn-recog's switch tables.
20811
20812 (define_insn "*call_value_pop_0"
20813   [(set (match_operand 0 "" "")
20814         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20815               (match_operand:SI 2 "" "")))
20816    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20817                             (match_operand:SI 3 "immediate_operand" "")))]
20818   "!TARGET_64BIT"
20819 {
20820   if (SIBLING_CALL_P (insn))
20821     return "jmp\t%P1";
20822   else
20823     return "call\t%P1";
20824 }
20825   [(set_attr "type" "callv")])
20826
20827 (define_insn "*call_value_pop_1"
20828   [(set (match_operand 0 "" "")
20829         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20830               (match_operand:SI 2 "" "")))
20831    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20832                             (match_operand:SI 3 "immediate_operand" "i")))]
20833   "!TARGET_64BIT"
20834 {
20835   if (constant_call_address_operand (operands[1], Pmode))
20836     {
20837       if (SIBLING_CALL_P (insn))
20838         return "jmp\t%P1";
20839       else
20840         return "call\t%P1";
20841     }
20842   if (SIBLING_CALL_P (insn))
20843     return "jmp\t%A1";
20844   else
20845     return "call\t%A1";
20846 }
20847   [(set_attr "type" "callv")])
20848
20849 (define_insn "*call_value_0"
20850   [(set (match_operand 0 "" "")
20851         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20852               (match_operand:SI 2 "" "")))]
20853   "!TARGET_64BIT"
20854 {
20855   if (SIBLING_CALL_P (insn))
20856     return "jmp\t%P1";
20857   else
20858     return "call\t%P1";
20859 }
20860   [(set_attr "type" "callv")])
20861
20862 (define_insn "*call_value_0_rex64"
20863   [(set (match_operand 0 "" "")
20864         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20865               (match_operand:DI 2 "const_int_operand" "")))]
20866   "TARGET_64BIT"
20867 {
20868   if (SIBLING_CALL_P (insn))
20869     return "jmp\t%P1";
20870   else
20871     return "call\t%P1";
20872 }
20873   [(set_attr "type" "callv")])
20874
20875 (define_insn "*call_value_1"
20876   [(set (match_operand 0 "" "")
20877         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20878               (match_operand:SI 2 "" "")))]
20879   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20880 {
20881   if (constant_call_address_operand (operands[1], Pmode))
20882     return "call\t%P1";
20883   return "call\t%A1";
20884 }
20885   [(set_attr "type" "callv")])
20886
20887 (define_insn "*sibcall_value_1"
20888   [(set (match_operand 0 "" "")
20889         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20890               (match_operand:SI 2 "" "")))]
20891   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20892 {
20893   if (constant_call_address_operand (operands[1], Pmode))
20894     return "jmp\t%P1";
20895   return "jmp\t%A1";
20896 }
20897   [(set_attr "type" "callv")])
20898
20899 (define_insn "*call_value_1_rex64"
20900   [(set (match_operand 0 "" "")
20901         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20902               (match_operand:DI 2 "" "")))]
20903   "!SIBLING_CALL_P (insn) && TARGET_64BIT
20904    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20905 {
20906   if (constant_call_address_operand (operands[1], Pmode))
20907     return "call\t%P1";
20908   return "call\t%A1";
20909 }
20910   [(set_attr "type" "callv")])
20911
20912 (define_insn "*call_value_1_rex64_large"
20913   [(set (match_operand 0 "" "")
20914         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20915               (match_operand:DI 2 "" "")))]
20916   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20917   "call\t%A1"
20918   [(set_attr "type" "callv")])
20919
20920 (define_insn "*sibcall_value_1_rex64"
20921   [(set (match_operand 0 "" "")
20922         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20923               (match_operand:DI 2 "" "")))]
20924   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20925   "jmp\t%P1"
20926   [(set_attr "type" "callv")])
20927
20928 (define_insn "*sibcall_value_1_rex64_v"
20929   [(set (match_operand 0 "" "")
20930         (call (mem:QI (reg:DI R11_REG))
20931               (match_operand:DI 1 "" "")))]
20932   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20933   "jmp\t{*%%}r11"
20934   [(set_attr "type" "callv")])
20935 \f
20936 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20937 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20938 ;; caught for use by garbage collectors and the like.  Using an insn that
20939 ;; maps to SIGILL makes it more likely the program will rightfully die.
20940 ;; Keeping with tradition, "6" is in honor of #UD.
20941 (define_insn "trap"
20942   [(trap_if (const_int 1) (const_int 6))]
20943   ""
20944   { return ASM_SHORT "0x0b0f"; }
20945   [(set_attr "length" "2")])
20946
20947 (define_expand "sse_prologue_save"
20948   [(parallel [(set (match_operand:BLK 0 "" "")
20949                    (unspec:BLK [(reg:DI 21)
20950                                 (reg:DI 22)
20951                                 (reg:DI 23)
20952                                 (reg:DI 24)
20953                                 (reg:DI 25)
20954                                 (reg:DI 26)
20955                                 (reg:DI 27)
20956                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20957               (use (match_operand:DI 1 "register_operand" ""))
20958               (use (match_operand:DI 2 "immediate_operand" ""))
20959               (use (label_ref:DI (match_operand 3 "" "")))])]
20960   "TARGET_64BIT"
20961   "")
20962
20963 (define_insn "*sse_prologue_save_insn"
20964   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20965                           (match_operand:DI 4 "const_int_operand" "n")))
20966         (unspec:BLK [(reg:DI 21)
20967                      (reg:DI 22)
20968                      (reg:DI 23)
20969                      (reg:DI 24)
20970                      (reg:DI 25)
20971                      (reg:DI 26)
20972                      (reg:DI 27)
20973                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20974    (use (match_operand:DI 1 "register_operand" "r"))
20975    (use (match_operand:DI 2 "const_int_operand" "i"))
20976    (use (label_ref:DI (match_operand 3 "" "X")))]
20977   "TARGET_64BIT
20978    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20979    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20980 {
20981   int i;
20982   operands[0] = gen_rtx_MEM (Pmode,
20983                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20984   output_asm_insn ("jmp\t%A1", operands);
20985   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20986     {
20987       operands[4] = adjust_address (operands[0], DImode, i*16);
20988       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20989       PUT_MODE (operands[4], TImode);
20990       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20991         output_asm_insn ("rex", operands);
20992       output_asm_insn ("movaps\t{%5, %4|%4, %5}", operands);
20993     }
20994   (*targetm.asm_out.internal_label) (asm_out_file, "L",
20995                                      CODE_LABEL_NUMBER (operands[3]));
20996   return "";
20997 }
20998   [(set_attr "type" "other")
20999    (set_attr "length_immediate" "0")
21000    (set_attr "length_address" "0")
21001    (set_attr "length" "135")
21002    (set_attr "memory" "store")
21003    (set_attr "modrm" "0")
21004    (set_attr "mode" "DI")])
21005
21006 (define_expand "prefetch"
21007   [(prefetch (match_operand 0 "address_operand" "")
21008              (match_operand:SI 1 "const_int_operand" "")
21009              (match_operand:SI 2 "const_int_operand" ""))]
21010   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21011 {
21012   int rw = INTVAL (operands[1]);
21013   int locality = INTVAL (operands[2]);
21014
21015   gcc_assert (rw == 0 || rw == 1);
21016   gcc_assert (locality >= 0 && locality <= 3);
21017   gcc_assert (GET_MODE (operands[0]) == Pmode
21018               || GET_MODE (operands[0]) == VOIDmode);
21019
21020   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21021      supported by SSE counterpart or the SSE prefetch is not available
21022      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21023      of locality.  */
21024   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21025     operands[2] = GEN_INT (3);
21026   else
21027     operands[1] = const0_rtx;
21028 })
21029
21030 (define_insn "*prefetch_sse"
21031   [(prefetch (match_operand:SI 0 "address_operand" "p")
21032              (const_int 0)
21033              (match_operand:SI 1 "const_int_operand" ""))]
21034   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21035 {
21036   static const char * const patterns[4] = {
21037    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21038   };
21039
21040   int locality = INTVAL (operands[1]);
21041   gcc_assert (locality >= 0 && locality <= 3);
21042
21043   return patterns[locality];
21044 }
21045   [(set_attr "type" "sse")
21046    (set_attr "memory" "none")])
21047
21048 (define_insn "*prefetch_sse_rex"
21049   [(prefetch (match_operand:DI 0 "address_operand" "p")
21050              (const_int 0)
21051              (match_operand:SI 1 "const_int_operand" ""))]
21052   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21053 {
21054   static const char * const patterns[4] = {
21055    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21056   };
21057
21058   int locality = INTVAL (operands[1]);
21059   gcc_assert (locality >= 0 && locality <= 3);
21060
21061   return patterns[locality];
21062 }
21063   [(set_attr "type" "sse")
21064    (set_attr "memory" "none")])
21065
21066 (define_insn "*prefetch_3dnow"
21067   [(prefetch (match_operand:SI 0 "address_operand" "p")
21068              (match_operand:SI 1 "const_int_operand" "n")
21069              (const_int 3))]
21070   "TARGET_3DNOW && !TARGET_64BIT"
21071 {
21072   if (INTVAL (operands[1]) == 0)
21073     return "prefetch\t%a0";
21074   else
21075     return "prefetchw\t%a0";
21076 }
21077   [(set_attr "type" "mmx")
21078    (set_attr "memory" "none")])
21079
21080 (define_insn "*prefetch_3dnow_rex"
21081   [(prefetch (match_operand:DI 0 "address_operand" "p")
21082              (match_operand:SI 1 "const_int_operand" "n")
21083              (const_int 3))]
21084   "TARGET_3DNOW && TARGET_64BIT"
21085 {
21086   if (INTVAL (operands[1]) == 0)
21087     return "prefetch\t%a0";
21088   else
21089     return "prefetchw\t%a0";
21090 }
21091   [(set_attr "type" "mmx")
21092    (set_attr "memory" "none")])
21093
21094 (define_expand "stack_protect_set"
21095   [(match_operand 0 "memory_operand" "")
21096    (match_operand 1 "memory_operand" "")]
21097   ""
21098 {
21099 #ifdef TARGET_THREAD_SSP_OFFSET
21100   if (TARGET_64BIT)
21101     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21102                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21103   else
21104     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21105                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21106 #else
21107   if (TARGET_64BIT)
21108     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21109   else
21110     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21111 #endif
21112   DONE;
21113 })
21114
21115 (define_insn "stack_protect_set_si"
21116   [(set (match_operand:SI 0 "memory_operand" "=m")
21117         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21118    (set (match_scratch:SI 2 "=&r") (const_int 0))
21119    (clobber (reg:CC FLAGS_REG))]
21120   ""
21121   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21122   [(set_attr "type" "multi")])
21123
21124 (define_insn "stack_protect_set_di"
21125   [(set (match_operand:DI 0 "memory_operand" "=m")
21126         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21127    (set (match_scratch:DI 2 "=&r") (const_int 0))
21128    (clobber (reg:CC FLAGS_REG))]
21129   "TARGET_64BIT"
21130   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21131   [(set_attr "type" "multi")])
21132
21133 (define_insn "stack_tls_protect_set_si"
21134   [(set (match_operand:SI 0 "memory_operand" "=m")
21135         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21136    (set (match_scratch:SI 2 "=&r") (const_int 0))
21137    (clobber (reg:CC FLAGS_REG))]
21138   ""
21139   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21140   [(set_attr "type" "multi")])
21141
21142 (define_insn "stack_tls_protect_set_di"
21143   [(set (match_operand:DI 0 "memory_operand" "=m")
21144         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21145    (set (match_scratch:DI 2 "=&r") (const_int 0))
21146    (clobber (reg:CC FLAGS_REG))]
21147   "TARGET_64BIT"
21148   {
21149      /* The kernel uses a different segment register for performance reasons; a
21150         system call would not have to trash the userspace segment register,
21151         which would be expensive */
21152      if (ix86_cmodel != CM_KERNEL)
21153         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21154      else
21155         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21156   }
21157   [(set_attr "type" "multi")])
21158
21159 (define_expand "stack_protect_test"
21160   [(match_operand 0 "memory_operand" "")
21161    (match_operand 1 "memory_operand" "")
21162    (match_operand 2 "" "")]
21163   ""
21164 {
21165   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21166   ix86_compare_op0 = operands[0];
21167   ix86_compare_op1 = operands[1];
21168   ix86_compare_emitted = flags;
21169
21170 #ifdef TARGET_THREAD_SSP_OFFSET
21171   if (TARGET_64BIT)
21172     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21173                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21174   else
21175     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21176                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21177 #else
21178   if (TARGET_64BIT)
21179     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21180   else
21181     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21182 #endif
21183   emit_jump_insn (gen_beq (operands[2]));
21184   DONE;
21185 })
21186
21187 (define_insn "stack_protect_test_si"
21188   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21189         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21190                      (match_operand:SI 2 "memory_operand" "m")]
21191                     UNSPEC_SP_TEST))
21192    (clobber (match_scratch:SI 3 "=&r"))]
21193   ""
21194   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21195   [(set_attr "type" "multi")])
21196
21197 (define_insn "stack_protect_test_di"
21198   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21199         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21200                      (match_operand:DI 2 "memory_operand" "m")]
21201                     UNSPEC_SP_TEST))
21202    (clobber (match_scratch:DI 3 "=&r"))]
21203   "TARGET_64BIT"
21204   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21205   [(set_attr "type" "multi")])
21206
21207 (define_insn "stack_tls_protect_test_si"
21208   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21209         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21210                      (match_operand:SI 2 "const_int_operand" "i")]
21211                     UNSPEC_SP_TLS_TEST))
21212    (clobber (match_scratch:SI 3 "=r"))]
21213   ""
21214   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21215   [(set_attr "type" "multi")])
21216
21217 (define_insn "stack_tls_protect_test_di"
21218   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21219         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21220                      (match_operand:DI 2 "const_int_operand" "i")]
21221                     UNSPEC_SP_TLS_TEST))
21222    (clobber (match_scratch:DI 3 "=r"))]
21223   "TARGET_64BIT"
21224   {
21225      /* The kernel uses a different segment register for performance reasons; a
21226         system call would not have to trash the userspace segment register,
21227         which would be expensive */
21228      if (ix86_cmodel != CM_KERNEL)
21229         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21230      else
21231         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21232   }
21233   [(set_attr "type" "multi")])
21234
21235 (define_mode_iterator CRC32MODE [QI HI SI])
21236 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21237 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21238
21239 (define_insn "sse4_2_crc32<mode>"
21240   [(set (match_operand:SI 0 "register_operand" "=r")
21241         (unspec:SI
21242           [(match_operand:SI 1 "register_operand" "0")
21243            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21244           UNSPEC_CRC32))]
21245   "TARGET_SSE4_2"
21246   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21247   [(set_attr "type" "sselog1")
21248    (set_attr "prefix_rep" "1")
21249    (set_attr "prefix_extra" "1")
21250    (set_attr "mode" "SI")])
21251
21252 (define_insn "sse4_2_crc32di"
21253   [(set (match_operand:DI 0 "register_operand" "=r")
21254         (unspec:DI
21255           [(match_operand:DI 1 "register_operand" "0")
21256            (match_operand:DI 2 "nonimmediate_operand" "rm")]
21257           UNSPEC_CRC32))]
21258   "TARGET_SSE4_2 && TARGET_64BIT"
21259   "crc32q\t{%2, %0|%0, %2}"
21260   [(set_attr "type" "sselog1")
21261    (set_attr "prefix_rep" "1")
21262    (set_attr "prefix_extra" "1")
21263    (set_attr "mode" "DI")])
21264
21265 (include "mmx.md")
21266 (include "sse.md")
21267 (include "sync.md")