OSDN Git Service

2008-04-07 Kenneth Zadeck <zadeck@naturalbridge.com>
[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") (umax "maxu") (umin "minu")])
552 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
553
554 ;; Mapping of parallel logic operators
555 (define_code_iterator plogic [and ior xor])
556
557 ;; Base name for insn mnemonic.
558 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
559
560 ;; All single word integer modes.
561 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
562
563 ;; Instruction suffix for integer modes.
564 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
565
566 ;; Register class for integer modes.
567 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
568
569 ;; Immediate operand constraint for integer modes.
570 (define_mode_attr i [(QI "i") (HI "i") (SI "i") (DI "e")])
571
572 ;; General operand predicate for integer modes.
573 (define_mode_attr general_operand
574         [(QI "general_operand")
575          (HI "general_operand")
576          (SI "general_operand")
577          (DI "x86_64_general_operand")])
578
579 ;; SSE and x87 SFmode and DFmode floating point modes
580 (define_mode_iterator MODEF [SF DF])
581
582 ;; All x87 floating point modes
583 (define_mode_iterator X87MODEF [SF DF XF])
584
585 ;; All integer modes handled by x87 fisttp operator.
586 (define_mode_iterator X87MODEI [HI SI DI])
587
588 ;; All integer modes handled by integer x87 operators.
589 (define_mode_iterator X87MODEI12 [HI SI])
590
591 ;; All integer modes handled by SSE cvtts?2si* operators.
592 (define_mode_iterator SSEMODEI24 [SI DI])
593
594 ;; SSE asm suffix for floating point modes
595 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
596
597 ;; SSE vector mode corresponding to a scalar mode
598 (define_mode_attr ssevecmode
599   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
600
601 ;; Instruction suffix for REX 64bit operators.
602 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
603 \f
604 ;; Scheduling descriptions
605
606 (include "pentium.md")
607 (include "ppro.md")
608 (include "k6.md")
609 (include "athlon.md")
610 (include "geode.md")
611
612 \f
613 ;; Operand and operator predicates and constraints
614
615 (include "predicates.md")
616 (include "constraints.md")
617
618 \f
619 ;; Compare instructions.
620
621 ;; All compare insns have expanders that save the operands away without
622 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
623 ;; after the cmp) will actually emit the cmpM.
624
625 (define_expand "cmpti"
626   [(set (reg:CC FLAGS_REG)
627         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
628                     (match_operand:TI 1 "x86_64_general_operand" "")))]
629   "TARGET_64BIT"
630 {
631   if (MEM_P (operands[0]) && MEM_P (operands[1]))
632     operands[0] = force_reg (TImode, operands[0]);
633   ix86_compare_op0 = operands[0];
634   ix86_compare_op1 = operands[1];
635   DONE;
636 })
637
638 (define_expand "cmpdi"
639   [(set (reg:CC FLAGS_REG)
640         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
641                     (match_operand:DI 1 "x86_64_general_operand" "")))]
642   ""
643 {
644   if (MEM_P (operands[0]) && MEM_P (operands[1]))
645     operands[0] = force_reg (DImode, operands[0]);
646   ix86_compare_op0 = operands[0];
647   ix86_compare_op1 = operands[1];
648   DONE;
649 })
650
651 (define_expand "cmpsi"
652   [(set (reg:CC FLAGS_REG)
653         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
654                     (match_operand:SI 1 "general_operand" "")))]
655   ""
656 {
657   if (MEM_P (operands[0]) && MEM_P (operands[1]))
658     operands[0] = force_reg (SImode, operands[0]);
659   ix86_compare_op0 = operands[0];
660   ix86_compare_op1 = operands[1];
661   DONE;
662 })
663
664 (define_expand "cmphi"
665   [(set (reg:CC FLAGS_REG)
666         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
667                     (match_operand:HI 1 "general_operand" "")))]
668   ""
669 {
670   if (MEM_P (operands[0]) && MEM_P (operands[1]))
671     operands[0] = force_reg (HImode, operands[0]);
672   ix86_compare_op0 = operands[0];
673   ix86_compare_op1 = operands[1];
674   DONE;
675 })
676
677 (define_expand "cmpqi"
678   [(set (reg:CC FLAGS_REG)
679         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
680                     (match_operand:QI 1 "general_operand" "")))]
681   "TARGET_QIMODE_MATH"
682 {
683   if (MEM_P (operands[0]) && MEM_P (operands[1]))
684     operands[0] = force_reg (QImode, operands[0]);
685   ix86_compare_op0 = operands[0];
686   ix86_compare_op1 = operands[1];
687   DONE;
688 })
689
690 (define_insn "cmpdi_ccno_1_rex64"
691   [(set (reg FLAGS_REG)
692         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
693                  (match_operand:DI 1 "const0_operand" "n,n")))]
694   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
695   "@
696    test{q}\t%0, %0
697    cmp{q}\t{%1, %0|%0, %1}"
698   [(set_attr "type" "test,icmp")
699    (set_attr "length_immediate" "0,1")
700    (set_attr "mode" "DI")])
701
702 (define_insn "*cmpdi_minus_1_rex64"
703   [(set (reg FLAGS_REG)
704         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
705                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
706                  (const_int 0)))]
707   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
708   "cmp{q}\t{%1, %0|%0, %1}"
709   [(set_attr "type" "icmp")
710    (set_attr "mode" "DI")])
711
712 (define_expand "cmpdi_1_rex64"
713   [(set (reg:CC FLAGS_REG)
714         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
715                     (match_operand:DI 1 "general_operand" "")))]
716   "TARGET_64BIT"
717   "")
718
719 (define_insn "cmpdi_1_insn_rex64"
720   [(set (reg FLAGS_REG)
721         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
722                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
723   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
724   "cmp{q}\t{%1, %0|%0, %1}"
725   [(set_attr "type" "icmp")
726    (set_attr "mode" "DI")])
727
728
729 (define_insn "*cmpsi_ccno_1"
730   [(set (reg FLAGS_REG)
731         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
732                  (match_operand:SI 1 "const0_operand" "n,n")))]
733   "ix86_match_ccmode (insn, CCNOmode)"
734   "@
735    test{l}\t%0, %0
736    cmp{l}\t{%1, %0|%0, %1}"
737   [(set_attr "type" "test,icmp")
738    (set_attr "length_immediate" "0,1")
739    (set_attr "mode" "SI")])
740
741 (define_insn "*cmpsi_minus_1"
742   [(set (reg FLAGS_REG)
743         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
744                            (match_operand:SI 1 "general_operand" "ri,mr"))
745                  (const_int 0)))]
746   "ix86_match_ccmode (insn, CCGOCmode)"
747   "cmp{l}\t{%1, %0|%0, %1}"
748   [(set_attr "type" "icmp")
749    (set_attr "mode" "SI")])
750
751 (define_expand "cmpsi_1"
752   [(set (reg:CC FLAGS_REG)
753         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
754                     (match_operand:SI 1 "general_operand" "")))]
755   ""
756   "")
757
758 (define_insn "*cmpsi_1_insn"
759   [(set (reg FLAGS_REG)
760         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
761                  (match_operand:SI 1 "general_operand" "ri,mr")))]
762   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
763     && ix86_match_ccmode (insn, CCmode)"
764   "cmp{l}\t{%1, %0|%0, %1}"
765   [(set_attr "type" "icmp")
766    (set_attr "mode" "SI")])
767
768 (define_insn "*cmphi_ccno_1"
769   [(set (reg FLAGS_REG)
770         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
771                  (match_operand:HI 1 "const0_operand" "n,n")))]
772   "ix86_match_ccmode (insn, CCNOmode)"
773   "@
774    test{w}\t%0, %0
775    cmp{w}\t{%1, %0|%0, %1}"
776   [(set_attr "type" "test,icmp")
777    (set_attr "length_immediate" "0,1")
778    (set_attr "mode" "HI")])
779
780 (define_insn "*cmphi_minus_1"
781   [(set (reg FLAGS_REG)
782         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
783                            (match_operand:HI 1 "general_operand" "ri,mr"))
784                  (const_int 0)))]
785   "ix86_match_ccmode (insn, CCGOCmode)"
786   "cmp{w}\t{%1, %0|%0, %1}"
787   [(set_attr "type" "icmp")
788    (set_attr "mode" "HI")])
789
790 (define_insn "*cmphi_1"
791   [(set (reg FLAGS_REG)
792         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
793                  (match_operand:HI 1 "general_operand" "ri,mr")))]
794   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
795    && ix86_match_ccmode (insn, CCmode)"
796   "cmp{w}\t{%1, %0|%0, %1}"
797   [(set_attr "type" "icmp")
798    (set_attr "mode" "HI")])
799
800 (define_insn "*cmpqi_ccno_1"
801   [(set (reg FLAGS_REG)
802         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
803                  (match_operand:QI 1 "const0_operand" "n,n")))]
804   "ix86_match_ccmode (insn, CCNOmode)"
805   "@
806    test{b}\t%0, %0
807    cmp{b}\t{$0, %0|%0, 0}"
808   [(set_attr "type" "test,icmp")
809    (set_attr "length_immediate" "0,1")
810    (set_attr "mode" "QI")])
811
812 (define_insn "*cmpqi_1"
813   [(set (reg FLAGS_REG)
814         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
815                  (match_operand:QI 1 "general_operand" "qi,mq")))]
816   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
817     && ix86_match_ccmode (insn, CCmode)"
818   "cmp{b}\t{%1, %0|%0, %1}"
819   [(set_attr "type" "icmp")
820    (set_attr "mode" "QI")])
821
822 (define_insn "*cmpqi_minus_1"
823   [(set (reg FLAGS_REG)
824         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
825                            (match_operand:QI 1 "general_operand" "qi,mq"))
826                  (const_int 0)))]
827   "ix86_match_ccmode (insn, CCGOCmode)"
828   "cmp{b}\t{%1, %0|%0, %1}"
829   [(set_attr "type" "icmp")
830    (set_attr "mode" "QI")])
831
832 (define_insn "*cmpqi_ext_1"
833   [(set (reg FLAGS_REG)
834         (compare
835           (match_operand:QI 0 "general_operand" "Qm")
836           (subreg:QI
837             (zero_extract:SI
838               (match_operand 1 "ext_register_operand" "Q")
839               (const_int 8)
840               (const_int 8)) 0)))]
841   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
842   "cmp{b}\t{%h1, %0|%0, %h1}"
843   [(set_attr "type" "icmp")
844    (set_attr "mode" "QI")])
845
846 (define_insn "*cmpqi_ext_1_rex64"
847   [(set (reg FLAGS_REG)
848         (compare
849           (match_operand:QI 0 "register_operand" "Q")
850           (subreg:QI
851             (zero_extract:SI
852               (match_operand 1 "ext_register_operand" "Q")
853               (const_int 8)
854               (const_int 8)) 0)))]
855   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
856   "cmp{b}\t{%h1, %0|%0, %h1}"
857   [(set_attr "type" "icmp")
858    (set_attr "mode" "QI")])
859
860 (define_insn "*cmpqi_ext_2"
861   [(set (reg FLAGS_REG)
862         (compare
863           (subreg:QI
864             (zero_extract:SI
865               (match_operand 0 "ext_register_operand" "Q")
866               (const_int 8)
867               (const_int 8)) 0)
868           (match_operand:QI 1 "const0_operand" "n")))]
869   "ix86_match_ccmode (insn, CCNOmode)"
870   "test{b}\t%h0, %h0"
871   [(set_attr "type" "test")
872    (set_attr "length_immediate" "0")
873    (set_attr "mode" "QI")])
874
875 (define_expand "cmpqi_ext_3"
876   [(set (reg:CC FLAGS_REG)
877         (compare:CC
878           (subreg:QI
879             (zero_extract:SI
880               (match_operand 0 "ext_register_operand" "")
881               (const_int 8)
882               (const_int 8)) 0)
883           (match_operand:QI 1 "general_operand" "")))]
884   ""
885   "")
886
887 (define_insn "cmpqi_ext_3_insn"
888   [(set (reg FLAGS_REG)
889         (compare
890           (subreg:QI
891             (zero_extract:SI
892               (match_operand 0 "ext_register_operand" "Q")
893               (const_int 8)
894               (const_int 8)) 0)
895           (match_operand:QI 1 "general_operand" "Qmn")))]
896   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
897   "cmp{b}\t{%1, %h0|%h0, %1}"
898   [(set_attr "type" "icmp")
899    (set_attr "mode" "QI")])
900
901 (define_insn "cmpqi_ext_3_insn_rex64"
902   [(set (reg FLAGS_REG)
903         (compare
904           (subreg:QI
905             (zero_extract:SI
906               (match_operand 0 "ext_register_operand" "Q")
907               (const_int 8)
908               (const_int 8)) 0)
909           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
910   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
911   "cmp{b}\t{%1, %h0|%h0, %1}"
912   [(set_attr "type" "icmp")
913    (set_attr "mode" "QI")])
914
915 (define_insn "*cmpqi_ext_4"
916   [(set (reg FLAGS_REG)
917         (compare
918           (subreg:QI
919             (zero_extract:SI
920               (match_operand 0 "ext_register_operand" "Q")
921               (const_int 8)
922               (const_int 8)) 0)
923           (subreg:QI
924             (zero_extract:SI
925               (match_operand 1 "ext_register_operand" "Q")
926               (const_int 8)
927               (const_int 8)) 0)))]
928   "ix86_match_ccmode (insn, CCmode)"
929   "cmp{b}\t{%h1, %h0|%h0, %h1}"
930   [(set_attr "type" "icmp")
931    (set_attr "mode" "QI")])
932
933 ;; These implement float point compares.
934 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
935 ;; which would allow mix and match FP modes on the compares.  Which is what
936 ;; the old patterns did, but with many more of them.
937
938 (define_expand "cmpxf"
939   [(set (reg:CC FLAGS_REG)
940         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
941                     (match_operand:XF 1 "nonmemory_operand" "")))]
942   "TARGET_80387"
943 {
944   ix86_compare_op0 = operands[0];
945   ix86_compare_op1 = operands[1];
946   DONE;
947 })
948
949 (define_expand "cmp<mode>"
950   [(set (reg:CC FLAGS_REG)
951         (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
952                     (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
953   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
954 {
955   ix86_compare_op0 = operands[0];
956   ix86_compare_op1 = operands[1];
957   DONE;
958 })
959
960 ;; FP compares, step 1:
961 ;; Set the FP condition codes.
962 ;;
963 ;; CCFPmode     compare with exceptions
964 ;; CCFPUmode    compare with no exceptions
965
966 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
967 ;; used to manage the reg stack popping would not be preserved.
968
969 (define_insn "*cmpfp_0"
970   [(set (match_operand:HI 0 "register_operand" "=a")
971         (unspec:HI
972           [(compare:CCFP
973              (match_operand 1 "register_operand" "f")
974              (match_operand 2 "const0_operand" "X"))]
975         UNSPEC_FNSTSW))]
976   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
977    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
978   "* return output_fp_compare (insn, operands, 0, 0);"
979   [(set_attr "type" "multi")
980    (set_attr "unit" "i387")
981    (set (attr "mode")
982      (cond [(match_operand:SF 1 "" "")
983               (const_string "SF")
984             (match_operand:DF 1 "" "")
985               (const_string "DF")
986            ]
987            (const_string "XF")))])
988
989 (define_insn_and_split "*cmpfp_0_cc"
990   [(set (reg:CCFP FLAGS_REG)
991         (compare:CCFP
992           (match_operand 1 "register_operand" "f")
993           (match_operand 2 "const0_operand" "X")))
994    (clobber (match_operand:HI 0 "register_operand" "=a"))]
995   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
996    && TARGET_SAHF && !TARGET_CMOVE
997    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
998   "#"
999   "&& reload_completed"
1000   [(set (match_dup 0)
1001         (unspec:HI
1002           [(compare:CCFP (match_dup 1)(match_dup 2))]
1003         UNSPEC_FNSTSW))
1004    (set (reg:CC FLAGS_REG)
1005         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1006   ""
1007   [(set_attr "type" "multi")
1008    (set_attr "unit" "i387")
1009    (set (attr "mode")
1010      (cond [(match_operand:SF 1 "" "")
1011               (const_string "SF")
1012             (match_operand:DF 1 "" "")
1013               (const_string "DF")
1014            ]
1015            (const_string "XF")))])
1016
1017 (define_insn "*cmpfp_xf"
1018   [(set (match_operand:HI 0 "register_operand" "=a")
1019         (unspec:HI
1020           [(compare:CCFP
1021              (match_operand:XF 1 "register_operand" "f")
1022              (match_operand:XF 2 "register_operand" "f"))]
1023           UNSPEC_FNSTSW))]
1024   "TARGET_80387"
1025   "* return output_fp_compare (insn, operands, 0, 0);"
1026   [(set_attr "type" "multi")
1027    (set_attr "unit" "i387")
1028    (set_attr "mode" "XF")])
1029
1030 (define_insn_and_split "*cmpfp_xf_cc"
1031   [(set (reg:CCFP FLAGS_REG)
1032         (compare:CCFP
1033           (match_operand:XF 1 "register_operand" "f")
1034           (match_operand:XF 2 "register_operand" "f")))
1035    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1036   "TARGET_80387
1037    && TARGET_SAHF && !TARGET_CMOVE"
1038   "#"
1039   "&& reload_completed"
1040   [(set (match_dup 0)
1041         (unspec:HI
1042           [(compare:CCFP (match_dup 1)(match_dup 2))]
1043         UNSPEC_FNSTSW))
1044    (set (reg:CC FLAGS_REG)
1045         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1046   ""
1047   [(set_attr "type" "multi")
1048    (set_attr "unit" "i387")
1049    (set_attr "mode" "XF")])
1050
1051 (define_insn "*cmpfp_<mode>"
1052   [(set (match_operand:HI 0 "register_operand" "=a")
1053         (unspec:HI
1054           [(compare:CCFP
1055              (match_operand:MODEF 1 "register_operand" "f")
1056              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1057           UNSPEC_FNSTSW))]
1058   "TARGET_80387"
1059   "* return output_fp_compare (insn, operands, 0, 0);"
1060   [(set_attr "type" "multi")
1061    (set_attr "unit" "i387")
1062    (set_attr "mode" "<MODE>")])
1063
1064 (define_insn_and_split "*cmpfp_<mode>_cc"
1065   [(set (reg:CCFP FLAGS_REG)
1066         (compare:CCFP
1067           (match_operand:MODEF 1 "register_operand" "f")
1068           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1069    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1070   "TARGET_80387
1071    && TARGET_SAHF && !TARGET_CMOVE"
1072   "#"
1073   "&& reload_completed"
1074   [(set (match_dup 0)
1075         (unspec:HI
1076           [(compare:CCFP (match_dup 1)(match_dup 2))]
1077         UNSPEC_FNSTSW))
1078    (set (reg:CC FLAGS_REG)
1079         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1080   ""
1081   [(set_attr "type" "multi")
1082    (set_attr "unit" "i387")
1083    (set_attr "mode" "<MODE>")])
1084
1085 (define_insn "*cmpfp_u"
1086   [(set (match_operand:HI 0 "register_operand" "=a")
1087         (unspec:HI
1088           [(compare:CCFPU
1089              (match_operand 1 "register_operand" "f")
1090              (match_operand 2 "register_operand" "f"))]
1091           UNSPEC_FNSTSW))]
1092   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1093    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1094   "* return output_fp_compare (insn, operands, 0, 1);"
1095   [(set_attr "type" "multi")
1096    (set_attr "unit" "i387")
1097    (set (attr "mode")
1098      (cond [(match_operand:SF 1 "" "")
1099               (const_string "SF")
1100             (match_operand:DF 1 "" "")
1101               (const_string "DF")
1102            ]
1103            (const_string "XF")))])
1104
1105 (define_insn_and_split "*cmpfp_u_cc"
1106   [(set (reg:CCFPU FLAGS_REG)
1107         (compare:CCFPU
1108           (match_operand 1 "register_operand" "f")
1109           (match_operand 2 "register_operand" "f")))
1110    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1111   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1112    && TARGET_SAHF && !TARGET_CMOVE
1113    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1114   "#"
1115   "&& reload_completed"
1116   [(set (match_dup 0)
1117         (unspec:HI
1118           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1119         UNSPEC_FNSTSW))
1120    (set (reg:CC FLAGS_REG)
1121         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1122   ""
1123   [(set_attr "type" "multi")
1124    (set_attr "unit" "i387")
1125    (set (attr "mode")
1126      (cond [(match_operand:SF 1 "" "")
1127               (const_string "SF")
1128             (match_operand:DF 1 "" "")
1129               (const_string "DF")
1130            ]
1131            (const_string "XF")))])
1132
1133 (define_insn "*cmpfp_<mode>"
1134   [(set (match_operand:HI 0 "register_operand" "=a")
1135         (unspec:HI
1136           [(compare:CCFP
1137              (match_operand 1 "register_operand" "f")
1138              (match_operator 3 "float_operator"
1139                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1140           UNSPEC_FNSTSW))]
1141   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1142    && TARGET_USE_<MODE>MODE_FIOP
1143    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1144   "* return output_fp_compare (insn, operands, 0, 0);"
1145   [(set_attr "type" "multi")
1146    (set_attr "unit" "i387")
1147    (set_attr "fp_int_src" "true")
1148    (set_attr "mode" "<MODE>")])
1149
1150 (define_insn_and_split "*cmpfp_<mode>_cc"
1151   [(set (reg:CCFP FLAGS_REG)
1152         (compare:CCFP
1153           (match_operand 1 "register_operand" "f")
1154           (match_operator 3 "float_operator"
1155             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1156    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1157   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1158    && TARGET_SAHF && !TARGET_CMOVE
1159    && TARGET_USE_<MODE>MODE_FIOP
1160    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1161   "#"
1162   "&& reload_completed"
1163   [(set (match_dup 0)
1164         (unspec:HI
1165           [(compare:CCFP
1166              (match_dup 1)
1167              (match_op_dup 3 [(match_dup 2)]))]
1168         UNSPEC_FNSTSW))
1169    (set (reg:CC FLAGS_REG)
1170         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1171   ""
1172   [(set_attr "type" "multi")
1173    (set_attr "unit" "i387")
1174    (set_attr "fp_int_src" "true")
1175    (set_attr "mode" "<MODE>")])
1176
1177 ;; FP compares, step 2
1178 ;; Move the fpsw to ax.
1179
1180 (define_insn "x86_fnstsw_1"
1181   [(set (match_operand:HI 0 "register_operand" "=a")
1182         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1183   "TARGET_80387"
1184   "fnstsw\t%0"
1185   [(set_attr "length" "2")
1186    (set_attr "mode" "SI")
1187    (set_attr "unit" "i387")])
1188
1189 ;; FP compares, step 3
1190 ;; Get ax into flags, general case.
1191
1192 (define_insn "x86_sahf_1"
1193   [(set (reg:CC FLAGS_REG)
1194         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1195                    UNSPEC_SAHF))]
1196   "TARGET_SAHF"
1197 {
1198 #ifdef HAVE_AS_IX86_SAHF
1199   return "sahf";
1200 #else
1201   return ".byte\t0x9e";
1202 #endif
1203 }
1204   [(set_attr "length" "1")
1205    (set_attr "athlon_decode" "vector")
1206    (set_attr "amdfam10_decode" "direct")
1207    (set_attr "mode" "SI")])
1208
1209 ;; Pentium Pro can do steps 1 through 3 in one go.
1210 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1211 (define_insn "*cmpfp_i_mixed"
1212   [(set (reg:CCFP FLAGS_REG)
1213         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1214                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1215   "TARGET_MIX_SSE_I387
1216    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1217    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1218   "* return output_fp_compare (insn, operands, 1, 0);"
1219   [(set_attr "type" "fcmp,ssecomi")
1220    (set (attr "mode")
1221      (if_then_else (match_operand:SF 1 "" "")
1222         (const_string "SF")
1223         (const_string "DF")))
1224    (set_attr "athlon_decode" "vector")
1225    (set_attr "amdfam10_decode" "direct")])
1226
1227 (define_insn "*cmpfp_i_sse"
1228   [(set (reg:CCFP FLAGS_REG)
1229         (compare:CCFP (match_operand 0 "register_operand" "x")
1230                       (match_operand 1 "nonimmediate_operand" "xm")))]
1231   "TARGET_SSE_MATH
1232    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1233    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1234   "* return output_fp_compare (insn, operands, 1, 0);"
1235   [(set_attr "type" "ssecomi")
1236    (set (attr "mode")
1237      (if_then_else (match_operand:SF 1 "" "")
1238         (const_string "SF")
1239         (const_string "DF")))
1240    (set_attr "athlon_decode" "vector")
1241    (set_attr "amdfam10_decode" "direct")])
1242
1243 (define_insn "*cmpfp_i_i387"
1244   [(set (reg:CCFP FLAGS_REG)
1245         (compare:CCFP (match_operand 0 "register_operand" "f")
1246                       (match_operand 1 "register_operand" "f")))]
1247   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1248    && TARGET_CMOVE
1249    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1250    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1251   "* return output_fp_compare (insn, operands, 1, 0);"
1252   [(set_attr "type" "fcmp")
1253    (set (attr "mode")
1254      (cond [(match_operand:SF 1 "" "")
1255               (const_string "SF")
1256             (match_operand:DF 1 "" "")
1257               (const_string "DF")
1258            ]
1259            (const_string "XF")))
1260    (set_attr "athlon_decode" "vector")
1261    (set_attr "amdfam10_decode" "direct")])
1262
1263 (define_insn "*cmpfp_iu_mixed"
1264   [(set (reg:CCFPU FLAGS_REG)
1265         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1266                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1267   "TARGET_MIX_SSE_I387
1268    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1269    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1270   "* return output_fp_compare (insn, operands, 1, 1);"
1271   [(set_attr "type" "fcmp,ssecomi")
1272    (set (attr "mode")
1273      (if_then_else (match_operand:SF 1 "" "")
1274         (const_string "SF")
1275         (const_string "DF")))
1276    (set_attr "athlon_decode" "vector")
1277    (set_attr "amdfam10_decode" "direct")])
1278
1279 (define_insn "*cmpfp_iu_sse"
1280   [(set (reg:CCFPU FLAGS_REG)
1281         (compare:CCFPU (match_operand 0 "register_operand" "x")
1282                        (match_operand 1 "nonimmediate_operand" "xm")))]
1283   "TARGET_SSE_MATH
1284    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1285    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1286   "* return output_fp_compare (insn, operands, 1, 1);"
1287   [(set_attr "type" "ssecomi")
1288    (set (attr "mode")
1289      (if_then_else (match_operand:SF 1 "" "")
1290         (const_string "SF")
1291         (const_string "DF")))
1292    (set_attr "athlon_decode" "vector")
1293    (set_attr "amdfam10_decode" "direct")])
1294
1295 (define_insn "*cmpfp_iu_387"
1296   [(set (reg:CCFPU FLAGS_REG)
1297         (compare:CCFPU (match_operand 0 "register_operand" "f")
1298                        (match_operand 1 "register_operand" "f")))]
1299   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1300    && TARGET_CMOVE
1301    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1302    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1303   "* return output_fp_compare (insn, operands, 1, 1);"
1304   [(set_attr "type" "fcmp")
1305    (set (attr "mode")
1306      (cond [(match_operand:SF 1 "" "")
1307               (const_string "SF")
1308             (match_operand:DF 1 "" "")
1309               (const_string "DF")
1310            ]
1311            (const_string "XF")))
1312    (set_attr "athlon_decode" "vector")
1313    (set_attr "amdfam10_decode" "direct")])
1314 \f
1315 ;; Move instructions.
1316
1317 ;; General case of fullword move.
1318
1319 (define_expand "movsi"
1320   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1321         (match_operand:SI 1 "general_operand" ""))]
1322   ""
1323   "ix86_expand_move (SImode, operands); DONE;")
1324
1325 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1326 ;; general_operand.
1327 ;;
1328 ;; %%% We don't use a post-inc memory reference because x86 is not a
1329 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1330 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1331 ;; targets without our curiosities, and it is just as easy to represent
1332 ;; this differently.
1333
1334 (define_insn "*pushsi2"
1335   [(set (match_operand:SI 0 "push_operand" "=<")
1336         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1337   "!TARGET_64BIT"
1338   "push{l}\t%1"
1339   [(set_attr "type" "push")
1340    (set_attr "mode" "SI")])
1341
1342 ;; For 64BIT abi we always round up to 8 bytes.
1343 (define_insn "*pushsi2_rex64"
1344   [(set (match_operand:SI 0 "push_operand" "=X")
1345         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1346   "TARGET_64BIT"
1347   "push{q}\t%q1"
1348   [(set_attr "type" "push")
1349    (set_attr "mode" "SI")])
1350
1351 (define_insn "*pushsi2_prologue"
1352   [(set (match_operand:SI 0 "push_operand" "=<")
1353         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1354    (clobber (mem:BLK (scratch)))]
1355   "!TARGET_64BIT"
1356   "push{l}\t%1"
1357   [(set_attr "type" "push")
1358    (set_attr "mode" "SI")])
1359
1360 (define_insn "*popsi1_epilogue"
1361   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1362         (mem:SI (reg:SI SP_REG)))
1363    (set (reg:SI SP_REG)
1364         (plus:SI (reg:SI SP_REG) (const_int 4)))
1365    (clobber (mem:BLK (scratch)))]
1366   "!TARGET_64BIT"
1367   "pop{l}\t%0"
1368   [(set_attr "type" "pop")
1369    (set_attr "mode" "SI")])
1370
1371 (define_insn "popsi1"
1372   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1373         (mem:SI (reg:SI SP_REG)))
1374    (set (reg:SI SP_REG)
1375         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1376   "!TARGET_64BIT"
1377   "pop{l}\t%0"
1378   [(set_attr "type" "pop")
1379    (set_attr "mode" "SI")])
1380
1381 (define_insn "*movsi_xor"
1382   [(set (match_operand:SI 0 "register_operand" "=r")
1383         (match_operand:SI 1 "const0_operand" "i"))
1384    (clobber (reg:CC FLAGS_REG))]
1385   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1386   "xor{l}\t%0, %0"
1387   [(set_attr "type" "alu1")
1388    (set_attr "mode" "SI")
1389    (set_attr "length_immediate" "0")])
1390
1391 (define_insn "*movsi_or"
1392   [(set (match_operand:SI 0 "register_operand" "=r")
1393         (match_operand:SI 1 "immediate_operand" "i"))
1394    (clobber (reg:CC FLAGS_REG))]
1395   "reload_completed
1396    && operands[1] == constm1_rtx
1397    && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1398 {
1399   operands[1] = constm1_rtx;
1400   return "or{l}\t{%1, %0|%0, %1}";
1401 }
1402   [(set_attr "type" "alu1")
1403    (set_attr "mode" "SI")
1404    (set_attr "length_immediate" "1")])
1405
1406 (define_insn "*movsi_1"
1407   [(set (match_operand:SI 0 "nonimmediate_operand"
1408                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1409         (match_operand:SI 1 "general_operand"
1410                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1411   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1412 {
1413   switch (get_attr_type (insn))
1414     {
1415     case TYPE_SSELOG1:
1416       if (get_attr_mode (insn) == MODE_TI)
1417         return "pxor\t%0, %0";
1418       return "xorps\t%0, %0";
1419
1420     case TYPE_SSEMOV:
1421       switch (get_attr_mode (insn))
1422         {
1423         case MODE_TI:
1424           return "movdqa\t{%1, %0|%0, %1}";
1425         case MODE_V4SF:
1426           return "movaps\t{%1, %0|%0, %1}";
1427         case MODE_SI:
1428           return "movd\t{%1, %0|%0, %1}";
1429         case MODE_SF:
1430           return "movss\t{%1, %0|%0, %1}";
1431         default:
1432           gcc_unreachable ();
1433         }
1434
1435     case TYPE_MMXADD:
1436       return "pxor\t%0, %0";
1437
1438     case TYPE_MMXMOV:
1439       if (get_attr_mode (insn) == MODE_DI)
1440         return "movq\t{%1, %0|%0, %1}";
1441       return "movd\t{%1, %0|%0, %1}";
1442
1443     case TYPE_LEA:
1444       return "lea{l}\t{%1, %0|%0, %1}";
1445
1446     default:
1447       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1448       return "mov{l}\t{%1, %0|%0, %1}";
1449     }
1450 }
1451   [(set (attr "type")
1452      (cond [(eq_attr "alternative" "2")
1453               (const_string "mmxadd")
1454             (eq_attr "alternative" "3,4,5")
1455               (const_string "mmxmov")
1456             (eq_attr "alternative" "6")
1457               (const_string "sselog1")
1458             (eq_attr "alternative" "7,8,9,10,11")
1459               (const_string "ssemov")
1460             (match_operand:DI 1 "pic_32bit_operand" "")
1461               (const_string "lea")
1462            ]
1463            (const_string "imov")))
1464    (set (attr "mode")
1465      (cond [(eq_attr "alternative" "2,3")
1466               (const_string "DI")
1467             (eq_attr "alternative" "6,7")
1468               (if_then_else
1469                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1470                 (const_string "V4SF")
1471                 (const_string "TI"))
1472             (and (eq_attr "alternative" "8,9,10,11")
1473                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1474               (const_string "SF")
1475            ]
1476            (const_string "SI")))])
1477
1478 ;; Stores and loads of ax to arbitrary constant address.
1479 ;; We fake an second form of instruction to force reload to load address
1480 ;; into register when rax is not available
1481 (define_insn "*movabssi_1_rex64"
1482   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1483         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1484   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1485   "@
1486    movabs{l}\t{%1, %P0|%P0, %1}
1487    mov{l}\t{%1, %a0|%a0, %1}"
1488   [(set_attr "type" "imov")
1489    (set_attr "modrm" "0,*")
1490    (set_attr "length_address" "8,0")
1491    (set_attr "length_immediate" "0,*")
1492    (set_attr "memory" "store")
1493    (set_attr "mode" "SI")])
1494
1495 (define_insn "*movabssi_2_rex64"
1496   [(set (match_operand:SI 0 "register_operand" "=a,r")
1497         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1498   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1499   "@
1500    movabs{l}\t{%P1, %0|%0, %P1}
1501    mov{l}\t{%a1, %0|%0, %a1}"
1502   [(set_attr "type" "imov")
1503    (set_attr "modrm" "0,*")
1504    (set_attr "length_address" "8,0")
1505    (set_attr "length_immediate" "0")
1506    (set_attr "memory" "load")
1507    (set_attr "mode" "SI")])
1508
1509 (define_insn "*swapsi"
1510   [(set (match_operand:SI 0 "register_operand" "+r")
1511         (match_operand:SI 1 "register_operand" "+r"))
1512    (set (match_dup 1)
1513         (match_dup 0))]
1514   ""
1515   "xchg{l}\t%1, %0"
1516   [(set_attr "type" "imov")
1517    (set_attr "mode" "SI")
1518    (set_attr "pent_pair" "np")
1519    (set_attr "athlon_decode" "vector")
1520    (set_attr "amdfam10_decode" "double")])
1521
1522 (define_expand "movhi"
1523   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1524         (match_operand:HI 1 "general_operand" ""))]
1525   ""
1526   "ix86_expand_move (HImode, operands); DONE;")
1527
1528 (define_insn "*pushhi2"
1529   [(set (match_operand:HI 0 "push_operand" "=X")
1530         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1531   "!TARGET_64BIT"
1532   "push{l}\t%k1"
1533   [(set_attr "type" "push")
1534    (set_attr "mode" "SI")])
1535
1536 ;; For 64BIT abi we always round up to 8 bytes.
1537 (define_insn "*pushhi2_rex64"
1538   [(set (match_operand:HI 0 "push_operand" "=X")
1539         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1540   "TARGET_64BIT"
1541   "push{q}\t%q1"
1542   [(set_attr "type" "push")
1543    (set_attr "mode" "DI")])
1544
1545 (define_insn "*movhi_1"
1546   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1547         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1548   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1549 {
1550   switch (get_attr_type (insn))
1551     {
1552     case TYPE_IMOVX:
1553       /* movzwl is faster than movw on p2 due to partial word stalls,
1554          though not as fast as an aligned movl.  */
1555       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1556     default:
1557       if (get_attr_mode (insn) == MODE_SI)
1558         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1559       else
1560         return "mov{w}\t{%1, %0|%0, %1}";
1561     }
1562 }
1563   [(set (attr "type")
1564      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1565               (const_string "imov")
1566             (and (eq_attr "alternative" "0")
1567                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1568                           (const_int 0))
1569                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1570                           (const_int 0))))
1571               (const_string "imov")
1572             (and (eq_attr "alternative" "1,2")
1573                  (match_operand:HI 1 "aligned_operand" ""))
1574               (const_string "imov")
1575             (and (ne (symbol_ref "TARGET_MOVX")
1576                      (const_int 0))
1577                  (eq_attr "alternative" "0,2"))
1578               (const_string "imovx")
1579            ]
1580            (const_string "imov")))
1581     (set (attr "mode")
1582       (cond [(eq_attr "type" "imovx")
1583                (const_string "SI")
1584              (and (eq_attr "alternative" "1,2")
1585                   (match_operand:HI 1 "aligned_operand" ""))
1586                (const_string "SI")
1587              (and (eq_attr "alternative" "0")
1588                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1589                            (const_int 0))
1590                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1591                            (const_int 0))))
1592                (const_string "SI")
1593             ]
1594             (const_string "HI")))])
1595
1596 ;; Stores and loads of ax to arbitrary constant address.
1597 ;; We fake an second form of instruction to force reload to load address
1598 ;; into register when rax is not available
1599 (define_insn "*movabshi_1_rex64"
1600   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1601         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1602   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1603   "@
1604    movabs{w}\t{%1, %P0|%P0, %1}
1605    mov{w}\t{%1, %a0|%a0, %1}"
1606   [(set_attr "type" "imov")
1607    (set_attr "modrm" "0,*")
1608    (set_attr "length_address" "8,0")
1609    (set_attr "length_immediate" "0,*")
1610    (set_attr "memory" "store")
1611    (set_attr "mode" "HI")])
1612
1613 (define_insn "*movabshi_2_rex64"
1614   [(set (match_operand:HI 0 "register_operand" "=a,r")
1615         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1616   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1617   "@
1618    movabs{w}\t{%P1, %0|%0, %P1}
1619    mov{w}\t{%a1, %0|%0, %a1}"
1620   [(set_attr "type" "imov")
1621    (set_attr "modrm" "0,*")
1622    (set_attr "length_address" "8,0")
1623    (set_attr "length_immediate" "0")
1624    (set_attr "memory" "load")
1625    (set_attr "mode" "HI")])
1626
1627 (define_insn "*swaphi_1"
1628   [(set (match_operand:HI 0 "register_operand" "+r")
1629         (match_operand:HI 1 "register_operand" "+r"))
1630    (set (match_dup 1)
1631         (match_dup 0))]
1632   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1633   "xchg{l}\t%k1, %k0"
1634   [(set_attr "type" "imov")
1635    (set_attr "mode" "SI")
1636    (set_attr "pent_pair" "np")
1637    (set_attr "athlon_decode" "vector")
1638    (set_attr "amdfam10_decode" "double")])
1639
1640 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1641 (define_insn "*swaphi_2"
1642   [(set (match_operand:HI 0 "register_operand" "+r")
1643         (match_operand:HI 1 "register_operand" "+r"))
1644    (set (match_dup 1)
1645         (match_dup 0))]
1646   "TARGET_PARTIAL_REG_STALL"
1647   "xchg{w}\t%1, %0"
1648   [(set_attr "type" "imov")
1649    (set_attr "mode" "HI")
1650    (set_attr "pent_pair" "np")
1651    (set_attr "athlon_decode" "vector")])
1652
1653 (define_expand "movstricthi"
1654   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1655         (match_operand:HI 1 "general_operand" ""))]
1656   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1657 {
1658   /* Don't generate memory->memory moves, go through a register */
1659   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1660     operands[1] = force_reg (HImode, operands[1]);
1661 })
1662
1663 (define_insn "*movstricthi_1"
1664   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1665         (match_operand:HI 1 "general_operand" "rn,m"))]
1666   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1667    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1668   "mov{w}\t{%1, %0|%0, %1}"
1669   [(set_attr "type" "imov")
1670    (set_attr "mode" "HI")])
1671
1672 (define_insn "*movstricthi_xor"
1673   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1674         (match_operand:HI 1 "const0_operand" "i"))
1675    (clobber (reg:CC FLAGS_REG))]
1676   "reload_completed
1677    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1678   "xor{w}\t%0, %0"
1679   [(set_attr "type" "alu1")
1680    (set_attr "mode" "HI")
1681    (set_attr "length_immediate" "0")])
1682
1683 (define_expand "movqi"
1684   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1685         (match_operand:QI 1 "general_operand" ""))]
1686   ""
1687   "ix86_expand_move (QImode, operands); DONE;")
1688
1689 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1690 ;; "push a byte".  But actually we use pushl, which has the effect
1691 ;; of rounding the amount pushed up to a word.
1692
1693 (define_insn "*pushqi2"
1694   [(set (match_operand:QI 0 "push_operand" "=X")
1695         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1696   "!TARGET_64BIT"
1697   "push{l}\t%k1"
1698   [(set_attr "type" "push")
1699    (set_attr "mode" "SI")])
1700
1701 ;; For 64BIT abi we always round up to 8 bytes.
1702 (define_insn "*pushqi2_rex64"
1703   [(set (match_operand:QI 0 "push_operand" "=X")
1704         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1705   "TARGET_64BIT"
1706   "push{q}\t%q1"
1707   [(set_attr "type" "push")
1708    (set_attr "mode" "DI")])
1709
1710 ;; Situation is quite tricky about when to choose full sized (SImode) move
1711 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1712 ;; partial register dependency machines (such as AMD Athlon), where QImode
1713 ;; moves issue extra dependency and for partial register stalls machines
1714 ;; that don't use QImode patterns (and QImode move cause stall on the next
1715 ;; instruction).
1716 ;;
1717 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1718 ;; register stall machines with, where we use QImode instructions, since
1719 ;; partial register stall can be caused there.  Then we use movzx.
1720 (define_insn "*movqi_1"
1721   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1722         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1723   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1724 {
1725   switch (get_attr_type (insn))
1726     {
1727     case TYPE_IMOVX:
1728       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1729       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1730     default:
1731       if (get_attr_mode (insn) == MODE_SI)
1732         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1733       else
1734         return "mov{b}\t{%1, %0|%0, %1}";
1735     }
1736 }
1737   [(set (attr "type")
1738      (cond [(and (eq_attr "alternative" "5")
1739                  (not (match_operand:QI 1 "aligned_operand" "")))
1740               (const_string "imovx")
1741             (ne (symbol_ref "optimize_size") (const_int 0))
1742               (const_string "imov")
1743             (and (eq_attr "alternative" "3")
1744                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1745                           (const_int 0))
1746                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1747                           (const_int 0))))
1748               (const_string "imov")
1749             (eq_attr "alternative" "3,5")
1750               (const_string "imovx")
1751             (and (ne (symbol_ref "TARGET_MOVX")
1752                      (const_int 0))
1753                  (eq_attr "alternative" "2"))
1754               (const_string "imovx")
1755            ]
1756            (const_string "imov")))
1757    (set (attr "mode")
1758       (cond [(eq_attr "alternative" "3,4,5")
1759                (const_string "SI")
1760              (eq_attr "alternative" "6")
1761                (const_string "QI")
1762              (eq_attr "type" "imovx")
1763                (const_string "SI")
1764              (and (eq_attr "type" "imov")
1765                   (and (eq_attr "alternative" "0,1")
1766                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1767                                 (const_int 0))
1768                             (and (eq (symbol_ref "optimize_size")
1769                                      (const_int 0))
1770                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1771                                      (const_int 0))))))
1772                (const_string "SI")
1773              ;; Avoid partial register stalls when not using QImode arithmetic
1774              (and (eq_attr "type" "imov")
1775                   (and (eq_attr "alternative" "0,1")
1776                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1777                                 (const_int 0))
1778                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1779                                 (const_int 0)))))
1780                (const_string "SI")
1781            ]
1782            (const_string "QI")))])
1783
1784 (define_expand "reload_outqi"
1785   [(parallel [(match_operand:QI 0 "" "=m")
1786               (match_operand:QI 1 "register_operand" "r")
1787               (match_operand:QI 2 "register_operand" "=&q")])]
1788   ""
1789 {
1790   rtx op0, op1, op2;
1791   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1792
1793   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1794   if (! q_regs_operand (op1, QImode))
1795     {
1796       emit_insn (gen_movqi (op2, op1));
1797       op1 = op2;
1798     }
1799   emit_insn (gen_movqi (op0, op1));
1800   DONE;
1801 })
1802
1803 (define_insn "*swapqi_1"
1804   [(set (match_operand:QI 0 "register_operand" "+r")
1805         (match_operand:QI 1 "register_operand" "+r"))
1806    (set (match_dup 1)
1807         (match_dup 0))]
1808   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1809   "xchg{l}\t%k1, %k0"
1810   [(set_attr "type" "imov")
1811    (set_attr "mode" "SI")
1812    (set_attr "pent_pair" "np")
1813    (set_attr "athlon_decode" "vector")
1814    (set_attr "amdfam10_decode" "vector")])
1815
1816 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1817 (define_insn "*swapqi_2"
1818   [(set (match_operand:QI 0 "register_operand" "+q")
1819         (match_operand:QI 1 "register_operand" "+q"))
1820    (set (match_dup 1)
1821         (match_dup 0))]
1822   "TARGET_PARTIAL_REG_STALL"
1823   "xchg{b}\t%1, %0"
1824   [(set_attr "type" "imov")
1825    (set_attr "mode" "QI")
1826    (set_attr "pent_pair" "np")
1827    (set_attr "athlon_decode" "vector")])
1828
1829 (define_expand "movstrictqi"
1830   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1831         (match_operand:QI 1 "general_operand" ""))]
1832   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1833 {
1834   /* Don't generate memory->memory moves, go through a register.  */
1835   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1836     operands[1] = force_reg (QImode, operands[1]);
1837 })
1838
1839 (define_insn "*movstrictqi_1"
1840   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1841         (match_operand:QI 1 "general_operand" "*qn,m"))]
1842   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1843    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1844   "mov{b}\t{%1, %0|%0, %1}"
1845   [(set_attr "type" "imov")
1846    (set_attr "mode" "QI")])
1847
1848 (define_insn "*movstrictqi_xor"
1849   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1850         (match_operand:QI 1 "const0_operand" "i"))
1851    (clobber (reg:CC FLAGS_REG))]
1852   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1853   "xor{b}\t%0, %0"
1854   [(set_attr "type" "alu1")
1855    (set_attr "mode" "QI")
1856    (set_attr "length_immediate" "0")])
1857
1858 (define_insn "*movsi_extv_1"
1859   [(set (match_operand:SI 0 "register_operand" "=R")
1860         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1861                          (const_int 8)
1862                          (const_int 8)))]
1863   ""
1864   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1865   [(set_attr "type" "imovx")
1866    (set_attr "mode" "SI")])
1867
1868 (define_insn "*movhi_extv_1"
1869   [(set (match_operand:HI 0 "register_operand" "=R")
1870         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1871                          (const_int 8)
1872                          (const_int 8)))]
1873   ""
1874   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1875   [(set_attr "type" "imovx")
1876    (set_attr "mode" "SI")])
1877
1878 (define_insn "*movqi_extv_1"
1879   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1880         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1881                          (const_int 8)
1882                          (const_int 8)))]
1883   "!TARGET_64BIT"
1884 {
1885   switch (get_attr_type (insn))
1886     {
1887     case TYPE_IMOVX:
1888       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1889     default:
1890       return "mov{b}\t{%h1, %0|%0, %h1}";
1891     }
1892 }
1893   [(set (attr "type")
1894      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1895                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1896                              (ne (symbol_ref "TARGET_MOVX")
1897                                  (const_int 0))))
1898         (const_string "imovx")
1899         (const_string "imov")))
1900    (set (attr "mode")
1901      (if_then_else (eq_attr "type" "imovx")
1902         (const_string "SI")
1903         (const_string "QI")))])
1904
1905 (define_insn "*movqi_extv_1_rex64"
1906   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1907         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1908                          (const_int 8)
1909                          (const_int 8)))]
1910   "TARGET_64BIT"
1911 {
1912   switch (get_attr_type (insn))
1913     {
1914     case TYPE_IMOVX:
1915       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1916     default:
1917       return "mov{b}\t{%h1, %0|%0, %h1}";
1918     }
1919 }
1920   [(set (attr "type")
1921      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1922                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1923                              (ne (symbol_ref "TARGET_MOVX")
1924                                  (const_int 0))))
1925         (const_string "imovx")
1926         (const_string "imov")))
1927    (set (attr "mode")
1928      (if_then_else (eq_attr "type" "imovx")
1929         (const_string "SI")
1930         (const_string "QI")))])
1931
1932 ;; Stores and loads of ax to arbitrary constant address.
1933 ;; We fake an second form of instruction to force reload to load address
1934 ;; into register when rax is not available
1935 (define_insn "*movabsqi_1_rex64"
1936   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1937         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1938   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1939   "@
1940    movabs{b}\t{%1, %P0|%P0, %1}
1941    mov{b}\t{%1, %a0|%a0, %1}"
1942   [(set_attr "type" "imov")
1943    (set_attr "modrm" "0,*")
1944    (set_attr "length_address" "8,0")
1945    (set_attr "length_immediate" "0,*")
1946    (set_attr "memory" "store")
1947    (set_attr "mode" "QI")])
1948
1949 (define_insn "*movabsqi_2_rex64"
1950   [(set (match_operand:QI 0 "register_operand" "=a,r")
1951         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1952   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1953   "@
1954    movabs{b}\t{%P1, %0|%0, %P1}
1955    mov{b}\t{%a1, %0|%0, %a1}"
1956   [(set_attr "type" "imov")
1957    (set_attr "modrm" "0,*")
1958    (set_attr "length_address" "8,0")
1959    (set_attr "length_immediate" "0")
1960    (set_attr "memory" "load")
1961    (set_attr "mode" "QI")])
1962
1963 (define_insn "*movdi_extzv_1"
1964   [(set (match_operand:DI 0 "register_operand" "=R")
1965         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1966                          (const_int 8)
1967                          (const_int 8)))]
1968   "TARGET_64BIT"
1969   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1970   [(set_attr "type" "imovx")
1971    (set_attr "mode" "DI")])
1972
1973 (define_insn "*movsi_extzv_1"
1974   [(set (match_operand:SI 0 "register_operand" "=R")
1975         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1976                          (const_int 8)
1977                          (const_int 8)))]
1978   ""
1979   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1980   [(set_attr "type" "imovx")
1981    (set_attr "mode" "SI")])
1982
1983 (define_insn "*movqi_extzv_2"
1984   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1985         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1986                                     (const_int 8)
1987                                     (const_int 8)) 0))]
1988   "!TARGET_64BIT"
1989 {
1990   switch (get_attr_type (insn))
1991     {
1992     case TYPE_IMOVX:
1993       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1994     default:
1995       return "mov{b}\t{%h1, %0|%0, %h1}";
1996     }
1997 }
1998   [(set (attr "type")
1999      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2000                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2001                              (ne (symbol_ref "TARGET_MOVX")
2002                                  (const_int 0))))
2003         (const_string "imovx")
2004         (const_string "imov")))
2005    (set (attr "mode")
2006      (if_then_else (eq_attr "type" "imovx")
2007         (const_string "SI")
2008         (const_string "QI")))])
2009
2010 (define_insn "*movqi_extzv_2_rex64"
2011   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2012         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2013                                     (const_int 8)
2014                                     (const_int 8)) 0))]
2015   "TARGET_64BIT"
2016 {
2017   switch (get_attr_type (insn))
2018     {
2019     case TYPE_IMOVX:
2020       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2021     default:
2022       return "mov{b}\t{%h1, %0|%0, %h1}";
2023     }
2024 }
2025   [(set (attr "type")
2026      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2027                         (ne (symbol_ref "TARGET_MOVX")
2028                             (const_int 0)))
2029         (const_string "imovx")
2030         (const_string "imov")))
2031    (set (attr "mode")
2032      (if_then_else (eq_attr "type" "imovx")
2033         (const_string "SI")
2034         (const_string "QI")))])
2035
2036 (define_insn "movsi_insv_1"
2037   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2038                          (const_int 8)
2039                          (const_int 8))
2040         (match_operand:SI 1 "general_operand" "Qmn"))]
2041   "!TARGET_64BIT"
2042   "mov{b}\t{%b1, %h0|%h0, %b1}"
2043   [(set_attr "type" "imov")
2044    (set_attr "mode" "QI")])
2045
2046 (define_insn "*movsi_insv_1_rex64"
2047   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2048                          (const_int 8)
2049                          (const_int 8))
2050         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2051   "TARGET_64BIT"
2052   "mov{b}\t{%b1, %h0|%h0, %b1}"
2053   [(set_attr "type" "imov")
2054    (set_attr "mode" "QI")])
2055
2056 (define_insn "movdi_insv_1_rex64"
2057   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2058                          (const_int 8)
2059                          (const_int 8))
2060         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2061   "TARGET_64BIT"
2062   "mov{b}\t{%b1, %h0|%h0, %b1}"
2063   [(set_attr "type" "imov")
2064    (set_attr "mode" "QI")])
2065
2066 (define_insn "*movqi_insv_2"
2067   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2068                          (const_int 8)
2069                          (const_int 8))
2070         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2071                      (const_int 8)))]
2072   ""
2073   "mov{b}\t{%h1, %h0|%h0, %h1}"
2074   [(set_attr "type" "imov")
2075    (set_attr "mode" "QI")])
2076
2077 (define_expand "movdi"
2078   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2079         (match_operand:DI 1 "general_operand" ""))]
2080   ""
2081   "ix86_expand_move (DImode, operands); DONE;")
2082
2083 (define_insn "*pushdi"
2084   [(set (match_operand:DI 0 "push_operand" "=<")
2085         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2086   "!TARGET_64BIT"
2087   "#")
2088
2089 (define_insn "*pushdi2_rex64"
2090   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2091         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2092   "TARGET_64BIT"
2093   "@
2094    push{q}\t%1
2095    #"
2096   [(set_attr "type" "push,multi")
2097    (set_attr "mode" "DI")])
2098
2099 ;; Convert impossible pushes of immediate to existing instructions.
2100 ;; First try to get scratch register and go through it.  In case this
2101 ;; fails, push sign extended lower part first and then overwrite
2102 ;; upper part by 32bit move.
2103 (define_peephole2
2104   [(match_scratch:DI 2 "r")
2105    (set (match_operand:DI 0 "push_operand" "")
2106         (match_operand:DI 1 "immediate_operand" ""))]
2107   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2108    && !x86_64_immediate_operand (operands[1], DImode)"
2109   [(set (match_dup 2) (match_dup 1))
2110    (set (match_dup 0) (match_dup 2))]
2111   "")
2112
2113 ;; We need to define this as both peepholer and splitter for case
2114 ;; peephole2 pass is not run.
2115 ;; "&& 1" is needed to keep it from matching the previous pattern.
2116 (define_peephole2
2117   [(set (match_operand:DI 0 "push_operand" "")
2118         (match_operand:DI 1 "immediate_operand" ""))]
2119   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2120    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2121   [(set (match_dup 0) (match_dup 1))
2122    (set (match_dup 2) (match_dup 3))]
2123   "split_di (operands + 1, 1, operands + 2, operands + 3);
2124    operands[1] = gen_lowpart (DImode, operands[2]);
2125    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2126                                                     GEN_INT (4)));
2127   ")
2128
2129 (define_split
2130   [(set (match_operand:DI 0 "push_operand" "")
2131         (match_operand:DI 1 "immediate_operand" ""))]
2132   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2133                     ? epilogue_completed : reload_completed)
2134    && !symbolic_operand (operands[1], DImode)
2135    && !x86_64_immediate_operand (operands[1], DImode)"
2136   [(set (match_dup 0) (match_dup 1))
2137    (set (match_dup 2) (match_dup 3))]
2138   "split_di (operands + 1, 1, operands + 2, operands + 3);
2139    operands[1] = gen_lowpart (DImode, operands[2]);
2140    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2141                                                     GEN_INT (4)));
2142   ")
2143
2144 (define_insn "*pushdi2_prologue_rex64"
2145   [(set (match_operand:DI 0 "push_operand" "=<")
2146         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2147    (clobber (mem:BLK (scratch)))]
2148   "TARGET_64BIT"
2149   "push{q}\t%1"
2150   [(set_attr "type" "push")
2151    (set_attr "mode" "DI")])
2152
2153 (define_insn "*popdi1_epilogue_rex64"
2154   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2155         (mem:DI (reg:DI SP_REG)))
2156    (set (reg:DI SP_REG)
2157         (plus:DI (reg:DI SP_REG) (const_int 8)))
2158    (clobber (mem:BLK (scratch)))]
2159   "TARGET_64BIT"
2160   "pop{q}\t%0"
2161   [(set_attr "type" "pop")
2162    (set_attr "mode" "DI")])
2163
2164 (define_insn "popdi1"
2165   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2166         (mem:DI (reg:DI SP_REG)))
2167    (set (reg:DI SP_REG)
2168         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2169   "TARGET_64BIT"
2170   "pop{q}\t%0"
2171   [(set_attr "type" "pop")
2172    (set_attr "mode" "DI")])
2173
2174 (define_insn "*movdi_xor_rex64"
2175   [(set (match_operand:DI 0 "register_operand" "=r")
2176         (match_operand:DI 1 "const0_operand" "i"))
2177    (clobber (reg:CC FLAGS_REG))]
2178   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2179    && reload_completed"
2180   "xor{l}\t%k0, %k0";
2181   [(set_attr "type" "alu1")
2182    (set_attr "mode" "SI")
2183    (set_attr "length_immediate" "0")])
2184
2185 (define_insn "*movdi_or_rex64"
2186   [(set (match_operand:DI 0 "register_operand" "=r")
2187         (match_operand:DI 1 "const_int_operand" "i"))
2188    (clobber (reg:CC FLAGS_REG))]
2189   "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2190    && reload_completed
2191    && operands[1] == constm1_rtx"
2192 {
2193   operands[1] = constm1_rtx;
2194   return "or{q}\t{%1, %0|%0, %1}";
2195 }
2196   [(set_attr "type" "alu1")
2197    (set_attr "mode" "DI")
2198    (set_attr "length_immediate" "1")])
2199
2200 (define_insn "*movdi_2"
2201   [(set (match_operand:DI 0 "nonimmediate_operand"
2202                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2203         (match_operand:DI 1 "general_operand"
2204                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2205   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2206   "@
2207    #
2208    #
2209    pxor\t%0, %0
2210    movq\t{%1, %0|%0, %1}
2211    movq\t{%1, %0|%0, %1}
2212    pxor\t%0, %0
2213    movq\t{%1, %0|%0, %1}
2214    movdqa\t{%1, %0|%0, %1}
2215    movq\t{%1, %0|%0, %1}
2216    xorps\t%0, %0
2217    movlps\t{%1, %0|%0, %1}
2218    movaps\t{%1, %0|%0, %1}
2219    movlps\t{%1, %0|%0, %1}"
2220   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2221    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2222
2223 (define_split
2224   [(set (match_operand:DI 0 "push_operand" "")
2225         (match_operand:DI 1 "general_operand" ""))]
2226   "!TARGET_64BIT && reload_completed
2227    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2228   [(const_int 0)]
2229   "ix86_split_long_move (operands); DONE;")
2230
2231 ;; %%% This multiword shite has got to go.
2232 (define_split
2233   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2234         (match_operand:DI 1 "general_operand" ""))]
2235   "!TARGET_64BIT && reload_completed
2236    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2237    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2238   [(const_int 0)]
2239   "ix86_split_long_move (operands); DONE;")
2240
2241 (define_insn "*movdi_1_rex64"
2242   [(set (match_operand:DI 0 "nonimmediate_operand"
2243           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2244         (match_operand:DI 1 "general_operand"
2245           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2246   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2247 {
2248   switch (get_attr_type (insn))
2249     {
2250     case TYPE_SSECVT:
2251       if (SSE_REG_P (operands[0]))
2252         return "movq2dq\t{%1, %0|%0, %1}";
2253       else
2254         return "movdq2q\t{%1, %0|%0, %1}";
2255
2256     case TYPE_SSEMOV:
2257       if (get_attr_mode (insn) == MODE_TI)
2258         return "movdqa\t{%1, %0|%0, %1}";
2259       /* FALLTHRU */
2260
2261     case TYPE_MMXMOV:
2262       /* Moves from and into integer register is done using movd
2263          opcode with REX prefix.  */
2264       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2265         return "movd\t{%1, %0|%0, %1}";
2266       return "movq\t{%1, %0|%0, %1}";
2267
2268     case TYPE_SSELOG1:
2269     case TYPE_MMXADD:
2270       return "pxor\t%0, %0";
2271
2272     case TYPE_MULTI:
2273       return "#";
2274
2275     case TYPE_LEA:
2276       return "lea{q}\t{%a1, %0|%0, %a1}";
2277
2278     default:
2279       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2280       if (get_attr_mode (insn) == MODE_SI)
2281         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2282       else if (which_alternative == 2)
2283         return "movabs{q}\t{%1, %0|%0, %1}";
2284       else
2285         return "mov{q}\t{%1, %0|%0, %1}";
2286     }
2287 }
2288   [(set (attr "type")
2289      (cond [(eq_attr "alternative" "5")
2290               (const_string "mmxadd")
2291             (eq_attr "alternative" "6,7,8,9,10")
2292               (const_string "mmxmov")
2293             (eq_attr "alternative" "11")
2294               (const_string "sselog1")
2295             (eq_attr "alternative" "12,13,14,15,16")
2296               (const_string "ssemov")
2297             (eq_attr "alternative" "17,18")
2298               (const_string "ssecvt")
2299             (eq_attr "alternative" "4")
2300               (const_string "multi")
2301             (match_operand:DI 1 "pic_32bit_operand" "")
2302               (const_string "lea")
2303            ]
2304            (const_string "imov")))
2305    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2306    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2307    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2308
2309 ;; Stores and loads of ax to arbitrary constant address.
2310 ;; We fake an second form of instruction to force reload to load address
2311 ;; into register when rax is not available
2312 (define_insn "*movabsdi_1_rex64"
2313   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2314         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2315   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2316   "@
2317    movabs{q}\t{%1, %P0|%P0, %1}
2318    mov{q}\t{%1, %a0|%a0, %1}"
2319   [(set_attr "type" "imov")
2320    (set_attr "modrm" "0,*")
2321    (set_attr "length_address" "8,0")
2322    (set_attr "length_immediate" "0,*")
2323    (set_attr "memory" "store")
2324    (set_attr "mode" "DI")])
2325
2326 (define_insn "*movabsdi_2_rex64"
2327   [(set (match_operand:DI 0 "register_operand" "=a,r")
2328         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2329   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2330   "@
2331    movabs{q}\t{%P1, %0|%0, %P1}
2332    mov{q}\t{%a1, %0|%0, %a1}"
2333   [(set_attr "type" "imov")
2334    (set_attr "modrm" "0,*")
2335    (set_attr "length_address" "8,0")
2336    (set_attr "length_immediate" "0")
2337    (set_attr "memory" "load")
2338    (set_attr "mode" "DI")])
2339
2340 ;; Convert impossible stores of immediate to existing instructions.
2341 ;; First try to get scratch register and go through it.  In case this
2342 ;; fails, move by 32bit parts.
2343 (define_peephole2
2344   [(match_scratch:DI 2 "r")
2345    (set (match_operand:DI 0 "memory_operand" "")
2346         (match_operand:DI 1 "immediate_operand" ""))]
2347   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2348    && !x86_64_immediate_operand (operands[1], DImode)"
2349   [(set (match_dup 2) (match_dup 1))
2350    (set (match_dup 0) (match_dup 2))]
2351   "")
2352
2353 ;; We need to define this as both peepholer and splitter for case
2354 ;; peephole2 pass is not run.
2355 ;; "&& 1" is needed to keep it from matching the previous pattern.
2356 (define_peephole2
2357   [(set (match_operand:DI 0 "memory_operand" "")
2358         (match_operand:DI 1 "immediate_operand" ""))]
2359   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2360    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2361   [(set (match_dup 2) (match_dup 3))
2362    (set (match_dup 4) (match_dup 5))]
2363   "split_di (operands, 2, operands + 2, operands + 4);")
2364
2365 (define_split
2366   [(set (match_operand:DI 0 "memory_operand" "")
2367         (match_operand:DI 1 "immediate_operand" ""))]
2368   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2369                     ? epilogue_completed : reload_completed)
2370    && !symbolic_operand (operands[1], DImode)
2371    && !x86_64_immediate_operand (operands[1], DImode)"
2372   [(set (match_dup 2) (match_dup 3))
2373    (set (match_dup 4) (match_dup 5))]
2374   "split_di (operands, 2, operands + 2, operands + 4);")
2375
2376 (define_insn "*swapdi_rex64"
2377   [(set (match_operand:DI 0 "register_operand" "+r")
2378         (match_operand:DI 1 "register_operand" "+r"))
2379    (set (match_dup 1)
2380         (match_dup 0))]
2381   "TARGET_64BIT"
2382   "xchg{q}\t%1, %0"
2383   [(set_attr "type" "imov")
2384    (set_attr "mode" "DI")
2385    (set_attr "pent_pair" "np")
2386    (set_attr "athlon_decode" "vector")
2387    (set_attr "amdfam10_decode" "double")])
2388
2389 (define_expand "movti"
2390   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2391         (match_operand:TI 1 "nonimmediate_operand" ""))]
2392   "TARGET_SSE || TARGET_64BIT"
2393 {
2394   if (TARGET_64BIT)
2395     ix86_expand_move (TImode, operands);
2396   else if (push_operand (operands[0], TImode))
2397     ix86_expand_push (TImode, operands[1]);
2398   else
2399     ix86_expand_vector_move (TImode, operands);
2400   DONE;
2401 })
2402
2403 (define_insn "*movti_internal"
2404   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2405         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2406   "TARGET_SSE && !TARGET_64BIT
2407    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2408 {
2409   switch (which_alternative)
2410     {
2411     case 0:
2412       if (get_attr_mode (insn) == MODE_V4SF)
2413         return "xorps\t%0, %0";
2414       else
2415         return "pxor\t%0, %0";
2416     case 1:
2417     case 2:
2418       /* TDmode values are passed as TImode on the stack.  Moving them
2419          to stack may result in unaligned memory access.  */
2420       if (misaligned_operand (operands[0], TImode)
2421           || misaligned_operand (operands[1], TImode))
2422         { 
2423           if (get_attr_mode (insn) == MODE_V4SF)
2424             return "movups\t{%1, %0|%0, %1}";
2425          else
2426            return "movdqu\t{%1, %0|%0, %1}";
2427         }
2428       else
2429         { 
2430           if (get_attr_mode (insn) == MODE_V4SF)
2431             return "movaps\t{%1, %0|%0, %1}";
2432          else
2433            return "movdqa\t{%1, %0|%0, %1}";
2434         }
2435     default:
2436       gcc_unreachable ();
2437     }
2438 }
2439   [(set_attr "type" "sselog1,ssemov,ssemov")
2440    (set (attr "mode")
2441         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2442                     (ne (symbol_ref "optimize_size") (const_int 0)))
2443                  (const_string "V4SF")
2444                (and (eq_attr "alternative" "2")
2445                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2446                         (const_int 0)))
2447                  (const_string "V4SF")]
2448               (const_string "TI")))])
2449
2450 (define_insn "*movti_rex64"
2451   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2452         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2453   "TARGET_64BIT
2454    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2455 {
2456   switch (which_alternative)
2457     {
2458     case 0:
2459     case 1:
2460       return "#";
2461     case 2:
2462       if (get_attr_mode (insn) == MODE_V4SF)
2463         return "xorps\t%0, %0";
2464       else
2465         return "pxor\t%0, %0";
2466     case 3:
2467     case 4:
2468       /* TDmode values are passed as TImode on the stack.  Moving them
2469          to stack may result in unaligned memory access.  */
2470       if (misaligned_operand (operands[0], TImode)
2471           || misaligned_operand (operands[1], TImode))
2472         { 
2473           if (get_attr_mode (insn) == MODE_V4SF)
2474             return "movups\t{%1, %0|%0, %1}";
2475          else
2476            return "movdqu\t{%1, %0|%0, %1}";
2477         }
2478       else
2479         { 
2480           if (get_attr_mode (insn) == MODE_V4SF)
2481             return "movaps\t{%1, %0|%0, %1}";
2482          else
2483            return "movdqa\t{%1, %0|%0, %1}";
2484         }
2485     default:
2486       gcc_unreachable ();
2487     }
2488 }
2489   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2490    (set (attr "mode")
2491         (cond [(eq_attr "alternative" "2,3")
2492                  (if_then_else
2493                    (ne (symbol_ref "optimize_size")
2494                        (const_int 0))
2495                    (const_string "V4SF")
2496                    (const_string "TI"))
2497                (eq_attr "alternative" "4")
2498                  (if_then_else
2499                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2500                             (const_int 0))
2501                         (ne (symbol_ref "optimize_size")
2502                             (const_int 0)))
2503                    (const_string "V4SF")
2504                    (const_string "TI"))]
2505                (const_string "DI")))])
2506
2507 (define_split
2508   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2509         (match_operand:TI 1 "general_operand" ""))]
2510   "reload_completed && !SSE_REG_P (operands[0])
2511    && !SSE_REG_P (operands[1])"
2512   [(const_int 0)]
2513   "ix86_split_long_move (operands); DONE;")
2514
2515 ;; This expands to what emit_move_complex would generate if we didn't
2516 ;; have a movti pattern.  Having this avoids problems with reload on
2517 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2518 ;; to have around all the time.
2519 (define_expand "movcdi"
2520   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2521         (match_operand:CDI 1 "general_operand" ""))]
2522   ""
2523 {
2524   if (push_operand (operands[0], CDImode))
2525     emit_move_complex_push (CDImode, operands[0], operands[1]);
2526   else
2527     emit_move_complex_parts (operands[0], operands[1]);
2528   DONE;
2529 })
2530
2531 (define_expand "movsf"
2532   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2533         (match_operand:SF 1 "general_operand" ""))]
2534   ""
2535   "ix86_expand_move (SFmode, operands); DONE;")
2536
2537 (define_insn "*pushsf"
2538   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2539         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2540   "!TARGET_64BIT"
2541 {
2542   /* Anything else should be already split before reg-stack.  */
2543   gcc_assert (which_alternative == 1);
2544   return "push{l}\t%1";
2545 }
2546   [(set_attr "type" "multi,push,multi")
2547    (set_attr "unit" "i387,*,*")
2548    (set_attr "mode" "SF,SI,SF")])
2549
2550 (define_insn "*pushsf_rex64"
2551   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2552         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2553   "TARGET_64BIT"
2554 {
2555   /* Anything else should be already split before reg-stack.  */
2556   gcc_assert (which_alternative == 1);
2557   return "push{q}\t%q1";
2558 }
2559   [(set_attr "type" "multi,push,multi")
2560    (set_attr "unit" "i387,*,*")
2561    (set_attr "mode" "SF,DI,SF")])
2562
2563 (define_split
2564   [(set (match_operand:SF 0 "push_operand" "")
2565         (match_operand:SF 1 "memory_operand" ""))]
2566   "reload_completed
2567    && MEM_P (operands[1])
2568    && (operands[2] = find_constant_src (insn))"
2569   [(set (match_dup 0)
2570         (match_dup 2))])
2571
2572
2573 ;; %%% Kill this when call knows how to work this out.
2574 (define_split
2575   [(set (match_operand:SF 0 "push_operand" "")
2576         (match_operand:SF 1 "any_fp_register_operand" ""))]
2577   "!TARGET_64BIT"
2578   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2579    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2580
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:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2586    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2587
2588 (define_insn "*movsf_1"
2589   [(set (match_operand:SF 0 "nonimmediate_operand"
2590           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2591         (match_operand:SF 1 "general_operand"
2592           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2593   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2594    && (reload_in_progress || reload_completed
2595        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2596        || (!TARGET_SSE_MATH && optimize_size
2597            && standard_80387_constant_p (operands[1]))
2598        || GET_CODE (operands[1]) != CONST_DOUBLE
2599        || memory_operand (operands[0], SFmode))"
2600 {
2601   switch (which_alternative)
2602     {
2603     case 0:
2604     case 1:
2605       return output_387_reg_move (insn, operands);
2606
2607     case 2:
2608       return standard_80387_constant_opcode (operands[1]);
2609
2610     case 3:
2611     case 4:
2612       return "mov{l}\t{%1, %0|%0, %1}";
2613     case 5:
2614       if (get_attr_mode (insn) == MODE_TI)
2615         return "pxor\t%0, %0";
2616       else
2617         return "xorps\t%0, %0";
2618     case 6:
2619       if (get_attr_mode (insn) == MODE_V4SF)
2620         return "movaps\t{%1, %0|%0, %1}";
2621       else
2622         return "movss\t{%1, %0|%0, %1}";
2623     case 7: case 8:
2624       return "movss\t{%1, %0|%0, %1}";
2625
2626     case 9: case 10:
2627     case 12: case 13: case 14: case 15:
2628       return "movd\t{%1, %0|%0, %1}";
2629
2630     case 11:
2631       return "movq\t{%1, %0|%0, %1}";
2632
2633     default:
2634       gcc_unreachable ();
2635     }
2636 }
2637   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2638    (set (attr "mode")
2639         (cond [(eq_attr "alternative" "3,4,9,10")
2640                  (const_string "SI")
2641                (eq_attr "alternative" "5")
2642                  (if_then_else
2643                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2644                                  (const_int 0))
2645                              (ne (symbol_ref "TARGET_SSE2")
2646                                  (const_int 0)))
2647                         (eq (symbol_ref "optimize_size")
2648                             (const_int 0)))
2649                    (const_string "TI")
2650                    (const_string "V4SF"))
2651                /* For architectures resolving dependencies on
2652                   whole SSE registers use APS move to break dependency
2653                   chains, otherwise use short move to avoid extra work.
2654
2655                   Do the same for architectures resolving dependencies on
2656                   the parts.  While in DF mode it is better to always handle
2657                   just register parts, the SF mode is different due to lack
2658                   of instructions to load just part of the register.  It is
2659                   better to maintain the whole registers in single format
2660                   to avoid problems on using packed logical operations.  */
2661                (eq_attr "alternative" "6")
2662                  (if_then_else
2663                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2664                             (const_int 0))
2665                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2666                             (const_int 0)))
2667                    (const_string "V4SF")
2668                    (const_string "SF"))
2669                (eq_attr "alternative" "11")
2670                  (const_string "DI")]
2671                (const_string "SF")))])
2672
2673 (define_insn "*swapsf"
2674   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2675         (match_operand:SF 1 "fp_register_operand" "+f"))
2676    (set (match_dup 1)
2677         (match_dup 0))]
2678   "reload_completed || TARGET_80387"
2679 {
2680   if (STACK_TOP_P (operands[0]))
2681     return "fxch\t%1";
2682   else
2683     return "fxch\t%0";
2684 }
2685   [(set_attr "type" "fxch")
2686    (set_attr "mode" "SF")])
2687
2688 (define_expand "movdf"
2689   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2690         (match_operand:DF 1 "general_operand" ""))]
2691   ""
2692   "ix86_expand_move (DFmode, operands); DONE;")
2693
2694 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2695 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2696 ;; On the average, pushdf using integers can be still shorter.  Allow this
2697 ;; pattern for optimize_size too.
2698
2699 (define_insn "*pushdf_nointeger"
2700   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2701         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2702   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2703 {
2704   /* This insn should be already split before reg-stack.  */
2705   gcc_unreachable ();
2706 }
2707   [(set_attr "type" "multi")
2708    (set_attr "unit" "i387,*,*,*")
2709    (set_attr "mode" "DF,SI,SI,DF")])
2710
2711 (define_insn "*pushdf_integer"
2712   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2713         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2714   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2715 {
2716   /* This insn should be already split before reg-stack.  */
2717   gcc_unreachable ();
2718 }
2719   [(set_attr "type" "multi")
2720    (set_attr "unit" "i387,*,*")
2721    (set_attr "mode" "DF,SI,DF")])
2722
2723 ;; %%% Kill this when call knows how to work this out.
2724 (define_split
2725   [(set (match_operand:DF 0 "push_operand" "")
2726         (match_operand:DF 1 "any_fp_register_operand" ""))]
2727   "!TARGET_64BIT && reload_completed"
2728   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2729    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2730   "")
2731
2732 (define_split
2733   [(set (match_operand:DF 0 "push_operand" "")
2734         (match_operand:DF 1 "any_fp_register_operand" ""))]
2735   "TARGET_64BIT && reload_completed"
2736   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2737    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2738   "")
2739
2740 (define_split
2741   [(set (match_operand:DF 0 "push_operand" "")
2742         (match_operand:DF 1 "general_operand" ""))]
2743   "reload_completed"
2744   [(const_int 0)]
2745   "ix86_split_long_move (operands); DONE;")
2746
2747 ;; Moving is usually shorter when only FP registers are used. This separate
2748 ;; movdf pattern avoids the use of integer registers for FP operations
2749 ;; when optimizing for size.
2750
2751 (define_insn "*movdf_nointeger"
2752   [(set (match_operand:DF 0 "nonimmediate_operand"
2753                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2754         (match_operand:DF 1 "general_operand"
2755                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
2756   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2757    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2758    && (reload_in_progress || reload_completed
2759        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2760        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2761            && !memory_operand (operands[0], DFmode)
2762            && standard_80387_constant_p (operands[1]))
2763        || GET_CODE (operands[1]) != CONST_DOUBLE
2764        || ((optimize_size
2765             || !TARGET_MEMORY_MISMATCH_STALL
2766             || reload_in_progress || reload_completed)
2767            && memory_operand (operands[0], DFmode)))"
2768 {
2769   switch (which_alternative)
2770     {
2771     case 0:
2772     case 1:
2773       return output_387_reg_move (insn, operands);
2774
2775     case 2:
2776       return standard_80387_constant_opcode (operands[1]);
2777
2778     case 3:
2779     case 4:
2780       return "#";
2781     case 5:
2782       switch (get_attr_mode (insn))
2783         {
2784         case MODE_V4SF:
2785           return "xorps\t%0, %0";
2786         case MODE_V2DF:
2787           return "xorpd\t%0, %0";
2788         case MODE_TI:
2789           return "pxor\t%0, %0";
2790         default:
2791           gcc_unreachable ();
2792         }
2793     case 6:
2794     case 7:
2795     case 8:
2796       switch (get_attr_mode (insn))
2797         {
2798         case MODE_V4SF:
2799           return "movaps\t{%1, %0|%0, %1}";
2800         case MODE_V2DF:
2801           return "movapd\t{%1, %0|%0, %1}";
2802         case MODE_TI:
2803           return "movdqa\t{%1, %0|%0, %1}";
2804         case MODE_DI:
2805           return "movq\t{%1, %0|%0, %1}";
2806         case MODE_DF:
2807           return "movsd\t{%1, %0|%0, %1}";
2808         case MODE_V1DF:
2809           return "movlpd\t{%1, %0|%0, %1}";
2810         case MODE_V2SF:
2811           return "movlps\t{%1, %0|%0, %1}";
2812         default:
2813           gcc_unreachable ();
2814         }
2815
2816     default:
2817       gcc_unreachable ();
2818     }
2819 }
2820   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2821    (set (attr "mode")
2822         (cond [(eq_attr "alternative" "0,1,2")
2823                  (const_string "DF")
2824                (eq_attr "alternative" "3,4")
2825                  (const_string "SI")
2826
2827                /* For SSE1, we have many fewer alternatives.  */
2828                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2829                  (cond [(eq_attr "alternative" "5,6")
2830                           (const_string "V4SF")
2831                        ]
2832                    (const_string "V2SF"))
2833
2834                /* xorps is one byte shorter.  */
2835                (eq_attr "alternative" "5")
2836                  (cond [(ne (symbol_ref "optimize_size")
2837                             (const_int 0))
2838                           (const_string "V4SF")
2839                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2840                             (const_int 0))
2841                           (const_string "TI")
2842                        ]
2843                        (const_string "V2DF"))
2844
2845                /* For architectures resolving dependencies on
2846                   whole SSE registers use APD move to break dependency
2847                   chains, otherwise use short move to avoid extra work.
2848
2849                   movaps encodes one byte shorter.  */
2850                (eq_attr "alternative" "6")
2851                  (cond
2852                    [(ne (symbol_ref "optimize_size")
2853                         (const_int 0))
2854                       (const_string "V4SF")
2855                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2856                         (const_int 0))
2857                       (const_string "V2DF")
2858                    ]
2859                    (const_string "DF"))
2860                /* For architectures resolving dependencies on register
2861                   parts we may avoid extra work to zero out upper part
2862                   of register.  */
2863                (eq_attr "alternative" "7")
2864                  (if_then_else
2865                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2866                        (const_int 0))
2867                    (const_string "V1DF")
2868                    (const_string "DF"))
2869               ]
2870               (const_string "DF")))])
2871
2872 (define_insn "*movdf_integer_rex64"
2873   [(set (match_operand:DF 0 "nonimmediate_operand"
2874                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2875         (match_operand:DF 1 "general_operand"
2876                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2877   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2878    && (reload_in_progress || reload_completed
2879        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2880        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2881            && standard_80387_constant_p (operands[1]))
2882        || GET_CODE (operands[1]) != CONST_DOUBLE
2883        || memory_operand (operands[0], DFmode))"
2884 {
2885   switch (which_alternative)
2886     {
2887     case 0:
2888     case 1:
2889       return output_387_reg_move (insn, operands);
2890
2891     case 2:
2892       return standard_80387_constant_opcode (operands[1]);
2893
2894     case 3:
2895     case 4:
2896       return "#";
2897
2898     case 5:
2899       switch (get_attr_mode (insn))
2900         {
2901         case MODE_V4SF:
2902           return "xorps\t%0, %0";
2903         case MODE_V2DF:
2904           return "xorpd\t%0, %0";
2905         case MODE_TI:
2906           return "pxor\t%0, %0";
2907         default:
2908           gcc_unreachable ();
2909         }
2910     case 6:
2911     case 7:
2912     case 8:
2913       switch (get_attr_mode (insn))
2914         {
2915         case MODE_V4SF:
2916           return "movaps\t{%1, %0|%0, %1}";
2917         case MODE_V2DF:
2918           return "movapd\t{%1, %0|%0, %1}";
2919         case MODE_TI:
2920           return "movdqa\t{%1, %0|%0, %1}";
2921         case MODE_DI:
2922           return "movq\t{%1, %0|%0, %1}";
2923         case MODE_DF:
2924           return "movsd\t{%1, %0|%0, %1}";
2925         case MODE_V1DF:
2926           return "movlpd\t{%1, %0|%0, %1}";
2927         case MODE_V2SF:
2928           return "movlps\t{%1, %0|%0, %1}";
2929         default:
2930           gcc_unreachable ();
2931         }
2932
2933     case 9:
2934     case 10:
2935       return "movd\t{%1, %0|%0, %1}";
2936
2937     default:
2938       gcc_unreachable();
2939     }
2940 }
2941   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2942    (set (attr "mode")
2943         (cond [(eq_attr "alternative" "0,1,2")
2944                  (const_string "DF")
2945                (eq_attr "alternative" "3,4,9,10")
2946                  (const_string "DI")
2947
2948                /* For SSE1, we have many fewer alternatives.  */
2949                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2950                  (cond [(eq_attr "alternative" "5,6")
2951                           (const_string "V4SF")
2952                        ]
2953                    (const_string "V2SF"))
2954
2955                /* xorps is one byte shorter.  */
2956                (eq_attr "alternative" "5")
2957                  (cond [(ne (symbol_ref "optimize_size")
2958                             (const_int 0))
2959                           (const_string "V4SF")
2960                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2961                             (const_int 0))
2962                           (const_string "TI")
2963                        ]
2964                        (const_string "V2DF"))
2965
2966                /* For architectures resolving dependencies on
2967                   whole SSE registers use APD move to break dependency
2968                   chains, otherwise use short move to avoid extra work.
2969
2970                   movaps encodes one byte shorter.  */
2971                (eq_attr "alternative" "6")
2972                  (cond
2973                    [(ne (symbol_ref "optimize_size")
2974                         (const_int 0))
2975                       (const_string "V4SF")
2976                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2977                         (const_int 0))
2978                       (const_string "V2DF")
2979                    ]
2980                    (const_string "DF"))
2981                /* For architectures resolving dependencies on register
2982                   parts we may avoid extra work to zero out upper part
2983                   of register.  */
2984                (eq_attr "alternative" "7")
2985                  (if_then_else
2986                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2987                        (const_int 0))
2988                    (const_string "V1DF")
2989                    (const_string "DF"))
2990               ]
2991               (const_string "DF")))])
2992
2993 (define_insn "*movdf_integer"
2994   [(set (match_operand:DF 0 "nonimmediate_operand"
2995                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
2996         (match_operand:DF 1 "general_operand"
2997                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
2998   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2999    && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
3000    && (reload_in_progress || reload_completed
3001        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3002        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
3003            && standard_80387_constant_p (operands[1]))
3004        || GET_CODE (operands[1]) != CONST_DOUBLE
3005        || memory_operand (operands[0], DFmode))"
3006 {
3007   switch (which_alternative)
3008     {
3009     case 0:
3010     case 1:
3011       return output_387_reg_move (insn, operands);
3012
3013     case 2:
3014       return standard_80387_constant_opcode (operands[1]);
3015
3016     case 3:
3017     case 4:
3018       return "#";
3019
3020     case 5:
3021       switch (get_attr_mode (insn))
3022         {
3023         case MODE_V4SF:
3024           return "xorps\t%0, %0";
3025         case MODE_V2DF:
3026           return "xorpd\t%0, %0";
3027         case MODE_TI:
3028           return "pxor\t%0, %0";
3029         default:
3030           gcc_unreachable ();
3031         }
3032     case 6:
3033     case 7:
3034     case 8:
3035       switch (get_attr_mode (insn))
3036         {
3037         case MODE_V4SF:
3038           return "movaps\t{%1, %0|%0, %1}";
3039         case MODE_V2DF:
3040           return "movapd\t{%1, %0|%0, %1}";
3041         case MODE_TI:
3042           return "movdqa\t{%1, %0|%0, %1}";
3043         case MODE_DI:
3044           return "movq\t{%1, %0|%0, %1}";
3045         case MODE_DF:
3046           return "movsd\t{%1, %0|%0, %1}";
3047         case MODE_V1DF:
3048           return "movlpd\t{%1, %0|%0, %1}";
3049         case MODE_V2SF:
3050           return "movlps\t{%1, %0|%0, %1}";
3051         default:
3052           gcc_unreachable ();
3053         }
3054
3055     default:
3056       gcc_unreachable();
3057     }
3058 }
3059   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3060    (set (attr "mode")
3061         (cond [(eq_attr "alternative" "0,1,2")
3062                  (const_string "DF")
3063                (eq_attr "alternative" "3,4")
3064                  (const_string "SI")
3065
3066                /* For SSE1, we have many fewer alternatives.  */
3067                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3068                  (cond [(eq_attr "alternative" "5,6")
3069                           (const_string "V4SF")
3070                        ]
3071                    (const_string "V2SF"))
3072
3073                /* xorps is one byte shorter.  */
3074                (eq_attr "alternative" "5")
3075                  (cond [(ne (symbol_ref "optimize_size")
3076                             (const_int 0))
3077                           (const_string "V4SF")
3078                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3079                             (const_int 0))
3080                           (const_string "TI")
3081                        ]
3082                        (const_string "V2DF"))
3083
3084                /* For architectures resolving dependencies on
3085                   whole SSE registers use APD move to break dependency
3086                   chains, otherwise use short move to avoid extra work.
3087
3088                   movaps encodes one byte shorter.  */
3089                (eq_attr "alternative" "6")
3090                  (cond
3091                    [(ne (symbol_ref "optimize_size")
3092                         (const_int 0))
3093                       (const_string "V4SF")
3094                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3095                         (const_int 0))
3096                       (const_string "V2DF")
3097                    ]
3098                    (const_string "DF"))
3099                /* For architectures resolving dependencies on register
3100                   parts we may avoid extra work to zero out upper part
3101                   of register.  */
3102                (eq_attr "alternative" "7")
3103                  (if_then_else
3104                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3105                        (const_int 0))
3106                    (const_string "V1DF")
3107                    (const_string "DF"))
3108               ]
3109               (const_string "DF")))])
3110
3111 (define_split
3112   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3113         (match_operand:DF 1 "general_operand" ""))]
3114   "reload_completed
3115    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3116    && ! (ANY_FP_REG_P (operands[0]) ||
3117          (GET_CODE (operands[0]) == SUBREG
3118           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3119    && ! (ANY_FP_REG_P (operands[1]) ||
3120          (GET_CODE (operands[1]) == SUBREG
3121           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3122   [(const_int 0)]
3123   "ix86_split_long_move (operands); DONE;")
3124
3125 (define_insn "*swapdf"
3126   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3127         (match_operand:DF 1 "fp_register_operand" "+f"))
3128    (set (match_dup 1)
3129         (match_dup 0))]
3130   "reload_completed || TARGET_80387"
3131 {
3132   if (STACK_TOP_P (operands[0]))
3133     return "fxch\t%1";
3134   else
3135     return "fxch\t%0";
3136 }
3137   [(set_attr "type" "fxch")
3138    (set_attr "mode" "DF")])
3139
3140 (define_expand "movxf"
3141   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3142         (match_operand:XF 1 "general_operand" ""))]
3143   ""
3144   "ix86_expand_move (XFmode, operands); DONE;")
3145
3146 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3147 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3148 ;; Pushing using integer instructions is longer except for constants
3149 ;; and direct memory references.
3150 ;; (assuming that any given constant is pushed only once, but this ought to be
3151 ;;  handled elsewhere).
3152
3153 (define_insn "*pushxf_nointeger"
3154   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3155         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3156   "optimize_size"
3157 {
3158   /* This insn should be already split before reg-stack.  */
3159   gcc_unreachable ();
3160 }
3161   [(set_attr "type" "multi")
3162    (set_attr "unit" "i387,*,*")
3163    (set_attr "mode" "XF,SI,SI")])
3164
3165 (define_insn "*pushxf_integer"
3166   [(set (match_operand:XF 0 "push_operand" "=<,<")
3167         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3168   "!optimize_size"
3169 {
3170   /* This insn should be already split before reg-stack.  */
3171   gcc_unreachable ();
3172 }
3173   [(set_attr "type" "multi")
3174    (set_attr "unit" "i387,*")
3175    (set_attr "mode" "XF,SI")])
3176
3177 (define_split
3178   [(set (match_operand 0 "push_operand" "")
3179         (match_operand 1 "general_operand" ""))]
3180   "reload_completed
3181    && (GET_MODE (operands[0]) == XFmode
3182        || GET_MODE (operands[0]) == DFmode)
3183    && !ANY_FP_REG_P (operands[1])"
3184   [(const_int 0)]
3185   "ix86_split_long_move (operands); DONE;")
3186
3187 (define_split
3188   [(set (match_operand:XF 0 "push_operand" "")
3189         (match_operand:XF 1 "any_fp_register_operand" ""))]
3190   "!TARGET_64BIT"
3191   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3192    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
3193   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3194
3195 (define_split
3196   [(set (match_operand:XF 0 "push_operand" "")
3197         (match_operand:XF 1 "any_fp_register_operand" ""))]
3198   "TARGET_64BIT"
3199   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3200    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
3201   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3202
3203 ;; Do not use integer registers when optimizing for size
3204 (define_insn "*movxf_nointeger"
3205   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3206         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3207   "optimize_size
3208    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3209    && (reload_in_progress || reload_completed
3210        || (optimize_size && standard_80387_constant_p (operands[1]))
3211        || GET_CODE (operands[1]) != CONST_DOUBLE
3212        || memory_operand (operands[0], XFmode))"
3213 {
3214   switch (which_alternative)
3215     {
3216     case 0:
3217     case 1:
3218       return output_387_reg_move (insn, operands);
3219
3220     case 2:
3221       return standard_80387_constant_opcode (operands[1]);
3222
3223     case 3: case 4:
3224       return "#";
3225     default:
3226       gcc_unreachable ();
3227     }
3228 }
3229   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3230    (set_attr "mode" "XF,XF,XF,SI,SI")])
3231
3232 (define_insn "*movxf_integer"
3233   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3234         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3235   "!optimize_size
3236    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3237    && (reload_in_progress || reload_completed
3238        || (optimize_size && standard_80387_constant_p (operands[1]))
3239        || GET_CODE (operands[1]) != CONST_DOUBLE
3240        || memory_operand (operands[0], XFmode))"
3241 {
3242   switch (which_alternative)
3243     {
3244     case 0:
3245     case 1:
3246       return output_387_reg_move (insn, operands);
3247
3248     case 2:
3249       return standard_80387_constant_opcode (operands[1]);
3250
3251     case 3: case 4:
3252       return "#";
3253
3254     default:
3255       gcc_unreachable ();
3256     }
3257 }
3258   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3259    (set_attr "mode" "XF,XF,XF,SI,SI")])
3260
3261 (define_expand "movtf"
3262   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3263         (match_operand:TF 1 "nonimmediate_operand" ""))]
3264   "TARGET_64BIT"
3265 {
3266   ix86_expand_move (TFmode, operands);
3267   DONE;
3268 })
3269
3270 (define_insn "*movtf_internal"
3271   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3272         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3273   "TARGET_64BIT
3274    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3275 {
3276   switch (which_alternative)
3277     {
3278     case 0:
3279     case 1:
3280       if (get_attr_mode (insn) == MODE_V4SF)
3281         return "movaps\t{%1, %0|%0, %1}";
3282       else
3283         return "movdqa\t{%1, %0|%0, %1}";
3284     case 2:
3285       if (get_attr_mode (insn) == MODE_V4SF)
3286         return "xorps\t%0, %0";
3287       else
3288         return "pxor\t%0, %0";
3289     case 3:
3290     case 4:
3291         return "#";
3292     default:
3293       gcc_unreachable ();
3294     }
3295 }
3296   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3297    (set (attr "mode")
3298         (cond [(eq_attr "alternative" "0,2")
3299                  (if_then_else
3300                    (ne (symbol_ref "optimize_size")
3301                        (const_int 0))
3302                    (const_string "V4SF")
3303                    (const_string "TI"))
3304                (eq_attr "alternative" "1")
3305                  (if_then_else
3306                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3307                             (const_int 0))
3308                         (ne (symbol_ref "optimize_size")
3309                             (const_int 0)))
3310                    (const_string "V4SF")
3311                    (const_string "TI"))]
3312                (const_string "DI")))])
3313
3314 (define_split
3315   [(set (match_operand 0 "nonimmediate_operand" "")
3316         (match_operand 1 "general_operand" ""))]
3317   "reload_completed
3318    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3319    && GET_MODE (operands[0]) == XFmode
3320    && ! (ANY_FP_REG_P (operands[0]) ||
3321          (GET_CODE (operands[0]) == SUBREG
3322           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3323    && ! (ANY_FP_REG_P (operands[1]) ||
3324          (GET_CODE (operands[1]) == SUBREG
3325           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3326   [(const_int 0)]
3327   "ix86_split_long_move (operands); DONE;")
3328
3329 (define_split
3330   [(set (match_operand 0 "register_operand" "")
3331         (match_operand 1 "memory_operand" ""))]
3332   "reload_completed
3333    && MEM_P (operands[1])
3334    && (GET_MODE (operands[0]) == TFmode
3335        || GET_MODE (operands[0]) == XFmode
3336        || GET_MODE (operands[0]) == SFmode
3337        || GET_MODE (operands[0]) == DFmode)
3338    && (operands[2] = find_constant_src (insn))"
3339   [(set (match_dup 0) (match_dup 2))]
3340 {
3341   rtx c = operands[2];
3342   rtx r = operands[0];
3343
3344   if (GET_CODE (r) == SUBREG)
3345     r = SUBREG_REG (r);
3346
3347   if (SSE_REG_P (r))
3348     {
3349       if (!standard_sse_constant_p (c))
3350         FAIL;
3351     }
3352   else if (FP_REG_P (r))
3353     {
3354       if (!standard_80387_constant_p (c))
3355         FAIL;
3356     }
3357   else if (MMX_REG_P (r))
3358     FAIL;
3359 })
3360
3361 (define_split
3362   [(set (match_operand 0 "register_operand" "")
3363         (float_extend (match_operand 1 "memory_operand" "")))]
3364   "reload_completed
3365    && MEM_P (operands[1])
3366    && (GET_MODE (operands[0]) == TFmode
3367        || GET_MODE (operands[0]) == XFmode
3368        || GET_MODE (operands[0]) == SFmode
3369        || GET_MODE (operands[0]) == DFmode)
3370    && (operands[2] = find_constant_src (insn))"
3371   [(set (match_dup 0) (match_dup 2))]
3372 {
3373   rtx c = operands[2];
3374   rtx r = operands[0];
3375
3376   if (GET_CODE (r) == SUBREG)
3377     r = SUBREG_REG (r);
3378
3379   if (SSE_REG_P (r))
3380     {
3381       if (!standard_sse_constant_p (c))
3382         FAIL;
3383     }
3384   else if (FP_REG_P (r))
3385     {
3386       if (!standard_80387_constant_p (c))
3387         FAIL;
3388     }
3389   else if (MMX_REG_P (r))
3390     FAIL;
3391 })
3392
3393 (define_insn "swapxf"
3394   [(set (match_operand:XF 0 "register_operand" "+f")
3395         (match_operand:XF 1 "register_operand" "+f"))
3396    (set (match_dup 1)
3397         (match_dup 0))]
3398   "TARGET_80387"
3399 {
3400   if (STACK_TOP_P (operands[0]))
3401     return "fxch\t%1";
3402   else
3403     return "fxch\t%0";
3404 }
3405   [(set_attr "type" "fxch")
3406    (set_attr "mode" "XF")])
3407
3408 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3409 (define_split
3410   [(set (match_operand:X87MODEF 0 "register_operand" "")
3411         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3412   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3413    && (standard_80387_constant_p (operands[1]) == 8
3414        || standard_80387_constant_p (operands[1]) == 9)"
3415   [(set (match_dup 0)(match_dup 1))
3416    (set (match_dup 0)
3417         (neg:X87MODEF (match_dup 0)))]
3418 {
3419   REAL_VALUE_TYPE r;
3420
3421   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3422   if (real_isnegzero (&r))
3423     operands[1] = CONST0_RTX (<MODE>mode);
3424   else
3425     operands[1] = CONST1_RTX (<MODE>mode);
3426 })
3427
3428 (define_split
3429   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3430         (match_operand:TF 1 "general_operand" ""))]
3431   "reload_completed
3432    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3433   [(const_int 0)]
3434   "ix86_split_long_move (operands); DONE;")
3435 \f
3436 ;; Zero extension instructions
3437
3438 (define_expand "zero_extendhisi2"
3439   [(set (match_operand:SI 0 "register_operand" "")
3440      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3441   ""
3442 {
3443   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3444     {
3445       operands[1] = force_reg (HImode, operands[1]);
3446       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3447       DONE;
3448     }
3449 })
3450
3451 (define_insn "zero_extendhisi2_and"
3452   [(set (match_operand:SI 0 "register_operand" "=r")
3453      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3454    (clobber (reg:CC FLAGS_REG))]
3455   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3456   "#"
3457   [(set_attr "type" "alu1")
3458    (set_attr "mode" "SI")])
3459
3460 (define_split
3461   [(set (match_operand:SI 0 "register_operand" "")
3462         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3463    (clobber (reg:CC FLAGS_REG))]
3464   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3465   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3466               (clobber (reg:CC FLAGS_REG))])]
3467   "")
3468
3469 (define_insn "*zero_extendhisi2_movzwl"
3470   [(set (match_operand:SI 0 "register_operand" "=r")
3471      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3472   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3473   "movz{wl|x}\t{%1, %0|%0, %1}"
3474   [(set_attr "type" "imovx")
3475    (set_attr "mode" "SI")])
3476
3477 (define_expand "zero_extendqihi2"
3478   [(parallel
3479     [(set (match_operand:HI 0 "register_operand" "")
3480        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3481      (clobber (reg:CC FLAGS_REG))])]
3482   ""
3483   "")
3484
3485 (define_insn "*zero_extendqihi2_and"
3486   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3487      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3488    (clobber (reg:CC FLAGS_REG))]
3489   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3490   "#"
3491   [(set_attr "type" "alu1")
3492    (set_attr "mode" "HI")])
3493
3494 (define_insn "*zero_extendqihi2_movzbw_and"
3495   [(set (match_operand:HI 0 "register_operand" "=r,r")
3496      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3497    (clobber (reg:CC FLAGS_REG))]
3498   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3499   "#"
3500   [(set_attr "type" "imovx,alu1")
3501    (set_attr "mode" "HI")])
3502
3503 ; zero extend to SImode here to avoid partial register stalls
3504 (define_insn "*zero_extendqihi2_movzbl"
3505   [(set (match_operand:HI 0 "register_operand" "=r")
3506      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3507   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3508   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3509   [(set_attr "type" "imovx")
3510    (set_attr "mode" "SI")])
3511
3512 ;; For the movzbw case strip only the clobber
3513 (define_split
3514   [(set (match_operand:HI 0 "register_operand" "")
3515         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3516    (clobber (reg:CC FLAGS_REG))]
3517   "reload_completed
3518    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3519    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3520   [(set (match_operand:HI 0 "register_operand" "")
3521         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3522
3523 ;; When source and destination does not overlap, clear destination
3524 ;; first and then do the movb
3525 (define_split
3526   [(set (match_operand:HI 0 "register_operand" "")
3527         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3528    (clobber (reg:CC FLAGS_REG))]
3529   "reload_completed
3530    && ANY_QI_REG_P (operands[0])
3531    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3532    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3533   [(set (match_dup 0) (const_int 0))
3534    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3535   "operands[2] = gen_lowpart (QImode, operands[0]);")
3536
3537 ;; Rest is handled by single and.
3538 (define_split
3539   [(set (match_operand:HI 0 "register_operand" "")
3540         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3541    (clobber (reg:CC FLAGS_REG))]
3542   "reload_completed
3543    && true_regnum (operands[0]) == true_regnum (operands[1])"
3544   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3545               (clobber (reg:CC FLAGS_REG))])]
3546   "")
3547
3548 (define_expand "zero_extendqisi2"
3549   [(parallel
3550     [(set (match_operand:SI 0 "register_operand" "")
3551        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3552      (clobber (reg:CC FLAGS_REG))])]
3553   ""
3554   "")
3555
3556 (define_insn "*zero_extendqisi2_and"
3557   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3558      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3559    (clobber (reg:CC FLAGS_REG))]
3560   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3561   "#"
3562   [(set_attr "type" "alu1")
3563    (set_attr "mode" "SI")])
3564
3565 (define_insn "*zero_extendqisi2_movzbw_and"
3566   [(set (match_operand:SI 0 "register_operand" "=r,r")
3567      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3568    (clobber (reg:CC FLAGS_REG))]
3569   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3570   "#"
3571   [(set_attr "type" "imovx,alu1")
3572    (set_attr "mode" "SI")])
3573
3574 (define_insn "*zero_extendqisi2_movzbw"
3575   [(set (match_operand:SI 0 "register_operand" "=r")
3576      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3577   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3578   "movz{bl|x}\t{%1, %0|%0, %1}"
3579   [(set_attr "type" "imovx")
3580    (set_attr "mode" "SI")])
3581
3582 ;; For the movzbl case strip only the clobber
3583 (define_split
3584   [(set (match_operand:SI 0 "register_operand" "")
3585         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3586    (clobber (reg:CC FLAGS_REG))]
3587   "reload_completed
3588    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3589    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3590   [(set (match_dup 0)
3591         (zero_extend:SI (match_dup 1)))])
3592
3593 ;; When source and destination does not overlap, clear destination
3594 ;; first and then do the movb
3595 (define_split
3596   [(set (match_operand:SI 0 "register_operand" "")
3597         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3598    (clobber (reg:CC FLAGS_REG))]
3599   "reload_completed
3600    && ANY_QI_REG_P (operands[0])
3601    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3602    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3603    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3604   [(set (match_dup 0) (const_int 0))
3605    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3606   "operands[2] = gen_lowpart (QImode, operands[0]);")
3607
3608 ;; Rest is handled by single and.
3609 (define_split
3610   [(set (match_operand:SI 0 "register_operand" "")
3611         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3612    (clobber (reg:CC FLAGS_REG))]
3613   "reload_completed
3614    && true_regnum (operands[0]) == true_regnum (operands[1])"
3615   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3616               (clobber (reg:CC FLAGS_REG))])]
3617   "")
3618
3619 ;; %%% Kill me once multi-word ops are sane.
3620 (define_expand "zero_extendsidi2"
3621   [(set (match_operand:DI 0 "register_operand" "")
3622      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3623   ""
3624 {
3625   if (!TARGET_64BIT)
3626     {
3627       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3628       DONE;
3629     }
3630 })
3631
3632 (define_insn "zero_extendsidi2_32"
3633   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3634         (zero_extend:DI
3635          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3636    (clobber (reg:CC FLAGS_REG))]
3637   "!TARGET_64BIT"
3638   "@
3639    #
3640    #
3641    #
3642    movd\t{%1, %0|%0, %1}
3643    movd\t{%1, %0|%0, %1}
3644    movd\t{%1, %0|%0, %1}
3645    movd\t{%1, %0|%0, %1}"
3646   [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3647    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3648
3649 (define_insn "zero_extendsidi2_rex64"
3650   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3651      (zero_extend:DI
3652        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3653   "TARGET_64BIT"
3654   "@
3655    mov\t{%k1, %k0|%k0, %k1}
3656    #
3657    movd\t{%1, %0|%0, %1}
3658    movd\t{%1, %0|%0, %1}
3659    movd\t{%1, %0|%0, %1}
3660    movd\t{%1, %0|%0, %1}"
3661   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3662    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3663
3664 (define_split
3665   [(set (match_operand:DI 0 "memory_operand" "")
3666      (zero_extend:DI (match_dup 0)))]
3667   "TARGET_64BIT"
3668   [(set (match_dup 4) (const_int 0))]
3669   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3670
3671 (define_split
3672   [(set (match_operand:DI 0 "register_operand" "")
3673         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3674    (clobber (reg:CC FLAGS_REG))]
3675   "!TARGET_64BIT && reload_completed
3676    && true_regnum (operands[0]) == true_regnum (operands[1])"
3677   [(set (match_dup 4) (const_int 0))]
3678   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3679
3680 (define_split
3681   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3682         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3683    (clobber (reg:CC FLAGS_REG))]
3684   "!TARGET_64BIT && reload_completed
3685    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3686   [(set (match_dup 3) (match_dup 1))
3687    (set (match_dup 4) (const_int 0))]
3688   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3689
3690 (define_insn "zero_extendhidi2"
3691   [(set (match_operand:DI 0 "register_operand" "=r")
3692      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3693   "TARGET_64BIT"
3694   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3695   [(set_attr "type" "imovx")
3696    (set_attr "mode" "DI")])
3697
3698 (define_insn "zero_extendqidi2"
3699   [(set (match_operand:DI 0 "register_operand" "=r")
3700      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3701   "TARGET_64BIT"
3702   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3703   [(set_attr "type" "imovx")
3704    (set_attr "mode" "DI")])
3705 \f
3706 ;; Sign extension instructions
3707
3708 (define_expand "extendsidi2"
3709   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3710                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3711               (clobber (reg:CC FLAGS_REG))
3712               (clobber (match_scratch:SI 2 ""))])]
3713   ""
3714 {
3715   if (TARGET_64BIT)
3716     {
3717       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3718       DONE;
3719     }
3720 })
3721
3722 (define_insn "*extendsidi2_1"
3723   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3724         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3725    (clobber (reg:CC FLAGS_REG))
3726    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3727   "!TARGET_64BIT"
3728   "#")
3729
3730 (define_insn "extendsidi2_rex64"
3731   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3732         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3733   "TARGET_64BIT"
3734   "@
3735    {cltq|cdqe}
3736    movs{lq|x}\t{%1,%0|%0, %1}"
3737   [(set_attr "type" "imovx")
3738    (set_attr "mode" "DI")
3739    (set_attr "prefix_0f" "0")
3740    (set_attr "modrm" "0,1")])
3741
3742 (define_insn "extendhidi2"
3743   [(set (match_operand:DI 0 "register_operand" "=r")
3744         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3745   "TARGET_64BIT"
3746   "movs{wq|x}\t{%1,%0|%0, %1}"
3747   [(set_attr "type" "imovx")
3748    (set_attr "mode" "DI")])
3749
3750 (define_insn "extendqidi2"
3751   [(set (match_operand:DI 0 "register_operand" "=r")
3752         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3753   "TARGET_64BIT"
3754   "movs{bq|x}\t{%1,%0|%0, %1}"
3755    [(set_attr "type" "imovx")
3756     (set_attr "mode" "DI")])
3757
3758 ;; Extend to memory case when source register does die.
3759 (define_split
3760   [(set (match_operand:DI 0 "memory_operand" "")
3761         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3762    (clobber (reg:CC FLAGS_REG))
3763    (clobber (match_operand:SI 2 "register_operand" ""))]
3764   "(reload_completed
3765     && dead_or_set_p (insn, operands[1])
3766     && !reg_mentioned_p (operands[1], operands[0]))"
3767   [(set (match_dup 3) (match_dup 1))
3768    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3769               (clobber (reg:CC FLAGS_REG))])
3770    (set (match_dup 4) (match_dup 1))]
3771   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3772
3773 ;; Extend to memory case when source register does not die.
3774 (define_split
3775   [(set (match_operand:DI 0 "memory_operand" "")
3776         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3777    (clobber (reg:CC FLAGS_REG))
3778    (clobber (match_operand:SI 2 "register_operand" ""))]
3779   "reload_completed"
3780   [(const_int 0)]
3781 {
3782   split_di (&operands[0], 1, &operands[3], &operands[4]);
3783
3784   emit_move_insn (operands[3], operands[1]);
3785
3786   /* Generate a cltd if possible and doing so it profitable.  */
3787   if ((optimize_size || TARGET_USE_CLTD)
3788       && true_regnum (operands[1]) == AX_REG
3789       && true_regnum (operands[2]) == DX_REG)
3790     {
3791       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3792     }
3793   else
3794     {
3795       emit_move_insn (operands[2], operands[1]);
3796       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3797     }
3798   emit_move_insn (operands[4], operands[2]);
3799   DONE;
3800 })
3801
3802 ;; Extend to register case.  Optimize case where source and destination
3803 ;; registers match and cases where we can use cltd.
3804 (define_split
3805   [(set (match_operand:DI 0 "register_operand" "")
3806         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3807    (clobber (reg:CC FLAGS_REG))
3808    (clobber (match_scratch:SI 2 ""))]
3809   "reload_completed"
3810   [(const_int 0)]
3811 {
3812   split_di (&operands[0], 1, &operands[3], &operands[4]);
3813
3814   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3815     emit_move_insn (operands[3], operands[1]);
3816
3817   /* Generate a cltd if possible and doing so it profitable.  */
3818   if ((optimize_size || TARGET_USE_CLTD)
3819       && true_regnum (operands[3]) == AX_REG)
3820     {
3821       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3822       DONE;
3823     }
3824
3825   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3826     emit_move_insn (operands[4], operands[1]);
3827
3828   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3829   DONE;
3830 })
3831
3832 (define_insn "extendhisi2"
3833   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3834         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3835   ""
3836 {
3837   switch (get_attr_prefix_0f (insn))
3838     {
3839     case 0:
3840       return "{cwtl|cwde}";
3841     default:
3842       return "movs{wl|x}\t{%1,%0|%0, %1}";
3843     }
3844 }
3845   [(set_attr "type" "imovx")
3846    (set_attr "mode" "SI")
3847    (set (attr "prefix_0f")
3848      ;; movsx is short decodable while cwtl is vector decoded.
3849      (if_then_else (and (eq_attr "cpu" "!k6")
3850                         (eq_attr "alternative" "0"))
3851         (const_string "0")
3852         (const_string "1")))
3853    (set (attr "modrm")
3854      (if_then_else (eq_attr "prefix_0f" "0")
3855         (const_string "0")
3856         (const_string "1")))])
3857
3858 (define_insn "*extendhisi2_zext"
3859   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3860         (zero_extend:DI
3861           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3862   "TARGET_64BIT"
3863 {
3864   switch (get_attr_prefix_0f (insn))
3865     {
3866     case 0:
3867       return "{cwtl|cwde}";
3868     default:
3869       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3870     }
3871 }
3872   [(set_attr "type" "imovx")
3873    (set_attr "mode" "SI")
3874    (set (attr "prefix_0f")
3875      ;; movsx is short decodable while cwtl is vector decoded.
3876      (if_then_else (and (eq_attr "cpu" "!k6")
3877                         (eq_attr "alternative" "0"))
3878         (const_string "0")
3879         (const_string "1")))
3880    (set (attr "modrm")
3881      (if_then_else (eq_attr "prefix_0f" "0")
3882         (const_string "0")
3883         (const_string "1")))])
3884
3885 (define_insn "extendqihi2"
3886   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3887         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3888   ""
3889 {
3890   switch (get_attr_prefix_0f (insn))
3891     {
3892     case 0:
3893       return "{cbtw|cbw}";
3894     default:
3895       return "movs{bw|x}\t{%1,%0|%0, %1}";
3896     }
3897 }
3898   [(set_attr "type" "imovx")
3899    (set_attr "mode" "HI")
3900    (set (attr "prefix_0f")
3901      ;; movsx is short decodable while cwtl is vector decoded.
3902      (if_then_else (and (eq_attr "cpu" "!k6")
3903                         (eq_attr "alternative" "0"))
3904         (const_string "0")
3905         (const_string "1")))
3906    (set (attr "modrm")
3907      (if_then_else (eq_attr "prefix_0f" "0")
3908         (const_string "0")
3909         (const_string "1")))])
3910
3911 (define_insn "extendqisi2"
3912   [(set (match_operand:SI 0 "register_operand" "=r")
3913         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3914   ""
3915   "movs{bl|x}\t{%1,%0|%0, %1}"
3916    [(set_attr "type" "imovx")
3917     (set_attr "mode" "SI")])
3918
3919 (define_insn "*extendqisi2_zext"
3920   [(set (match_operand:DI 0 "register_operand" "=r")
3921         (zero_extend:DI
3922           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3923   "TARGET_64BIT"
3924   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3925    [(set_attr "type" "imovx")
3926     (set_attr "mode" "SI")])
3927 \f
3928 ;; Conversions between float and double.
3929
3930 ;; These are all no-ops in the model used for the 80387.  So just
3931 ;; emit moves.
3932
3933 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3934 (define_insn "*dummy_extendsfdf2"
3935   [(set (match_operand:DF 0 "push_operand" "=<")
3936         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3937   "0"
3938   "#")
3939
3940 (define_split
3941   [(set (match_operand:DF 0 "push_operand" "")
3942         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3943   "!TARGET_64BIT"
3944   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3945    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
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:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3952    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3953
3954 (define_insn "*dummy_extendsfxf2"
3955   [(set (match_operand:XF 0 "push_operand" "=<")
3956         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3957   "0"
3958   "#")
3959
3960 (define_split
3961   [(set (match_operand:XF 0 "push_operand" "")
3962         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3963   ""
3964   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3965    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3966   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3967
3968 (define_split
3969   [(set (match_operand:XF 0 "push_operand" "")
3970         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3971   "TARGET_64BIT"
3972   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3973    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3974   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3975
3976 (define_split
3977   [(set (match_operand:XF 0 "push_operand" "")
3978         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3979   ""
3980   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3981    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3982   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3983
3984 (define_split
3985   [(set (match_operand:XF 0 "push_operand" "")
3986         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3987   "TARGET_64BIT"
3988   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3989    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3990   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3991
3992 (define_expand "extendsfdf2"
3993   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3994         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3995   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3996 {
3997   /* ??? Needed for compress_float_constant since all fp constants
3998      are LEGITIMATE_CONSTANT_P.  */
3999   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4000     {
4001       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4002           && standard_80387_constant_p (operands[1]) > 0)
4003         {
4004           operands[1] = simplify_const_unary_operation
4005             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4006           emit_move_insn_1 (operands[0], operands[1]);
4007           DONE;
4008         }
4009       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4010     }
4011 })
4012
4013 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4014    cvtss2sd:
4015       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4016       cvtps2pd xmm2,xmm1
4017    We do the conversion post reload to avoid producing of 128bit spills
4018    that might lead to ICE on 32bit target.  The sequence unlikely combine
4019    anyway.  */
4020 (define_split
4021   [(set (match_operand:DF 0 "register_operand" "")
4022         (float_extend:DF
4023           (match_operand:SF 1 "nonimmediate_operand" "")))]
4024   "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4025    && reload_completed && SSE_REG_P (operands[0])"
4026    [(set (match_dup 2)
4027          (float_extend:V2DF
4028            (vec_select:V2SF
4029              (match_dup 3)
4030              (parallel [(const_int 0) (const_int 1)]))))]
4031 {
4032   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4033   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4034   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4035      Try to avoid move when unpacking can be done in source.  */
4036   if (REG_P (operands[1]))
4037     {
4038       /* If it is unsafe to overwrite upper half of source, we need
4039          to move to destination and unpack there.  */
4040       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4041            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4042           && true_regnum (operands[0]) != true_regnum (operands[1]))
4043         {
4044           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4045           emit_move_insn (tmp, operands[1]);
4046         }
4047       else
4048         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4049       emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4050     }
4051   else
4052     emit_insn (gen_vec_setv4sf_0 (operands[3],
4053                                   CONST0_RTX (V4SFmode), operands[1]));
4054 })
4055
4056 (define_insn "*extendsfdf2_mixed"
4057   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4058         (float_extend:DF
4059           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4060   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4061 {
4062   switch (which_alternative)
4063     {
4064     case 0:
4065     case 1:
4066       return output_387_reg_move (insn, operands);
4067
4068     case 2:
4069       return "cvtss2sd\t{%1, %0|%0, %1}";
4070
4071     default:
4072       gcc_unreachable ();
4073     }
4074 }
4075   [(set_attr "type" "fmov,fmov,ssecvt")
4076    (set_attr "mode" "SF,XF,DF")])
4077
4078 (define_insn "*extendsfdf2_sse"
4079   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4080         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4081   "TARGET_SSE2 && TARGET_SSE_MATH"
4082   "cvtss2sd\t{%1, %0|%0, %1}"
4083   [(set_attr "type" "ssecvt")
4084    (set_attr "mode" "DF")])
4085
4086 (define_insn "*extendsfdf2_i387"
4087   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4088         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4089   "TARGET_80387"
4090   "* return output_387_reg_move (insn, operands);"
4091   [(set_attr "type" "fmov")
4092    (set_attr "mode" "SF,XF")])
4093
4094 (define_expand "extend<mode>xf2"
4095   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4096         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4097   "TARGET_80387"
4098 {
4099   /* ??? Needed for compress_float_constant since all fp constants
4100      are LEGITIMATE_CONSTANT_P.  */
4101   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4102     {
4103       if (standard_80387_constant_p (operands[1]) > 0)
4104         {
4105           operands[1] = simplify_const_unary_operation
4106             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4107           emit_move_insn_1 (operands[0], operands[1]);
4108           DONE;
4109         }
4110       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4111     }
4112 })
4113
4114 (define_insn "*extend<mode>xf2_i387"
4115   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4116         (float_extend:XF
4117           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4118   "TARGET_80387"
4119   "* return output_387_reg_move (insn, operands);"
4120   [(set_attr "type" "fmov")
4121    (set_attr "mode" "<MODE>,XF")])
4122
4123 ;; %%% This seems bad bad news.
4124 ;; This cannot output into an f-reg because there is no way to be sure
4125 ;; of truncating in that case.  Otherwise this is just like a simple move
4126 ;; insn.  So we pretend we can output to a reg in order to get better
4127 ;; register preferencing, but we really use a stack slot.
4128
4129 ;; Conversion from DFmode to SFmode.
4130
4131 (define_expand "truncdfsf2"
4132   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4133         (float_truncate:SF
4134           (match_operand:DF 1 "nonimmediate_operand" "")))]
4135   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4136 {
4137   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4138     ;
4139   else if (flag_unsafe_math_optimizations)
4140     ;
4141   else
4142     {
4143       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4144       rtx temp = assign_386_stack_local (SFmode, slot);
4145       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4146       DONE;
4147     }
4148 })
4149
4150 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4151    cvtsd2ss:
4152       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4153       cvtpd2ps xmm2,xmm1
4154    We do the conversion post reload to avoid producing of 128bit spills
4155    that might lead to ICE on 32bit target.  The sequence unlikely combine
4156    anyway.  */
4157 (define_split
4158   [(set (match_operand:SF 0 "register_operand" "")
4159         (float_truncate:SF
4160           (match_operand:DF 1 "nonimmediate_operand" "")))]
4161   "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4162    && reload_completed && SSE_REG_P (operands[0])"
4163    [(set (match_dup 2)
4164          (vec_concat:V4SF
4165            (float_truncate:V2SF
4166              (match_dup 4))
4167            (match_dup 3)))]
4168 {
4169   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4170   operands[3] = CONST0_RTX (V2SFmode);
4171   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4172   /* Use movsd for loading from memory, unpcklpd for registers.
4173      Try to avoid move when unpacking can be done in source, or SSE3
4174      movddup is available.  */
4175   if (REG_P (operands[1]))
4176     {
4177       if (!TARGET_SSE3
4178           && true_regnum (operands[0]) != true_regnum (operands[1])
4179           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4180               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4181         {
4182           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4183           emit_move_insn (tmp, operands[1]);
4184           operands[1] = tmp;
4185         }
4186       else if (!TARGET_SSE3)
4187         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4188       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4189     }
4190   else
4191     emit_insn (gen_sse2_loadlpd (operands[4],
4192                                  CONST0_RTX (V2DFmode), operands[1]));
4193 })
4194
4195 (define_expand "truncdfsf2_with_temp"
4196   [(parallel [(set (match_operand:SF 0 "" "")
4197                    (float_truncate:SF (match_operand:DF 1 "" "")))
4198               (clobber (match_operand:SF 2 "" ""))])]
4199   "")
4200
4201 (define_insn "*truncdfsf_fast_mixed"
4202   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,x")
4203         (float_truncate:SF
4204           (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
4205   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4206 {
4207   switch (which_alternative)
4208     {
4209     case 0:
4210     case 1:
4211       return output_387_reg_move (insn, operands);
4212     case 2:
4213       return "cvtsd2ss\t{%1, %0|%0, %1}";
4214     default:
4215       gcc_unreachable ();
4216     }
4217 }
4218   [(set_attr "type" "fmov,fmov,ssecvt")
4219    (set_attr "mode" "SF")])
4220
4221 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4222 ;; because nothing we do here is unsafe.
4223 (define_insn "*truncdfsf_fast_sse"
4224   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4225         (float_truncate:SF
4226           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4227   "TARGET_SSE2 && TARGET_SSE_MATH"
4228   "cvtsd2ss\t{%1, %0|%0, %1}"
4229   [(set_attr "type" "ssecvt")
4230    (set_attr "mode" "SF")])
4231
4232 (define_insn "*truncdfsf_fast_i387"
4233   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4234         (float_truncate:SF
4235           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4236   "TARGET_80387 && flag_unsafe_math_optimizations"
4237   "* return output_387_reg_move (insn, operands);"
4238   [(set_attr "type" "fmov")
4239    (set_attr "mode" "SF")])
4240
4241 (define_insn "*truncdfsf_mixed"
4242   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y2")
4243         (float_truncate:SF
4244           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Y2m")))
4245    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
4246   "TARGET_MIX_SSE_I387"
4247 {
4248   switch (which_alternative)
4249     {
4250     case 0:
4251       return output_387_reg_move (insn, operands);
4252
4253     case 1:
4254       return "#";
4255     case 2:
4256       return "cvtsd2ss\t{%1, %0|%0, %1}";
4257     default:
4258       gcc_unreachable ();
4259     }
4260 }
4261   [(set_attr "type" "fmov,multi,ssecvt")
4262    (set_attr "unit" "*,i387,*")
4263    (set_attr "mode" "SF")])
4264
4265 (define_insn "*truncdfsf_i387"
4266   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4267         (float_truncate:SF
4268           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4269    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4270   "TARGET_80387"
4271 {
4272   switch (which_alternative)
4273     {
4274     case 0:
4275       return output_387_reg_move (insn, operands);
4276
4277     case 1:
4278       return "#";
4279     default:
4280       gcc_unreachable ();
4281     }
4282 }
4283   [(set_attr "type" "fmov,multi")
4284    (set_attr "unit" "*,i387")
4285    (set_attr "mode" "SF")])
4286
4287 (define_insn "*truncdfsf2_i387_1"
4288   [(set (match_operand:SF 0 "memory_operand" "=m")
4289         (float_truncate:SF
4290           (match_operand:DF 1 "register_operand" "f")))]
4291   "TARGET_80387
4292    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4293    && !TARGET_MIX_SSE_I387"
4294   "* return output_387_reg_move (insn, operands);"
4295   [(set_attr "type" "fmov")
4296    (set_attr "mode" "SF")])
4297
4298 (define_split
4299   [(set (match_operand:SF 0 "register_operand" "")
4300         (float_truncate:SF
4301          (match_operand:DF 1 "fp_register_operand" "")))
4302    (clobber (match_operand 2 "" ""))]
4303   "reload_completed"
4304   [(set (match_dup 2) (match_dup 1))
4305    (set (match_dup 0) (match_dup 2))]
4306 {
4307   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4308 })
4309
4310 ;; Conversion from XFmode to {SF,DF}mode
4311
4312 (define_expand "truncxf<mode>2"
4313   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4314                    (float_truncate:MODEF
4315                      (match_operand:XF 1 "register_operand" "")))
4316               (clobber (match_dup 2))])]
4317   "TARGET_80387"
4318 {
4319   if (flag_unsafe_math_optimizations)
4320     {
4321       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4322       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4323       if (reg != operands[0])
4324         emit_move_insn (operands[0], reg);
4325       DONE;
4326     }
4327   else
4328     {
4329       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4330       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4331     }
4332 })
4333
4334 (define_insn "*truncxfsf2_mixed"
4335   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4336         (float_truncate:SF
4337           (match_operand:XF 1 "register_operand" "f,f")))
4338    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4339   "TARGET_80387"
4340 {
4341   gcc_assert (!which_alternative);
4342   return output_387_reg_move (insn, operands);
4343 }
4344   [(set_attr "type" "fmov,multi")
4345    (set_attr "unit" "*,i387")
4346    (set_attr "mode" "SF")])
4347
4348 (define_insn "*truncxfdf2_mixed"
4349   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4350         (float_truncate:DF
4351           (match_operand:XF 1 "register_operand" "f,f")))
4352    (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4353   "TARGET_80387"
4354 {
4355   gcc_assert (!which_alternative);
4356   return output_387_reg_move (insn, operands);
4357 }
4358   [(set_attr "type" "fmov,multi")
4359    (set_attr "unit" "*,i387")
4360    (set_attr "mode" "DF")])
4361
4362 (define_insn "truncxf<mode>2_i387_noop"
4363   [(set (match_operand:MODEF 0 "register_operand" "=f")
4364         (float_truncate:MODEF
4365           (match_operand:XF 1 "register_operand" "f")))]
4366   "TARGET_80387 && flag_unsafe_math_optimizations"
4367   "* return output_387_reg_move (insn, operands);"
4368   [(set_attr "type" "fmov")
4369    (set_attr "mode" "<MODE>")])
4370
4371 (define_insn "*truncxf<mode>2_i387"
4372   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4373         (float_truncate:MODEF
4374           (match_operand:XF 1 "register_operand" "f")))]
4375   "TARGET_80387"
4376   "* return output_387_reg_move (insn, operands);"
4377   [(set_attr "type" "fmov")
4378    (set_attr "mode" "<MODE>")])
4379
4380 (define_split
4381   [(set (match_operand:MODEF 0 "register_operand" "")
4382         (float_truncate:MODEF
4383           (match_operand:XF 1 "register_operand" "")))
4384    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4385   "TARGET_80387 && reload_completed"
4386   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4387    (set (match_dup 0) (match_dup 2))]
4388   "")
4389
4390 (define_split
4391   [(set (match_operand:MODEF 0 "memory_operand" "")
4392         (float_truncate:MODEF
4393           (match_operand:XF 1 "register_operand" "")))
4394    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4395   "TARGET_80387"
4396   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4397   "")
4398 \f
4399 ;; Signed conversion to DImode.
4400
4401 (define_expand "fix_truncxfdi2"
4402   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4403                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4404               (clobber (reg:CC FLAGS_REG))])]
4405   "TARGET_80387"
4406 {
4407   if (TARGET_FISTTP)
4408    {
4409      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4410      DONE;
4411    }
4412 })
4413
4414 (define_expand "fix_trunc<mode>di2"
4415   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4416                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4417               (clobber (reg:CC FLAGS_REG))])]
4418   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4419 {
4420   if (TARGET_FISTTP
4421       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4422    {
4423      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4424      DONE;
4425    }
4426   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4427    {
4428      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4429      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4430      if (out != operands[0])
4431         emit_move_insn (operands[0], out);
4432      DONE;
4433    }
4434 })
4435
4436 ;; Signed conversion to SImode.
4437
4438 (define_expand "fix_truncxfsi2"
4439   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4440                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4441               (clobber (reg:CC FLAGS_REG))])]
4442   "TARGET_80387"
4443 {
4444   if (TARGET_FISTTP)
4445    {
4446      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4447      DONE;
4448    }
4449 })
4450
4451 (define_expand "fix_trunc<mode>si2"
4452   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4453                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4454               (clobber (reg:CC FLAGS_REG))])]
4455   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4456 {
4457   if (TARGET_FISTTP
4458       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4459    {
4460      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4461      DONE;
4462    }
4463   if (SSE_FLOAT_MODE_P (<MODE>mode))
4464    {
4465      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4466      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4467      if (out != operands[0])
4468         emit_move_insn (operands[0], out);
4469      DONE;
4470    }
4471 })
4472
4473 ;; Signed conversion to HImode.
4474
4475 (define_expand "fix_trunc<mode>hi2"
4476   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4477                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4478               (clobber (reg:CC FLAGS_REG))])]
4479   "TARGET_80387
4480    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4481 {
4482   if (TARGET_FISTTP)
4483    {
4484      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4485      DONE;
4486    }
4487 })
4488
4489 ;; Unsigned conversion to SImode.
4490
4491 (define_expand "fixuns_trunc<mode>si2"
4492   [(parallel
4493     [(set (match_operand:SI 0 "register_operand" "")
4494           (unsigned_fix:SI
4495             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4496      (use (match_dup 2))
4497      (clobber (match_scratch:<ssevecmode> 3 ""))
4498      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4499   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4500 {
4501   enum machine_mode mode = <MODE>mode;
4502   enum machine_mode vecmode = <ssevecmode>mode;
4503   REAL_VALUE_TYPE TWO31r;
4504   rtx two31;
4505
4506   real_ldexp (&TWO31r, &dconst1, 31);
4507   two31 = const_double_from_real_value (TWO31r, mode);
4508   two31 = ix86_build_const_vector (mode, true, two31);
4509   operands[2] = force_reg (vecmode, two31);
4510 })
4511
4512 (define_insn_and_split "*fixuns_trunc<mode>_1"
4513   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4514         (unsigned_fix:SI
4515           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4516    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4517    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4518    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4519   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4520   "#"
4521   "&& reload_completed"
4522   [(const_int 0)]
4523 {
4524   ix86_split_convert_uns_si_sse (operands);
4525   DONE;
4526 })
4527
4528 ;; Unsigned conversion to HImode.
4529 ;; Without these patterns, we'll try the unsigned SI conversion which
4530 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4531
4532 (define_expand "fixuns_trunc<mode>hi2"
4533   [(set (match_dup 2)
4534         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4535    (set (match_operand:HI 0 "nonimmediate_operand" "")
4536         (subreg:HI (match_dup 2) 0))]
4537   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4538   "operands[2] = gen_reg_rtx (SImode);")
4539
4540 ;; When SSE is available, it is always faster to use it!
4541 (define_insn "fix_trunc<mode>di_sse"
4542   [(set (match_operand:DI 0 "register_operand" "=r,r")
4543         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4544   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4545    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4546   "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4547   [(set_attr "type" "sseicvt")
4548    (set_attr "mode" "<MODE>")
4549    (set_attr "athlon_decode" "double,vector")
4550    (set_attr "amdfam10_decode" "double,double")])
4551
4552 (define_insn "fix_trunc<mode>si_sse"
4553   [(set (match_operand:SI 0 "register_operand" "=r,r")
4554         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4555   "SSE_FLOAT_MODE_P (<MODE>mode)
4556    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4557   "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4558   [(set_attr "type" "sseicvt")
4559    (set_attr "mode" "<MODE>")
4560    (set_attr "athlon_decode" "double,vector")
4561    (set_attr "amdfam10_decode" "double,double")])
4562
4563 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4564 (define_peephole2
4565   [(set (match_operand:MODEF 0 "register_operand" "")
4566         (match_operand:MODEF 1 "memory_operand" ""))
4567    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4568         (fix:SSEMODEI24 (match_dup 0)))]
4569   "TARGET_SHORTEN_X87_SSE
4570    && peep2_reg_dead_p (2, operands[0])"
4571   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4572   "")
4573
4574 ;; Avoid vector decoded forms of the instruction.
4575 (define_peephole2
4576   [(match_scratch:DF 2 "Y2")
4577    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4578         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4579   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4580   [(set (match_dup 2) (match_dup 1))
4581    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4582   "")
4583
4584 (define_peephole2
4585   [(match_scratch:SF 2 "x")
4586    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4587         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4588   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4589   [(set (match_dup 2) (match_dup 1))
4590    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4591   "")
4592
4593 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4594   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4595         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4596   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4597    && TARGET_FISTTP
4598    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4599          && (TARGET_64BIT || <MODE>mode != DImode))
4600         && TARGET_SSE_MATH)
4601    && !(reload_completed || reload_in_progress)"
4602   "#"
4603   "&& 1"
4604   [(const_int 0)]
4605 {
4606   if (memory_operand (operands[0], VOIDmode))
4607     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4608   else
4609     {
4610       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4611       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4612                                                             operands[1],
4613                                                             operands[2]));
4614     }
4615   DONE;
4616 }
4617   [(set_attr "type" "fisttp")
4618    (set_attr "mode" "<MODE>")])
4619
4620 (define_insn "fix_trunc<mode>_i387_fisttp"
4621   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4622         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4623    (clobber (match_scratch:XF 2 "=&1f"))]
4624   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4625    && TARGET_FISTTP
4626    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4627          && (TARGET_64BIT || <MODE>mode != DImode))
4628         && TARGET_SSE_MATH)"
4629   "* return output_fix_trunc (insn, operands, 1);"
4630   [(set_attr "type" "fisttp")
4631    (set_attr "mode" "<MODE>")])
4632
4633 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4634   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4635         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4636    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4637    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4638   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4639    && TARGET_FISTTP
4640    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4641         && (TARGET_64BIT || <MODE>mode != DImode))
4642         && TARGET_SSE_MATH)"
4643   "#"
4644   [(set_attr "type" "fisttp")
4645    (set_attr "mode" "<MODE>")])
4646
4647 (define_split
4648   [(set (match_operand:X87MODEI 0 "register_operand" "")
4649         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4650    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4651    (clobber (match_scratch 3 ""))]
4652   "reload_completed"
4653   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4654               (clobber (match_dup 3))])
4655    (set (match_dup 0) (match_dup 2))]
4656   "")
4657
4658 (define_split
4659   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4660         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4661    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4662    (clobber (match_scratch 3 ""))]
4663   "reload_completed"
4664   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4665               (clobber (match_dup 3))])]
4666   "")
4667
4668 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4669 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4670 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4671 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4672 ;; function in i386.c.
4673 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4674   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4675         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4676    (clobber (reg:CC FLAGS_REG))]
4677   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4678    && !TARGET_FISTTP
4679    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4680          && (TARGET_64BIT || <MODE>mode != DImode))
4681    && !(reload_completed || reload_in_progress)"
4682   "#"
4683   "&& 1"
4684   [(const_int 0)]
4685 {
4686   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4687
4688   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4689   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4690   if (memory_operand (operands[0], VOIDmode))
4691     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4692                                          operands[2], operands[3]));
4693   else
4694     {
4695       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4696       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4697                                                      operands[2], operands[3],
4698                                                      operands[4]));
4699     }
4700   DONE;
4701 }
4702   [(set_attr "type" "fistp")
4703    (set_attr "i387_cw" "trunc")
4704    (set_attr "mode" "<MODE>")])
4705
4706 (define_insn "fix_truncdi_i387"
4707   [(set (match_operand:DI 0 "memory_operand" "=m")
4708         (fix:DI (match_operand 1 "register_operand" "f")))
4709    (use (match_operand:HI 2 "memory_operand" "m"))
4710    (use (match_operand:HI 3 "memory_operand" "m"))
4711    (clobber (match_scratch:XF 4 "=&1f"))]
4712   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4713    && !TARGET_FISTTP
4714    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4715   "* return output_fix_trunc (insn, operands, 0);"
4716   [(set_attr "type" "fistp")
4717    (set_attr "i387_cw" "trunc")
4718    (set_attr "mode" "DI")])
4719
4720 (define_insn "fix_truncdi_i387_with_temp"
4721   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4722         (fix:DI (match_operand 1 "register_operand" "f,f")))
4723    (use (match_operand:HI 2 "memory_operand" "m,m"))
4724    (use (match_operand:HI 3 "memory_operand" "m,m"))
4725    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4726    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4727   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4728    && !TARGET_FISTTP
4729    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4730   "#"
4731   [(set_attr "type" "fistp")
4732    (set_attr "i387_cw" "trunc")
4733    (set_attr "mode" "DI")])
4734
4735 (define_split
4736   [(set (match_operand:DI 0 "register_operand" "")
4737         (fix:DI (match_operand 1 "register_operand" "")))
4738    (use (match_operand:HI 2 "memory_operand" ""))
4739    (use (match_operand:HI 3 "memory_operand" ""))
4740    (clobber (match_operand:DI 4 "memory_operand" ""))
4741    (clobber (match_scratch 5 ""))]
4742   "reload_completed"
4743   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4744               (use (match_dup 2))
4745               (use (match_dup 3))
4746               (clobber (match_dup 5))])
4747    (set (match_dup 0) (match_dup 4))]
4748   "")
4749
4750 (define_split
4751   [(set (match_operand:DI 0 "memory_operand" "")
4752         (fix:DI (match_operand 1 "register_operand" "")))
4753    (use (match_operand:HI 2 "memory_operand" ""))
4754    (use (match_operand:HI 3 "memory_operand" ""))
4755    (clobber (match_operand:DI 4 "memory_operand" ""))
4756    (clobber (match_scratch 5 ""))]
4757   "reload_completed"
4758   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4759               (use (match_dup 2))
4760               (use (match_dup 3))
4761               (clobber (match_dup 5))])]
4762   "")
4763
4764 (define_insn "fix_trunc<mode>_i387"
4765   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4766         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4767    (use (match_operand:HI 2 "memory_operand" "m"))
4768    (use (match_operand:HI 3 "memory_operand" "m"))]
4769   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4770    && !TARGET_FISTTP
4771    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4772   "* return output_fix_trunc (insn, operands, 0);"
4773   [(set_attr "type" "fistp")
4774    (set_attr "i387_cw" "trunc")
4775    (set_attr "mode" "<MODE>")])
4776
4777 (define_insn "fix_trunc<mode>_i387_with_temp"
4778   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4779         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4780    (use (match_operand:HI 2 "memory_operand" "m,m"))
4781    (use (match_operand:HI 3 "memory_operand" "m,m"))
4782    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4783   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4784    && !TARGET_FISTTP
4785    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4786   "#"
4787   [(set_attr "type" "fistp")
4788    (set_attr "i387_cw" "trunc")
4789    (set_attr "mode" "<MODE>")])
4790
4791 (define_split
4792   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4793         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4794    (use (match_operand:HI 2 "memory_operand" ""))
4795    (use (match_operand:HI 3 "memory_operand" ""))
4796    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4797   "reload_completed"
4798   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4799               (use (match_dup 2))
4800               (use (match_dup 3))])
4801    (set (match_dup 0) (match_dup 4))]
4802   "")
4803
4804 (define_split
4805   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4806         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4807    (use (match_operand:HI 2 "memory_operand" ""))
4808    (use (match_operand:HI 3 "memory_operand" ""))
4809    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4810   "reload_completed"
4811   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4812               (use (match_dup 2))
4813               (use (match_dup 3))])]
4814   "")
4815
4816 (define_insn "x86_fnstcw_1"
4817   [(set (match_operand:HI 0 "memory_operand" "=m")
4818         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4819   "TARGET_80387"
4820   "fnstcw\t%0"
4821   [(set_attr "length" "2")
4822    (set_attr "mode" "HI")
4823    (set_attr "unit" "i387")])
4824
4825 (define_insn "x86_fldcw_1"
4826   [(set (reg:HI FPCR_REG)
4827         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4828   "TARGET_80387"
4829   "fldcw\t%0"
4830   [(set_attr "length" "2")
4831    (set_attr "mode" "HI")
4832    (set_attr "unit" "i387")
4833    (set_attr "athlon_decode" "vector")
4834    (set_attr "amdfam10_decode" "vector")])
4835 \f
4836 ;; Conversion between fixed point and floating point.
4837
4838 ;; Even though we only accept memory inputs, the backend _really_
4839 ;; wants to be able to do this between registers.
4840
4841 (define_expand "floathi<mode>2"
4842   [(set (match_operand:X87MODEF 0 "register_operand" "")
4843         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4844   "TARGET_80387
4845    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4846        || TARGET_MIX_SSE_I387)"
4847   "")
4848
4849 ;; Pre-reload splitter to add memory clobber to the pattern.
4850 (define_insn_and_split "*floathi<mode>2_1"
4851   [(set (match_operand:X87MODEF 0 "register_operand" "")
4852         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4853   "TARGET_80387
4854    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4855        || TARGET_MIX_SSE_I387)
4856    && !(reload_completed || reload_in_progress)"
4857   "#"
4858   "&& 1"
4859   [(parallel [(set (match_dup 0)
4860               (float:X87MODEF (match_dup 1)))
4861    (clobber (match_dup 2))])]
4862   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4863
4864 (define_insn "*floathi<mode>2_i387_with_temp"
4865   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4866         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4867   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4868   "TARGET_80387
4869    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4870        || TARGET_MIX_SSE_I387)"
4871   "#"
4872   [(set_attr "type" "fmov,multi")
4873    (set_attr "mode" "<MODE>")
4874    (set_attr "unit" "*,i387")
4875    (set_attr "fp_int_src" "true")])
4876
4877 (define_insn "*floathi<mode>2_i387"
4878   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4879         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4880   "TARGET_80387
4881    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4882        || TARGET_MIX_SSE_I387)"
4883   "fild%z1\t%1"
4884   [(set_attr "type" "fmov")
4885    (set_attr "mode" "<MODE>")
4886    (set_attr "fp_int_src" "true")])
4887
4888 (define_split
4889   [(set (match_operand:X87MODEF 0 "register_operand" "")
4890         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4891    (clobber (match_operand:HI 2 "memory_operand" ""))]
4892   "TARGET_80387
4893    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4894        || TARGET_MIX_SSE_I387)
4895    && reload_completed"
4896   [(set (match_dup 2) (match_dup 1))
4897    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4898   "")
4899
4900 (define_split
4901   [(set (match_operand:X87MODEF 0 "register_operand" "")
4902         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4903    (clobber (match_operand:HI 2 "memory_operand" ""))]
4904    "TARGET_80387
4905     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4906         || TARGET_MIX_SSE_I387)
4907     && reload_completed"
4908   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
4909   "")
4910
4911 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4912   [(set (match_operand:X87MODEF 0 "register_operand" "")
4913         (float:X87MODEF
4914           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4915   "TARGET_80387
4916    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4917        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4918   "")
4919
4920 ;; Pre-reload splitter to add memory clobber to the pattern.
4921 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4922   [(set (match_operand:X87MODEF 0 "register_operand" "")
4923         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4924   "((TARGET_80387
4925      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4926            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4927          || TARGET_MIX_SSE_I387))
4928     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4929         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4930         && ((<SSEMODEI24:MODE>mode == SImode
4931              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4932              && flag_trapping_math)
4933             || !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size))))
4934    && !(reload_completed || reload_in_progress)"
4935   "#"
4936   "&& 1"
4937   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4938               (clobber (match_dup 2))])]
4939 {
4940   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4941
4942   /* Avoid store forwarding (partial memory) stall penalty
4943      by passing DImode value through XMM registers.  */
4944   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT 
4945       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES 
4946       && !optimize_size)
4947     {
4948       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4949                                                             operands[1],
4950                                                             operands[2]));
4951       DONE;
4952     }
4953 })
4954
4955 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4956   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4957         (float:MODEF
4958           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4959    (clobber (match_operand:SI 2 "memory_operand" "=m,m,m,m,m"))]
4960   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4961    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4962   "#"
4963   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4964    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4965    (set_attr "unit" "*,i387,*,*,*")
4966    (set_attr "athlon_decode" "*,*,double,direct,double")
4967    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4968    (set_attr "fp_int_src" "true")])
4969
4970 (define_insn "*floatsi<mode>2_vector_mixed"
4971   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4972         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4973   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4974    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4975   "@
4976    fild%z1\t%1
4977    #"
4978   [(set_attr "type" "fmov,sseicvt")
4979    (set_attr "mode" "<MODE>,<ssevecmode>")
4980    (set_attr "unit" "i387,*")
4981    (set_attr "athlon_decode" "*,direct")
4982    (set_attr "amdfam10_decode" "*,double")
4983    (set_attr "fp_int_src" "true")])
4984
4985 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
4986   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4987         (float:MODEF
4988           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
4989   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,m,m,m"))]
4990   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4991    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4992   "#"
4993   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4994    (set_attr "mode" "<MODEF:MODE>")
4995    (set_attr "unit" "*,i387,*,*")
4996    (set_attr "athlon_decode" "*,*,double,direct")
4997    (set_attr "amdfam10_decode" "*,*,vector,double")
4998    (set_attr "fp_int_src" "true")])
4999
5000 (define_split
5001   [(set (match_operand:MODEF 0 "register_operand" "")
5002         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5003    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5004   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5005    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5006    && TARGET_INTER_UNIT_CONVERSIONS
5007    && reload_completed
5008    && (SSE_REG_P (operands[0])
5009        || (GET_CODE (operands[0]) == SUBREG
5010            && SSE_REG_P (operands[0])))"
5011   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5012   "")
5013
5014 (define_split
5015   [(set (match_operand:MODEF 0 "register_operand" "")
5016         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5017    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5018   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5019    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5020    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5021    && reload_completed
5022    && (SSE_REG_P (operands[0])
5023        || (GET_CODE (operands[0]) == SUBREG
5024            && SSE_REG_P (operands[0])))"
5025   [(set (match_dup 2) (match_dup 1))
5026    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5027   "")
5028
5029 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5030   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5031         (float:MODEF
5032           (match_operand:SSEMODEI24 1 "register_operand" "m,r,m")))]
5033   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5034    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5035    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5036   "@
5037    fild%z1\t%1
5038    cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}
5039    cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5040   [(set_attr "type" "fmov,sseicvt,sseicvt")
5041    (set_attr "mode" "<MODEF:MODE>")
5042    (set_attr "unit" "i387,*,*")
5043    (set_attr "athlon_decode" "*,double,direct")
5044    (set_attr "amdfam10_decode" "*,vector,double")
5045    (set_attr "fp_int_src" "true")])
5046
5047 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5048   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5049         (float:MODEF
5050           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5051   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5052    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5053    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5054   "@
5055    fild%z1\t%1
5056    cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5057   [(set_attr "type" "fmov,sseicvt")
5058    (set_attr "mode" "<MODEF:MODE>")
5059    (set_attr "athlon_decode" "*,direct")
5060    (set_attr "amdfam10_decode" "*,double")
5061    (set_attr "fp_int_src" "true")])
5062
5063 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5064   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5065         (float:MODEF
5066           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5067    (clobber (match_operand:SI 2 "memory_operand" "=m,m,m"))]
5068   "TARGET_SSE2 && TARGET_SSE_MATH
5069    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5070   "#"
5071   [(set_attr "type" "sseicvt")
5072    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5073    (set_attr "athlon_decode" "double,direct,double")
5074    (set_attr "amdfam10_decode" "vector,double,double")
5075    (set_attr "fp_int_src" "true")])
5076
5077 (define_insn "*floatsi<mode>2_vector_sse"
5078   [(set (match_operand:MODEF 0 "register_operand" "=x")
5079         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5080   "TARGET_SSE2 && TARGET_SSE_MATH
5081    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5082   "#"
5083   [(set_attr "type" "sseicvt")
5084    (set_attr "mode" "<MODE>")
5085    (set_attr "athlon_decode" "direct")
5086    (set_attr "amdfam10_decode" "double")
5087    (set_attr "fp_int_src" "true")])
5088
5089 (define_split
5090   [(set (match_operand:MODEF 0 "register_operand" "")
5091         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5092    (clobber (match_operand:SI 2 "memory_operand" ""))]
5093   "TARGET_SSE2 && TARGET_SSE_MATH
5094    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5095    && reload_completed
5096    && (SSE_REG_P (operands[0])
5097        || (GET_CODE (operands[0]) == SUBREG
5098            && SSE_REG_P (operands[0])))"
5099   [(const_int 0)]
5100 {
5101   rtx op1 = operands[1];
5102
5103   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5104                                      <MODE>mode, 0);
5105   if (GET_CODE (op1) == SUBREG)
5106     op1 = SUBREG_REG (op1);
5107
5108   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5109     {
5110       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5111       emit_insn (gen_sse2_loadld (operands[4],
5112                                   CONST0_RTX (V4SImode), operands[1]));
5113     }
5114   /* We can ignore possible trapping value in the
5115      high part of SSE register for non-trapping math. */
5116   else if (SSE_REG_P (op1) && !flag_trapping_math)
5117     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5118   else
5119     {
5120       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5121       emit_move_insn (operands[2], operands[1]);
5122       emit_insn (gen_sse2_loadld (operands[4],
5123                                   CONST0_RTX (V4SImode), operands[2]));
5124     }
5125   emit_insn
5126     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5127   DONE;
5128 })
5129
5130 (define_split
5131   [(set (match_operand:MODEF 0 "register_operand" "")
5132         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5133    (clobber (match_operand:SI 2 "memory_operand" ""))]
5134   "TARGET_SSE2 && TARGET_SSE_MATH
5135    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5136    && reload_completed
5137    && (SSE_REG_P (operands[0])
5138        || (GET_CODE (operands[0]) == SUBREG
5139            && SSE_REG_P (operands[0])))"
5140   [(const_int 0)]
5141 {
5142   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5143                                      <MODE>mode, 0);
5144   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5145
5146   emit_insn (gen_sse2_loadld (operands[4],
5147                               CONST0_RTX (V4SImode), operands[1]));
5148   emit_insn
5149     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5150   DONE;
5151 })
5152
5153 (define_split
5154   [(set (match_operand:MODEF 0 "register_operand" "")
5155         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5156   "TARGET_SSE2 && TARGET_SSE_MATH
5157    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5158    && reload_completed
5159    && (SSE_REG_P (operands[0])
5160        || (GET_CODE (operands[0]) == SUBREG
5161            && SSE_REG_P (operands[0])))"
5162   [(const_int 0)]
5163 {
5164   rtx op1 = operands[1];
5165
5166   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5167                                      <MODE>mode, 0);
5168   if (GET_CODE (op1) == SUBREG)
5169     op1 = SUBREG_REG (op1);
5170
5171   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5172     {
5173       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5174       emit_insn (gen_sse2_loadld (operands[4],
5175                                   CONST0_RTX (V4SImode), operands[1]));
5176     }
5177   /* We can ignore possible trapping value in the
5178      high part of SSE register for non-trapping math. */
5179   else if (SSE_REG_P (op1) && !flag_trapping_math)
5180     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5181   else
5182     gcc_unreachable ();
5183 })
5184
5185 (define_split
5186   [(set (match_operand:MODEF 0 "register_operand" "")
5187         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5188   "TARGET_SSE2 && TARGET_SSE_MATH
5189    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5190    && reload_completed
5191    && (SSE_REG_P (operands[0])
5192        || (GET_CODE (operands[0]) == SUBREG
5193            && SSE_REG_P (operands[0])))"
5194   [(const_int 0)]
5195 {
5196   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5197                                      <MODE>mode, 0);
5198   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5199
5200   emit_insn (gen_sse2_loadld (operands[4],
5201                               CONST0_RTX (V4SImode), operands[1]));
5202   emit_insn
5203     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5204   DONE;
5205 })
5206
5207 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5208   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5209         (float:MODEF
5210           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5211   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,m"))]
5212   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5213    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5214   "#"
5215   [(set_attr "type" "sseicvt")
5216    (set_attr "mode" "<MODEF:MODE>")
5217    (set_attr "athlon_decode" "double,direct")
5218    (set_attr "amdfam10_decode" "vector,double")
5219    (set_attr "fp_int_src" "true")])
5220
5221 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5222   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5223         (float:MODEF
5224           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5225   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5226    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5227    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5228   "@
5229    cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}
5230    cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5231   [(set_attr "type" "sseicvt")
5232    (set_attr "mode" "<MODEF:MODE>")
5233    (set_attr "athlon_decode" "double,direct")
5234    (set_attr "amdfam10_decode" "vector,double")
5235    (set_attr "fp_int_src" "true")])
5236
5237 (define_split
5238   [(set (match_operand:MODEF 0 "register_operand" "")
5239         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5240    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5241   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5242    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5243    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5244    && reload_completed
5245    && (SSE_REG_P (operands[0])
5246        || (GET_CODE (operands[0]) == SUBREG
5247            && SSE_REG_P (operands[0])))"
5248   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5249   "")
5250
5251 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5252   [(set (match_operand:MODEF 0 "register_operand" "=x")
5253         (float:MODEF
5254           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5255   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5256    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5257    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5258   "cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5259   [(set_attr "type" "sseicvt")
5260    (set_attr "mode" "<MODEF:MODE>")
5261    (set_attr "athlon_decode" "direct")
5262    (set_attr "amdfam10_decode" "double")
5263    (set_attr "fp_int_src" "true")])
5264
5265 (define_split
5266   [(set (match_operand:MODEF 0 "register_operand" "")
5267         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5268    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5269   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5270    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5271    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5272    && reload_completed
5273    && (SSE_REG_P (operands[0])
5274        || (GET_CODE (operands[0]) == SUBREG
5275            && SSE_REG_P (operands[0])))"
5276   [(set (match_dup 2) (match_dup 1))
5277    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5278   "")
5279
5280 (define_split
5281   [(set (match_operand:MODEF 0 "register_operand" "")
5282         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5283    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5284   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5285    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5286    && reload_completed
5287    && (SSE_REG_P (operands[0])
5288        || (GET_CODE (operands[0]) == SUBREG
5289            && SSE_REG_P (operands[0])))"
5290   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5291   "")
5292
5293 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5294   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5295         (float:X87MODEF
5296           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5297   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,m"))]
5298   "TARGET_80387"
5299   "@
5300    fild%z1\t%1
5301    #"
5302   [(set_attr "type" "fmov,multi")
5303    (set_attr "mode" "<X87MODEF:MODE>")
5304    (set_attr "unit" "*,i387")
5305    (set_attr "fp_int_src" "true")])
5306
5307 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5308   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5309         (float:X87MODEF
5310           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5311   "TARGET_80387"
5312   "fild%z1\t%1"
5313   [(set_attr "type" "fmov")
5314    (set_attr "mode" "<X87MODEF:MODE>")
5315    (set_attr "fp_int_src" "true")])
5316
5317 (define_split
5318   [(set (match_operand:X87MODEF 0 "register_operand" "")
5319         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5320    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5321   "TARGET_80387
5322    && reload_completed
5323    && FP_REG_P (operands[0])"
5324   [(set (match_dup 2) (match_dup 1))
5325    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5326   "")
5327
5328 (define_split
5329   [(set (match_operand:X87MODEF 0 "register_operand" "")
5330         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5331    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5332   "TARGET_80387
5333    && reload_completed
5334    && FP_REG_P (operands[0])"
5335   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5336   "")
5337
5338 ;; Avoid store forwarding (partial memory) stall penalty
5339 ;; by passing DImode value through XMM registers.  */
5340
5341 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5342   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5343         (float:X87MODEF
5344           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5345    (clobber (match_scratch:V4SI 3 "=&x,x"))
5346    (clobber (match_scratch:V4SI 4 "=&x,x"))
5347    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))]
5348   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5349    && !TARGET_64BIT && !optimize_size"
5350   "#"
5351   [(set_attr "type" "multi")
5352    (set_attr "mode" "<X87MODEF:MODE>")
5353    (set_attr "unit" "i387")
5354    (set_attr "fp_int_src" "true")])
5355
5356 (define_split
5357   [(set (match_operand:X87MODEF 0 "register_operand" "")
5358         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5359    (clobber (match_operand:V4SI 3 "register_operand" ""))
5360    (clobber (match_operand:V4SI 4 "register_operand" ""))
5361    (clobber (match_operand:DI 2 "memory_operand" ""))]
5362   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5363    && !TARGET_64BIT && !optimize_size
5364    && reload_completed
5365    && FP_REG_P (operands[0])"
5366   [(set (match_dup 2) (match_dup 3))
5367    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5368 {
5369   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5370      Assemble the 64-bit DImode value in an xmm register.  */
5371   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5372                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5373   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5374                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5375   emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5376
5377   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5378 })
5379
5380 (define_split
5381   [(set (match_operand:X87MODEF 0 "register_operand" "")
5382         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5383    (clobber (match_operand:V4SI 2 "register_operand" ""))
5384    (clobber (match_operand:V4SI 3 "register_operand" ""))
5385    (clobber (match_operand:DI 4 "memory_operand" ""))]
5386   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5387    && !TARGET_64BIT && !optimize_size
5388    && reload_completed
5389    && FP_REG_P (operands[0])"
5390   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5391   "")
5392
5393 ;; Avoid store forwarding (partial memory) stall penalty by extending
5394 ;; SImode value to DImode through XMM register instead of pushing two
5395 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5396 ;; targets benefit from this optimization. Also note that fild
5397 ;; loads from memory only.
5398
5399 (define_insn "*floatunssi<mode>2_1"
5400   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5401         (unsigned_float:X87MODEF
5402           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5403    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5404    (clobber (match_scratch:SI 3 "=X,x"))]
5405   "!TARGET_64BIT
5406    && TARGET_80387 && TARGET_SSE"
5407   "#"
5408   [(set_attr "type" "multi")
5409    (set_attr "mode" "<MODE>")])
5410
5411 (define_split
5412   [(set (match_operand:X87MODEF 0 "register_operand" "")
5413         (unsigned_float:X87MODEF
5414           (match_operand:SI 1 "register_operand" "")))
5415    (clobber (match_operand:DI 2 "memory_operand" ""))
5416    (clobber (match_scratch:SI 3 ""))]
5417   "!TARGET_64BIT
5418    && TARGET_80387 && TARGET_SSE
5419    && reload_completed"
5420   [(set (match_dup 2) (match_dup 1))
5421    (set (match_dup 0)
5422         (float:X87MODEF (match_dup 2)))]
5423   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5424
5425 (define_split
5426   [(set (match_operand:X87MODEF 0 "register_operand" "")
5427         (unsigned_float:X87MODEF
5428           (match_operand:SI 1 "memory_operand" "")))
5429    (clobber (match_operand:DI 2 "memory_operand" ""))
5430    (clobber (match_scratch:SI 3 ""))]
5431   "!TARGET_64BIT
5432    && TARGET_80387 && TARGET_SSE
5433    && reload_completed"
5434   [(set (match_dup 2) (match_dup 3))
5435    (set (match_dup 0)
5436         (float:X87MODEF (match_dup 2)))]
5437 {
5438   emit_move_insn (operands[3], operands[1]);
5439   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5440 })
5441
5442 (define_expand "floatunssi<mode>2"
5443   [(parallel
5444      [(set (match_operand:X87MODEF 0 "register_operand" "")
5445            (unsigned_float:X87MODEF
5446              (match_operand:SI 1 "nonimmediate_operand" "")))
5447       (clobber (match_dup 2))
5448       (clobber (match_scratch:SI 3 ""))])]
5449   "!TARGET_64BIT
5450    && ((TARGET_80387 && TARGET_SSE)
5451        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5452 {
5453   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5454     {
5455       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5456       DONE;
5457     }
5458   else
5459     {
5460       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5461       operands[2] = assign_386_stack_local (DImode, slot);
5462     }
5463 })
5464
5465 (define_expand "floatunsdisf2"
5466   [(use (match_operand:SF 0 "register_operand" ""))
5467    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5468   "TARGET_64BIT && TARGET_SSE_MATH"
5469   "x86_emit_floatuns (operands); DONE;")
5470
5471 (define_expand "floatunsdidf2"
5472   [(use (match_operand:DF 0 "register_operand" ""))
5473    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5474   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5475    && TARGET_SSE2 && TARGET_SSE_MATH"
5476 {
5477   if (TARGET_64BIT)
5478     x86_emit_floatuns (operands);
5479   else
5480     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5481   DONE;
5482 })
5483 \f
5484 ;; Add instructions
5485
5486 ;; %%% splits for addditi3
5487
5488 (define_expand "addti3"
5489   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5490         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5491                  (match_operand:TI 2 "x86_64_general_operand" "")))
5492    (clobber (reg:CC FLAGS_REG))]
5493   "TARGET_64BIT"
5494   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5495
5496 (define_insn "*addti3_1"
5497   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5498         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5499                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5500    (clobber (reg:CC FLAGS_REG))]
5501   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5502   "#")
5503
5504 (define_split
5505   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5506         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5507                  (match_operand:TI 2 "x86_64_general_operand" "")))
5508    (clobber (reg:CC FLAGS_REG))]
5509   "TARGET_64BIT && reload_completed"
5510   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5511                                           UNSPEC_ADD_CARRY))
5512               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5513    (parallel [(set (match_dup 3)
5514                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5515                                      (match_dup 4))
5516                             (match_dup 5)))
5517               (clobber (reg:CC FLAGS_REG))])]
5518   "split_ti (operands+0, 1, operands+0, operands+3);
5519    split_ti (operands+1, 1, operands+1, operands+4);
5520    split_ti (operands+2, 1, operands+2, operands+5);")
5521
5522 ;; %%% splits for addsidi3
5523 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5524 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5525 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5526
5527 (define_expand "adddi3"
5528   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5529         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5530                  (match_operand:DI 2 "x86_64_general_operand" "")))
5531    (clobber (reg:CC FLAGS_REG))]
5532   ""
5533   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5534
5535 (define_insn "*adddi3_1"
5536   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5537         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5538                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5539    (clobber (reg:CC FLAGS_REG))]
5540   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5541   "#")
5542
5543 (define_split
5544   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5545         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5546                  (match_operand:DI 2 "general_operand" "")))
5547    (clobber (reg:CC FLAGS_REG))]
5548   "!TARGET_64BIT && reload_completed"
5549   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5550                                           UNSPEC_ADD_CARRY))
5551               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5552    (parallel [(set (match_dup 3)
5553                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5554                                      (match_dup 4))
5555                             (match_dup 5)))
5556               (clobber (reg:CC FLAGS_REG))])]
5557   "split_di (operands+0, 1, operands+0, operands+3);
5558    split_di (operands+1, 1, operands+1, operands+4);
5559    split_di (operands+2, 1, operands+2, operands+5);")
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, 1, operands+0, operands+3);
7295    split_ti (operands+1, 1, operands+1, operands+4);
7296    split_ti (operands+2, 1, operands+2, operands+5);")
7297
7298 ;; %%% splits for subsidi3
7299
7300 (define_expand "subdi3"
7301   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
7302                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7303                              (match_operand:DI 2 "x86_64_general_operand" "")))
7304               (clobber (reg:CC FLAGS_REG))])]
7305   ""
7306   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7307
7308 (define_insn "*subdi3_1"
7309   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7310         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7311                   (match_operand:DI 2 "general_operand" "roiF,riF")))
7312    (clobber (reg:CC FLAGS_REG))]
7313   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7314   "#")
7315
7316 (define_split
7317   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7318         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7319                   (match_operand:DI 2 "general_operand" "")))
7320    (clobber (reg:CC FLAGS_REG))]
7321   "!TARGET_64BIT && reload_completed"
7322   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7323               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7324    (parallel [(set (match_dup 3)
7325                    (minus:SI (match_dup 4)
7326                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7327                                       (match_dup 5))))
7328               (clobber (reg:CC FLAGS_REG))])]
7329   "split_di (operands+0, 1, operands+0, operands+3);
7330    split_di (operands+1, 1, operands+1, operands+4);
7331    split_di (operands+2, 1, operands+2, operands+5);")
7332
7333 (define_insn "subdi3_carry_rex64"
7334   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7335           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7336             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7337                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7338    (clobber (reg:CC FLAGS_REG))]
7339   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7340   "sbb{q}\t{%2, %0|%0, %2}"
7341   [(set_attr "type" "alu")
7342    (set_attr "pent_pair" "pu")
7343    (set_attr "mode" "DI")])
7344
7345 (define_insn "*subdi_1_rex64"
7346   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7347         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7348                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7349    (clobber (reg:CC FLAGS_REG))]
7350   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7351   "sub{q}\t{%2, %0|%0, %2}"
7352   [(set_attr "type" "alu")
7353    (set_attr "mode" "DI")])
7354
7355 (define_insn "*subdi_2_rex64"
7356   [(set (reg FLAGS_REG)
7357         (compare
7358           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7359                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7360           (const_int 0)))
7361    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7362         (minus:DI (match_dup 1) (match_dup 2)))]
7363   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7364    && ix86_binary_operator_ok (MINUS, DImode, operands)"
7365   "sub{q}\t{%2, %0|%0, %2}"
7366   [(set_attr "type" "alu")
7367    (set_attr "mode" "DI")])
7368
7369 (define_insn "*subdi_3_rex63"
7370   [(set (reg FLAGS_REG)
7371         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7372                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7373    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7374         (minus:DI (match_dup 1) (match_dup 2)))]
7375   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7376    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7377   "sub{q}\t{%2, %0|%0, %2}"
7378   [(set_attr "type" "alu")
7379    (set_attr "mode" "DI")])
7380
7381 (define_insn "subqi3_carry"
7382   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7383           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7384             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7385                (match_operand:QI 2 "general_operand" "qi,qm"))))
7386    (clobber (reg:CC FLAGS_REG))]
7387   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7388   "sbb{b}\t{%2, %0|%0, %2}"
7389   [(set_attr "type" "alu")
7390    (set_attr "pent_pair" "pu")
7391    (set_attr "mode" "QI")])
7392
7393 (define_insn "subhi3_carry"
7394   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7395           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7396             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7397                (match_operand:HI 2 "general_operand" "ri,rm"))))
7398    (clobber (reg:CC FLAGS_REG))]
7399   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7400   "sbb{w}\t{%2, %0|%0, %2}"
7401   [(set_attr "type" "alu")
7402    (set_attr "pent_pair" "pu")
7403    (set_attr "mode" "HI")])
7404
7405 (define_insn "subsi3_carry"
7406   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7407           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7408             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7409                (match_operand:SI 2 "general_operand" "ri,rm"))))
7410    (clobber (reg:CC FLAGS_REG))]
7411   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7412   "sbb{l}\t{%2, %0|%0, %2}"
7413   [(set_attr "type" "alu")
7414    (set_attr "pent_pair" "pu")
7415    (set_attr "mode" "SI")])
7416
7417 (define_insn "subsi3_carry_zext"
7418   [(set (match_operand:DI 0 "register_operand" "=r")
7419           (zero_extend:DI
7420             (minus:SI (match_operand:SI 1 "register_operand" "0")
7421               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7422                  (match_operand:SI 2 "general_operand" "g")))))
7423    (clobber (reg:CC FLAGS_REG))]
7424   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7425   "sbb{l}\t{%2, %k0|%k0, %2}"
7426   [(set_attr "type" "alu")
7427    (set_attr "pent_pair" "pu")
7428    (set_attr "mode" "SI")])
7429
7430 (define_expand "subsi3"
7431   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7432                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7433                              (match_operand:SI 2 "general_operand" "")))
7434               (clobber (reg:CC FLAGS_REG))])]
7435   ""
7436   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7437
7438 (define_insn "*subsi_1"
7439   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7440         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7441                   (match_operand:SI 2 "general_operand" "ri,rm")))
7442    (clobber (reg:CC FLAGS_REG))]
7443   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7444   "sub{l}\t{%2, %0|%0, %2}"
7445   [(set_attr "type" "alu")
7446    (set_attr "mode" "SI")])
7447
7448 (define_insn "*subsi_1_zext"
7449   [(set (match_operand:DI 0 "register_operand" "=r")
7450         (zero_extend:DI
7451           (minus:SI (match_operand:SI 1 "register_operand" "0")
7452                     (match_operand:SI 2 "general_operand" "g"))))
7453    (clobber (reg:CC FLAGS_REG))]
7454   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7455   "sub{l}\t{%2, %k0|%k0, %2}"
7456   [(set_attr "type" "alu")
7457    (set_attr "mode" "SI")])
7458
7459 (define_insn "*subsi_2"
7460   [(set (reg FLAGS_REG)
7461         (compare
7462           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7463                     (match_operand:SI 2 "general_operand" "ri,rm"))
7464           (const_int 0)))
7465    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7466         (minus:SI (match_dup 1) (match_dup 2)))]
7467   "ix86_match_ccmode (insn, CCGOCmode)
7468    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7469   "sub{l}\t{%2, %0|%0, %2}"
7470   [(set_attr "type" "alu")
7471    (set_attr "mode" "SI")])
7472
7473 (define_insn "*subsi_2_zext"
7474   [(set (reg FLAGS_REG)
7475         (compare
7476           (minus:SI (match_operand:SI 1 "register_operand" "0")
7477                     (match_operand:SI 2 "general_operand" "g"))
7478           (const_int 0)))
7479    (set (match_operand:DI 0 "register_operand" "=r")
7480         (zero_extend:DI
7481           (minus:SI (match_dup 1)
7482                     (match_dup 2))))]
7483   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7484    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7485   "sub{l}\t{%2, %k0|%k0, %2}"
7486   [(set_attr "type" "alu")
7487    (set_attr "mode" "SI")])
7488
7489 (define_insn "*subsi_3"
7490   [(set (reg FLAGS_REG)
7491         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7492                  (match_operand:SI 2 "general_operand" "ri,rm")))
7493    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7494         (minus:SI (match_dup 1) (match_dup 2)))]
7495   "ix86_match_ccmode (insn, CCmode)
7496    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7497   "sub{l}\t{%2, %0|%0, %2}"
7498   [(set_attr "type" "alu")
7499    (set_attr "mode" "SI")])
7500
7501 (define_insn "*subsi_3_zext"
7502   [(set (reg FLAGS_REG)
7503         (compare (match_operand:SI 1 "register_operand" "0")
7504                  (match_operand:SI 2 "general_operand" "g")))
7505    (set (match_operand:DI 0 "register_operand" "=r")
7506         (zero_extend:DI
7507           (minus:SI (match_dup 1)
7508                     (match_dup 2))))]
7509   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7510    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7511   "sub{l}\t{%2, %1|%1, %2}"
7512   [(set_attr "type" "alu")
7513    (set_attr "mode" "DI")])
7514
7515 (define_expand "subhi3"
7516   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7517                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7518                              (match_operand:HI 2 "general_operand" "")))
7519               (clobber (reg:CC FLAGS_REG))])]
7520   "TARGET_HIMODE_MATH"
7521   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7522
7523 (define_insn "*subhi_1"
7524   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7525         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7526                   (match_operand:HI 2 "general_operand" "ri,rm")))
7527    (clobber (reg:CC FLAGS_REG))]
7528   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7529   "sub{w}\t{%2, %0|%0, %2}"
7530   [(set_attr "type" "alu")
7531    (set_attr "mode" "HI")])
7532
7533 (define_insn "*subhi_2"
7534   [(set (reg FLAGS_REG)
7535         (compare
7536           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7537                     (match_operand:HI 2 "general_operand" "ri,rm"))
7538           (const_int 0)))
7539    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7540         (minus:HI (match_dup 1) (match_dup 2)))]
7541   "ix86_match_ccmode (insn, CCGOCmode)
7542    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7543   "sub{w}\t{%2, %0|%0, %2}"
7544   [(set_attr "type" "alu")
7545    (set_attr "mode" "HI")])
7546
7547 (define_insn "*subhi_3"
7548   [(set (reg FLAGS_REG)
7549         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7550                  (match_operand:HI 2 "general_operand" "ri,rm")))
7551    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7552         (minus:HI (match_dup 1) (match_dup 2)))]
7553   "ix86_match_ccmode (insn, CCmode)
7554    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7555   "sub{w}\t{%2, %0|%0, %2}"
7556   [(set_attr "type" "alu")
7557    (set_attr "mode" "HI")])
7558
7559 (define_expand "subqi3"
7560   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7561                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7562                              (match_operand:QI 2 "general_operand" "")))
7563               (clobber (reg:CC FLAGS_REG))])]
7564   "TARGET_QIMODE_MATH"
7565   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7566
7567 (define_insn "*subqi_1"
7568   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7569         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7570                   (match_operand:QI 2 "general_operand" "qn,qmn")))
7571    (clobber (reg:CC FLAGS_REG))]
7572   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7573   "sub{b}\t{%2, %0|%0, %2}"
7574   [(set_attr "type" "alu")
7575    (set_attr "mode" "QI")])
7576
7577 (define_insn "*subqi_1_slp"
7578   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7579         (minus:QI (match_dup 0)
7580                   (match_operand:QI 1 "general_operand" "qn,qmn")))
7581    (clobber (reg:CC FLAGS_REG))]
7582   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7583    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7584   "sub{b}\t{%1, %0|%0, %1}"
7585   [(set_attr "type" "alu1")
7586    (set_attr "mode" "QI")])
7587
7588 (define_insn "*subqi_2"
7589   [(set (reg FLAGS_REG)
7590         (compare
7591           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7592                     (match_operand:QI 2 "general_operand" "qi,qm"))
7593           (const_int 0)))
7594    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7595         (minus:HI (match_dup 1) (match_dup 2)))]
7596   "ix86_match_ccmode (insn, CCGOCmode)
7597    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7598   "sub{b}\t{%2, %0|%0, %2}"
7599   [(set_attr "type" "alu")
7600    (set_attr "mode" "QI")])
7601
7602 (define_insn "*subqi_3"
7603   [(set (reg FLAGS_REG)
7604         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7605                  (match_operand:QI 2 "general_operand" "qi,qm")))
7606    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7607         (minus:HI (match_dup 1) (match_dup 2)))]
7608   "ix86_match_ccmode (insn, CCmode)
7609    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7610   "sub{b}\t{%2, %0|%0, %2}"
7611   [(set_attr "type" "alu")
7612    (set_attr "mode" "QI")])
7613
7614 ;; The patterns that match these are at the end of this file.
7615
7616 (define_expand "subxf3"
7617   [(set (match_operand:XF 0 "register_operand" "")
7618         (minus:XF (match_operand:XF 1 "register_operand" "")
7619                   (match_operand:XF 2 "register_operand" "")))]
7620   "TARGET_80387"
7621   "")
7622
7623 (define_expand "sub<mode>3"
7624   [(set (match_operand:MODEF 0 "register_operand" "")
7625         (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7626                      (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7627   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7628   "")
7629 \f
7630 ;; Multiply instructions
7631
7632 (define_expand "muldi3"
7633   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7634                    (mult:DI (match_operand:DI 1 "register_operand" "")
7635                             (match_operand:DI 2 "x86_64_general_operand" "")))
7636               (clobber (reg:CC FLAGS_REG))])]
7637   "TARGET_64BIT"
7638   "")
7639
7640 ;; On AMDFAM10
7641 ;; IMUL reg64, reg64, imm8      Direct
7642 ;; IMUL reg64, mem64, imm8      VectorPath
7643 ;; IMUL reg64, reg64, imm32     Direct
7644 ;; IMUL reg64, mem64, imm32     VectorPath
7645 ;; IMUL reg64, reg64            Direct
7646 ;; IMUL reg64, mem64            Direct
7647
7648 (define_insn "*muldi3_1_rex64"
7649   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7650         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7651                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7652    (clobber (reg:CC FLAGS_REG))]
7653   "TARGET_64BIT
7654    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7655   "@
7656    imul{q}\t{%2, %1, %0|%0, %1, %2}
7657    imul{q}\t{%2, %1, %0|%0, %1, %2}
7658    imul{q}\t{%2, %0|%0, %2}"
7659   [(set_attr "type" "imul")
7660    (set_attr "prefix_0f" "0,0,1")
7661    (set (attr "athlon_decode")
7662         (cond [(eq_attr "cpu" "athlon")
7663                   (const_string "vector")
7664                (eq_attr "alternative" "1")
7665                   (const_string "vector")
7666                (and (eq_attr "alternative" "2")
7667                     (match_operand 1 "memory_operand" ""))
7668                   (const_string "vector")]
7669               (const_string "direct")))
7670    (set (attr "amdfam10_decode")
7671         (cond [(and (eq_attr "alternative" "0,1")
7672                     (match_operand 1 "memory_operand" ""))
7673                   (const_string "vector")]
7674               (const_string "direct")))
7675    (set_attr "mode" "DI")])
7676
7677 (define_expand "mulsi3"
7678   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7679                    (mult:SI (match_operand:SI 1 "register_operand" "")
7680                             (match_operand:SI 2 "general_operand" "")))
7681               (clobber (reg:CC FLAGS_REG))])]
7682   ""
7683   "")
7684
7685 ;; On AMDFAM10
7686 ;; IMUL reg32, reg32, imm8      Direct
7687 ;; IMUL reg32, mem32, imm8      VectorPath
7688 ;; IMUL reg32, reg32, imm32     Direct
7689 ;; IMUL reg32, mem32, imm32     VectorPath
7690 ;; IMUL reg32, reg32            Direct
7691 ;; IMUL reg32, mem32            Direct
7692
7693 (define_insn "*mulsi3_1"
7694   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7695         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7696                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7697    (clobber (reg:CC FLAGS_REG))]
7698   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7699   "@
7700    imul{l}\t{%2, %1, %0|%0, %1, %2}
7701    imul{l}\t{%2, %1, %0|%0, %1, %2}
7702    imul{l}\t{%2, %0|%0, %2}"
7703   [(set_attr "type" "imul")
7704    (set_attr "prefix_0f" "0,0,1")
7705    (set (attr "athlon_decode")
7706         (cond [(eq_attr "cpu" "athlon")
7707                   (const_string "vector")
7708                (eq_attr "alternative" "1")
7709                   (const_string "vector")
7710                (and (eq_attr "alternative" "2")
7711                     (match_operand 1 "memory_operand" ""))
7712                   (const_string "vector")]
7713               (const_string "direct")))
7714    (set (attr "amdfam10_decode")
7715         (cond [(and (eq_attr "alternative" "0,1")
7716                     (match_operand 1 "memory_operand" ""))
7717                   (const_string "vector")]
7718               (const_string "direct")))
7719    (set_attr "mode" "SI")])
7720
7721 (define_insn "*mulsi3_1_zext"
7722   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7723         (zero_extend:DI
7724           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7725                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7726    (clobber (reg:CC FLAGS_REG))]
7727   "TARGET_64BIT
7728    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7729   "@
7730    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7731    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7732    imul{l}\t{%2, %k0|%k0, %2}"
7733   [(set_attr "type" "imul")
7734    (set_attr "prefix_0f" "0,0,1")
7735    (set (attr "athlon_decode")
7736         (cond [(eq_attr "cpu" "athlon")
7737                   (const_string "vector")
7738                (eq_attr "alternative" "1")
7739                   (const_string "vector")
7740                (and (eq_attr "alternative" "2")
7741                     (match_operand 1 "memory_operand" ""))
7742                   (const_string "vector")]
7743               (const_string "direct")))
7744    (set (attr "amdfam10_decode")
7745         (cond [(and (eq_attr "alternative" "0,1")
7746                     (match_operand 1 "memory_operand" ""))
7747                   (const_string "vector")]
7748               (const_string "direct")))
7749    (set_attr "mode" "SI")])
7750
7751 (define_expand "mulhi3"
7752   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7753                    (mult:HI (match_operand:HI 1 "register_operand" "")
7754                             (match_operand:HI 2 "general_operand" "")))
7755               (clobber (reg:CC FLAGS_REG))])]
7756   "TARGET_HIMODE_MATH"
7757   "")
7758
7759 ;; On AMDFAM10
7760 ;; IMUL reg16, reg16, imm8      VectorPath
7761 ;; IMUL reg16, mem16, imm8      VectorPath
7762 ;; IMUL reg16, reg16, imm16     VectorPath
7763 ;; IMUL reg16, mem16, imm16     VectorPath
7764 ;; IMUL reg16, reg16            Direct
7765 ;; IMUL reg16, mem16            Direct
7766 (define_insn "*mulhi3_1"
7767   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7768         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7769                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7770    (clobber (reg:CC FLAGS_REG))]
7771   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7772   "@
7773    imul{w}\t{%2, %1, %0|%0, %1, %2}
7774    imul{w}\t{%2, %1, %0|%0, %1, %2}
7775    imul{w}\t{%2, %0|%0, %2}"
7776   [(set_attr "type" "imul")
7777    (set_attr "prefix_0f" "0,0,1")
7778    (set (attr "athlon_decode")
7779         (cond [(eq_attr "cpu" "athlon")
7780                   (const_string "vector")
7781                (eq_attr "alternative" "1,2")
7782                   (const_string "vector")]
7783               (const_string "direct")))
7784    (set (attr "amdfam10_decode")
7785         (cond [(eq_attr "alternative" "0,1")
7786                   (const_string "vector")]
7787               (const_string "direct")))
7788    (set_attr "mode" "HI")])
7789
7790 (define_expand "mulqi3"
7791   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7792                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7793                             (match_operand:QI 2 "register_operand" "")))
7794               (clobber (reg:CC FLAGS_REG))])]
7795   "TARGET_QIMODE_MATH"
7796   "")
7797
7798 ;;On AMDFAM10
7799 ;; MUL reg8     Direct
7800 ;; MUL mem8     Direct
7801
7802 (define_insn "*mulqi3_1"
7803   [(set (match_operand:QI 0 "register_operand" "=a")
7804         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7805                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7806    (clobber (reg:CC FLAGS_REG))]
7807   "TARGET_QIMODE_MATH
7808    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7809   "mul{b}\t%2"
7810   [(set_attr "type" "imul")
7811    (set_attr "length_immediate" "0")
7812    (set (attr "athlon_decode")
7813      (if_then_else (eq_attr "cpu" "athlon")
7814         (const_string "vector")
7815         (const_string "direct")))
7816    (set_attr "amdfam10_decode" "direct")
7817    (set_attr "mode" "QI")])
7818
7819 (define_expand "umulqihi3"
7820   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7821                    (mult:HI (zero_extend:HI
7822                               (match_operand:QI 1 "nonimmediate_operand" ""))
7823                             (zero_extend:HI
7824                               (match_operand:QI 2 "register_operand" ""))))
7825               (clobber (reg:CC FLAGS_REG))])]
7826   "TARGET_QIMODE_MATH"
7827   "")
7828
7829 (define_insn "*umulqihi3_1"
7830   [(set (match_operand:HI 0 "register_operand" "=a")
7831         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7832                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7833    (clobber (reg:CC FLAGS_REG))]
7834   "TARGET_QIMODE_MATH
7835    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7836   "mul{b}\t%2"
7837   [(set_attr "type" "imul")
7838    (set_attr "length_immediate" "0")
7839    (set (attr "athlon_decode")
7840      (if_then_else (eq_attr "cpu" "athlon")
7841         (const_string "vector")
7842         (const_string "direct")))
7843    (set_attr "amdfam10_decode" "direct")
7844    (set_attr "mode" "QI")])
7845
7846 (define_expand "mulqihi3"
7847   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7848                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7849                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7850               (clobber (reg:CC FLAGS_REG))])]
7851   "TARGET_QIMODE_MATH"
7852   "")
7853
7854 (define_insn "*mulqihi3_insn"
7855   [(set (match_operand:HI 0 "register_operand" "=a")
7856         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7857                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7858    (clobber (reg:CC FLAGS_REG))]
7859   "TARGET_QIMODE_MATH
7860    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7861   "imul{b}\t%2"
7862   [(set_attr "type" "imul")
7863    (set_attr "length_immediate" "0")
7864    (set (attr "athlon_decode")
7865      (if_then_else (eq_attr "cpu" "athlon")
7866         (const_string "vector")
7867         (const_string "direct")))
7868    (set_attr "amdfam10_decode" "direct")
7869    (set_attr "mode" "QI")])
7870
7871 (define_expand "umulditi3"
7872   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7873                    (mult:TI (zero_extend:TI
7874                               (match_operand:DI 1 "nonimmediate_operand" ""))
7875                             (zero_extend:TI
7876                               (match_operand:DI 2 "register_operand" ""))))
7877               (clobber (reg:CC FLAGS_REG))])]
7878   "TARGET_64BIT"
7879   "")
7880
7881 (define_insn "*umulditi3_insn"
7882   [(set (match_operand:TI 0 "register_operand" "=A")
7883         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7884                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7885    (clobber (reg:CC FLAGS_REG))]
7886   "TARGET_64BIT
7887    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7888   "mul{q}\t%2"
7889   [(set_attr "type" "imul")
7890    (set_attr "length_immediate" "0")
7891    (set (attr "athlon_decode")
7892      (if_then_else (eq_attr "cpu" "athlon")
7893         (const_string "vector")
7894         (const_string "double")))
7895    (set_attr "amdfam10_decode" "double")
7896    (set_attr "mode" "DI")])
7897
7898 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7899 (define_expand "umulsidi3"
7900   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7901                    (mult:DI (zero_extend:DI
7902                               (match_operand:SI 1 "nonimmediate_operand" ""))
7903                             (zero_extend:DI
7904                               (match_operand:SI 2 "register_operand" ""))))
7905               (clobber (reg:CC FLAGS_REG))])]
7906   "!TARGET_64BIT"
7907   "")
7908
7909 (define_insn "*umulsidi3_insn"
7910   [(set (match_operand:DI 0 "register_operand" "=A")
7911         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7912                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7913    (clobber (reg:CC FLAGS_REG))]
7914   "!TARGET_64BIT
7915    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7916   "mul{l}\t%2"
7917   [(set_attr "type" "imul")
7918    (set_attr "length_immediate" "0")
7919    (set (attr "athlon_decode")
7920      (if_then_else (eq_attr "cpu" "athlon")
7921         (const_string "vector")
7922         (const_string "double")))
7923    (set_attr "amdfam10_decode" "double")
7924    (set_attr "mode" "SI")])
7925
7926 (define_expand "mulditi3"
7927   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7928                    (mult:TI (sign_extend:TI
7929                               (match_operand:DI 1 "nonimmediate_operand" ""))
7930                             (sign_extend:TI
7931                               (match_operand:DI 2 "register_operand" ""))))
7932               (clobber (reg:CC FLAGS_REG))])]
7933   "TARGET_64BIT"
7934   "")
7935
7936 (define_insn "*mulditi3_insn"
7937   [(set (match_operand:TI 0 "register_operand" "=A")
7938         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7939                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7940    (clobber (reg:CC FLAGS_REG))]
7941   "TARGET_64BIT
7942    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7943   "imul{q}\t%2"
7944   [(set_attr "type" "imul")
7945    (set_attr "length_immediate" "0")
7946    (set (attr "athlon_decode")
7947      (if_then_else (eq_attr "cpu" "athlon")
7948         (const_string "vector")
7949         (const_string "double")))
7950    (set_attr "amdfam10_decode" "double")
7951    (set_attr "mode" "DI")])
7952
7953 (define_expand "mulsidi3"
7954   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7955                    (mult:DI (sign_extend:DI
7956                               (match_operand:SI 1 "nonimmediate_operand" ""))
7957                             (sign_extend:DI
7958                               (match_operand:SI 2 "register_operand" ""))))
7959               (clobber (reg:CC FLAGS_REG))])]
7960   "!TARGET_64BIT"
7961   "")
7962
7963 (define_insn "*mulsidi3_insn"
7964   [(set (match_operand:DI 0 "register_operand" "=A")
7965         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7966                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7967    (clobber (reg:CC FLAGS_REG))]
7968   "!TARGET_64BIT
7969    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7970   "imul{l}\t%2"
7971   [(set_attr "type" "imul")
7972    (set_attr "length_immediate" "0")
7973    (set (attr "athlon_decode")
7974      (if_then_else (eq_attr "cpu" "athlon")
7975         (const_string "vector")
7976         (const_string "double")))
7977    (set_attr "amdfam10_decode" "double")
7978    (set_attr "mode" "SI")])
7979
7980 (define_expand "umuldi3_highpart"
7981   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7982                    (truncate:DI
7983                      (lshiftrt:TI
7984                        (mult:TI (zero_extend:TI
7985                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7986                                 (zero_extend:TI
7987                                   (match_operand:DI 2 "register_operand" "")))
7988                        (const_int 64))))
7989               (clobber (match_scratch:DI 3 ""))
7990               (clobber (reg:CC FLAGS_REG))])]
7991   "TARGET_64BIT"
7992   "")
7993
7994 (define_insn "*umuldi3_highpart_rex64"
7995   [(set (match_operand:DI 0 "register_operand" "=d")
7996         (truncate:DI
7997           (lshiftrt:TI
7998             (mult:TI (zero_extend:TI
7999                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8000                      (zero_extend:TI
8001                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8002             (const_int 64))))
8003    (clobber (match_scratch:DI 3 "=1"))
8004    (clobber (reg:CC FLAGS_REG))]
8005   "TARGET_64BIT
8006    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8007   "mul{q}\t%2"
8008   [(set_attr "type" "imul")
8009    (set_attr "length_immediate" "0")
8010    (set (attr "athlon_decode")
8011      (if_then_else (eq_attr "cpu" "athlon")
8012         (const_string "vector")
8013         (const_string "double")))
8014    (set_attr "amdfam10_decode" "double")
8015    (set_attr "mode" "DI")])
8016
8017 (define_expand "umulsi3_highpart"
8018   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8019                    (truncate:SI
8020                      (lshiftrt:DI
8021                        (mult:DI (zero_extend:DI
8022                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8023                                 (zero_extend:DI
8024                                   (match_operand:SI 2 "register_operand" "")))
8025                        (const_int 32))))
8026               (clobber (match_scratch:SI 3 ""))
8027               (clobber (reg:CC FLAGS_REG))])]
8028   ""
8029   "")
8030
8031 (define_insn "*umulsi3_highpart_insn"
8032   [(set (match_operand:SI 0 "register_operand" "=d")
8033         (truncate:SI
8034           (lshiftrt:DI
8035             (mult:DI (zero_extend:DI
8036                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8037                      (zero_extend:DI
8038                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8039             (const_int 32))))
8040    (clobber (match_scratch:SI 3 "=1"))
8041    (clobber (reg:CC FLAGS_REG))]
8042   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8043   "mul{l}\t%2"
8044   [(set_attr "type" "imul")
8045    (set_attr "length_immediate" "0")
8046    (set (attr "athlon_decode")
8047      (if_then_else (eq_attr "cpu" "athlon")
8048         (const_string "vector")
8049         (const_string "double")))
8050    (set_attr "amdfam10_decode" "double")
8051    (set_attr "mode" "SI")])
8052
8053 (define_insn "*umulsi3_highpart_zext"
8054   [(set (match_operand:DI 0 "register_operand" "=d")
8055         (zero_extend:DI (truncate:SI
8056           (lshiftrt:DI
8057             (mult:DI (zero_extend:DI
8058                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8059                      (zero_extend:DI
8060                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8061             (const_int 32)))))
8062    (clobber (match_scratch:SI 3 "=1"))
8063    (clobber (reg:CC FLAGS_REG))]
8064   "TARGET_64BIT
8065    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8066   "mul{l}\t%2"
8067   [(set_attr "type" "imul")
8068    (set_attr "length_immediate" "0")
8069    (set (attr "athlon_decode")
8070      (if_then_else (eq_attr "cpu" "athlon")
8071         (const_string "vector")
8072         (const_string "double")))
8073    (set_attr "amdfam10_decode" "double")
8074    (set_attr "mode" "SI")])
8075
8076 (define_expand "smuldi3_highpart"
8077   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8078                    (truncate:DI
8079                      (lshiftrt:TI
8080                        (mult:TI (sign_extend:TI
8081                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8082                                 (sign_extend:TI
8083                                   (match_operand:DI 2 "register_operand" "")))
8084                        (const_int 64))))
8085               (clobber (match_scratch:DI 3 ""))
8086               (clobber (reg:CC FLAGS_REG))])]
8087   "TARGET_64BIT"
8088   "")
8089
8090 (define_insn "*smuldi3_highpart_rex64"
8091   [(set (match_operand:DI 0 "register_operand" "=d")
8092         (truncate:DI
8093           (lshiftrt:TI
8094             (mult:TI (sign_extend:TI
8095                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8096                      (sign_extend:TI
8097                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8098             (const_int 64))))
8099    (clobber (match_scratch:DI 3 "=1"))
8100    (clobber (reg:CC FLAGS_REG))]
8101   "TARGET_64BIT
8102    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8103   "imul{q}\t%2"
8104   [(set_attr "type" "imul")
8105    (set (attr "athlon_decode")
8106      (if_then_else (eq_attr "cpu" "athlon")
8107         (const_string "vector")
8108         (const_string "double")))
8109    (set_attr "amdfam10_decode" "double")
8110    (set_attr "mode" "DI")])
8111
8112 (define_expand "smulsi3_highpart"
8113   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8114                    (truncate:SI
8115                      (lshiftrt:DI
8116                        (mult:DI (sign_extend:DI
8117                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8118                                 (sign_extend:DI
8119                                   (match_operand:SI 2 "register_operand" "")))
8120                        (const_int 32))))
8121               (clobber (match_scratch:SI 3 ""))
8122               (clobber (reg:CC FLAGS_REG))])]
8123   ""
8124   "")
8125
8126 (define_insn "*smulsi3_highpart_insn"
8127   [(set (match_operand:SI 0 "register_operand" "=d")
8128         (truncate:SI
8129           (lshiftrt:DI
8130             (mult:DI (sign_extend:DI
8131                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8132                      (sign_extend:DI
8133                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8134             (const_int 32))))
8135    (clobber (match_scratch:SI 3 "=1"))
8136    (clobber (reg:CC FLAGS_REG))]
8137   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8138   "imul{l}\t%2"
8139   [(set_attr "type" "imul")
8140    (set (attr "athlon_decode")
8141      (if_then_else (eq_attr "cpu" "athlon")
8142         (const_string "vector")
8143         (const_string "double")))
8144    (set_attr "amdfam10_decode" "double")
8145    (set_attr "mode" "SI")])
8146
8147 (define_insn "*smulsi3_highpart_zext"
8148   [(set (match_operand:DI 0 "register_operand" "=d")
8149         (zero_extend:DI (truncate:SI
8150           (lshiftrt:DI
8151             (mult:DI (sign_extend:DI
8152                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8153                      (sign_extend:DI
8154                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8155             (const_int 32)))))
8156    (clobber (match_scratch:SI 3 "=1"))
8157    (clobber (reg:CC FLAGS_REG))]
8158   "TARGET_64BIT
8159    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8160   "imul{l}\t%2"
8161   [(set_attr "type" "imul")
8162    (set (attr "athlon_decode")
8163      (if_then_else (eq_attr "cpu" "athlon")
8164         (const_string "vector")
8165         (const_string "double")))
8166    (set_attr "amdfam10_decode" "double")
8167    (set_attr "mode" "SI")])
8168
8169 ;; The patterns that match these are at the end of this file.
8170
8171 (define_expand "mulxf3"
8172   [(set (match_operand:XF 0 "register_operand" "")
8173         (mult:XF (match_operand:XF 1 "register_operand" "")
8174                  (match_operand:XF 2 "register_operand" "")))]
8175   "TARGET_80387"
8176   "")
8177
8178 (define_expand "mul<mode>3"
8179   [(set (match_operand:MODEF 0 "register_operand" "")
8180         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8181                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8182   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8183   "")
8184
8185 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8186
8187 \f
8188 ;; Divide instructions
8189
8190 (define_insn "divqi3"
8191   [(set (match_operand:QI 0 "register_operand" "=a")
8192         (div:QI (match_operand:HI 1 "register_operand" "0")
8193                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8194    (clobber (reg:CC FLAGS_REG))]
8195   "TARGET_QIMODE_MATH"
8196   "idiv{b}\t%2"
8197   [(set_attr "type" "idiv")
8198    (set_attr "mode" "QI")])
8199
8200 (define_insn "udivqi3"
8201   [(set (match_operand:QI 0 "register_operand" "=a")
8202         (udiv:QI (match_operand:HI 1 "register_operand" "0")
8203                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8204    (clobber (reg:CC FLAGS_REG))]
8205   "TARGET_QIMODE_MATH"
8206   "div{b}\t%2"
8207   [(set_attr "type" "idiv")
8208    (set_attr "mode" "QI")])
8209
8210 ;; The patterns that match these are at the end of this file.
8211
8212 (define_expand "divxf3"
8213   [(set (match_operand:XF 0 "register_operand" "")
8214         (div:XF (match_operand:XF 1 "register_operand" "")
8215                 (match_operand:XF 2 "register_operand" "")))]
8216   "TARGET_80387"
8217   "")
8218
8219 (define_expand "divdf3"
8220   [(set (match_operand:DF 0 "register_operand" "")
8221         (div:DF (match_operand:DF 1 "register_operand" "")
8222                 (match_operand:DF 2 "nonimmediate_operand" "")))]
8223    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8224    "")
8225
8226 (define_expand "divsf3"
8227   [(set (match_operand:SF 0 "register_operand" "")
8228         (div:SF (match_operand:SF 1 "register_operand" "")
8229                 (match_operand:SF 2 "nonimmediate_operand" "")))]
8230   "TARGET_80387 || TARGET_SSE_MATH"
8231 {
8232   if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8233       && flag_finite_math_only && !flag_trapping_math
8234       && flag_unsafe_math_optimizations)
8235     {
8236       ix86_emit_swdivsf (operands[0], operands[1],
8237                          operands[2], SFmode);
8238       DONE;
8239     }
8240 })
8241 \f
8242 ;; Remainder instructions.
8243
8244 (define_expand "divmoddi4"
8245   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8246                    (div:DI (match_operand:DI 1 "register_operand" "")
8247                            (match_operand:DI 2 "nonimmediate_operand" "")))
8248               (set (match_operand:DI 3 "register_operand" "")
8249                    (mod:DI (match_dup 1) (match_dup 2)))
8250               (clobber (reg:CC FLAGS_REG))])]
8251   "TARGET_64BIT"
8252   "")
8253
8254 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8255 ;; Penalize eax case slightly because it results in worse scheduling
8256 ;; of code.
8257 (define_insn "*divmoddi4_nocltd_rex64"
8258   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8259         (div:DI (match_operand:DI 2 "register_operand" "1,0")
8260                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8261    (set (match_operand:DI 1 "register_operand" "=&d,&d")
8262         (mod:DI (match_dup 2) (match_dup 3)))
8263    (clobber (reg:CC FLAGS_REG))]
8264   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8265   "#"
8266   [(set_attr "type" "multi")])
8267
8268 (define_insn "*divmoddi4_cltd_rex64"
8269   [(set (match_operand:DI 0 "register_operand" "=a")
8270         (div:DI (match_operand:DI 2 "register_operand" "a")
8271                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8272    (set (match_operand:DI 1 "register_operand" "=&d")
8273         (mod:DI (match_dup 2) (match_dup 3)))
8274    (clobber (reg:CC FLAGS_REG))]
8275   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8276   "#"
8277   [(set_attr "type" "multi")])
8278
8279 (define_insn "*divmoddi_noext_rex64"
8280   [(set (match_operand:DI 0 "register_operand" "=a")
8281         (div:DI (match_operand:DI 1 "register_operand" "0")
8282                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8283    (set (match_operand:DI 3 "register_operand" "=d")
8284         (mod:DI (match_dup 1) (match_dup 2)))
8285    (use (match_operand:DI 4 "register_operand" "3"))
8286    (clobber (reg:CC FLAGS_REG))]
8287   "TARGET_64BIT"
8288   "idiv{q}\t%2"
8289   [(set_attr "type" "idiv")
8290    (set_attr "mode" "DI")])
8291
8292 (define_split
8293   [(set (match_operand:DI 0 "register_operand" "")
8294         (div:DI (match_operand:DI 1 "register_operand" "")
8295                 (match_operand:DI 2 "nonimmediate_operand" "")))
8296    (set (match_operand:DI 3 "register_operand" "")
8297         (mod:DI (match_dup 1) (match_dup 2)))
8298    (clobber (reg:CC FLAGS_REG))]
8299   "TARGET_64BIT && reload_completed"
8300   [(parallel [(set (match_dup 3)
8301                    (ashiftrt:DI (match_dup 4) (const_int 63)))
8302               (clobber (reg:CC FLAGS_REG))])
8303    (parallel [(set (match_dup 0)
8304                    (div:DI (reg:DI 0) (match_dup 2)))
8305               (set (match_dup 3)
8306                    (mod:DI (reg:DI 0) (match_dup 2)))
8307               (use (match_dup 3))
8308               (clobber (reg:CC FLAGS_REG))])]
8309 {
8310   /* Avoid use of cltd in favor of a mov+shift.  */
8311   if (!TARGET_USE_CLTD && !optimize_size)
8312     {
8313       if (true_regnum (operands[1]))
8314         emit_move_insn (operands[0], operands[1]);
8315       else
8316         emit_move_insn (operands[3], operands[1]);
8317       operands[4] = operands[3];
8318     }
8319   else
8320     {
8321       gcc_assert (!true_regnum (operands[1]));
8322       operands[4] = operands[1];
8323     }
8324 })
8325
8326
8327 (define_expand "divmodsi4"
8328   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8329                    (div:SI (match_operand:SI 1 "register_operand" "")
8330                            (match_operand:SI 2 "nonimmediate_operand" "")))
8331               (set (match_operand:SI 3 "register_operand" "")
8332                    (mod:SI (match_dup 1) (match_dup 2)))
8333               (clobber (reg:CC FLAGS_REG))])]
8334   ""
8335   "")
8336
8337 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8338 ;; Penalize eax case slightly because it results in worse scheduling
8339 ;; of code.
8340 (define_insn "*divmodsi4_nocltd"
8341   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8342         (div:SI (match_operand:SI 2 "register_operand" "1,0")
8343                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8344    (set (match_operand:SI 1 "register_operand" "=&d,&d")
8345         (mod:SI (match_dup 2) (match_dup 3)))
8346    (clobber (reg:CC FLAGS_REG))]
8347   "!optimize_size && !TARGET_USE_CLTD"
8348   "#"
8349   [(set_attr "type" "multi")])
8350
8351 (define_insn "*divmodsi4_cltd"
8352   [(set (match_operand:SI 0 "register_operand" "=a")
8353         (div:SI (match_operand:SI 2 "register_operand" "a")
8354                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8355    (set (match_operand:SI 1 "register_operand" "=&d")
8356         (mod:SI (match_dup 2) (match_dup 3)))
8357    (clobber (reg:CC FLAGS_REG))]
8358   "optimize_size || TARGET_USE_CLTD"
8359   "#"
8360   [(set_attr "type" "multi")])
8361
8362 (define_insn "*divmodsi_noext"
8363   [(set (match_operand:SI 0 "register_operand" "=a")
8364         (div:SI (match_operand:SI 1 "register_operand" "0")
8365                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8366    (set (match_operand:SI 3 "register_operand" "=d")
8367         (mod:SI (match_dup 1) (match_dup 2)))
8368    (use (match_operand:SI 4 "register_operand" "3"))
8369    (clobber (reg:CC FLAGS_REG))]
8370   ""
8371   "idiv{l}\t%2"
8372   [(set_attr "type" "idiv")
8373    (set_attr "mode" "SI")])
8374
8375 (define_split
8376   [(set (match_operand:SI 0 "register_operand" "")
8377         (div:SI (match_operand:SI 1 "register_operand" "")
8378                 (match_operand:SI 2 "nonimmediate_operand" "")))
8379    (set (match_operand:SI 3 "register_operand" "")
8380         (mod:SI (match_dup 1) (match_dup 2)))
8381    (clobber (reg:CC FLAGS_REG))]
8382   "reload_completed"
8383   [(parallel [(set (match_dup 3)
8384                    (ashiftrt:SI (match_dup 4) (const_int 31)))
8385               (clobber (reg:CC FLAGS_REG))])
8386    (parallel [(set (match_dup 0)
8387                    (div:SI (reg:SI 0) (match_dup 2)))
8388               (set (match_dup 3)
8389                    (mod:SI (reg:SI 0) (match_dup 2)))
8390               (use (match_dup 3))
8391               (clobber (reg:CC FLAGS_REG))])]
8392 {
8393   /* Avoid use of cltd in favor of a mov+shift.  */
8394   if (!TARGET_USE_CLTD && !optimize_size)
8395     {
8396       if (true_regnum (operands[1]))
8397         emit_move_insn (operands[0], operands[1]);
8398       else
8399         emit_move_insn (operands[3], operands[1]);
8400       operands[4] = operands[3];
8401     }
8402   else
8403     {
8404       gcc_assert (!true_regnum (operands[1]));
8405       operands[4] = operands[1];
8406     }
8407 })
8408 ;; %%% Split me.
8409 (define_insn "divmodhi4"
8410   [(set (match_operand:HI 0 "register_operand" "=a")
8411         (div:HI (match_operand:HI 1 "register_operand" "0")
8412                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8413    (set (match_operand:HI 3 "register_operand" "=&d")
8414         (mod:HI (match_dup 1) (match_dup 2)))
8415    (clobber (reg:CC FLAGS_REG))]
8416   "TARGET_HIMODE_MATH"
8417   "cwtd\;idiv{w}\t%2"
8418   [(set_attr "type" "multi")
8419    (set_attr "length_immediate" "0")
8420    (set_attr "mode" "SI")])
8421
8422 (define_insn "udivmoddi4"
8423   [(set (match_operand:DI 0 "register_operand" "=a")
8424         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8425                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8426    (set (match_operand:DI 3 "register_operand" "=&d")
8427         (umod:DI (match_dup 1) (match_dup 2)))
8428    (clobber (reg:CC FLAGS_REG))]
8429   "TARGET_64BIT"
8430   "xor{q}\t%3, %3\;div{q}\t%2"
8431   [(set_attr "type" "multi")
8432    (set_attr "length_immediate" "0")
8433    (set_attr "mode" "DI")])
8434
8435 (define_insn "*udivmoddi4_noext"
8436   [(set (match_operand:DI 0 "register_operand" "=a")
8437         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8438                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8439    (set (match_operand:DI 3 "register_operand" "=d")
8440         (umod:DI (match_dup 1) (match_dup 2)))
8441    (use (match_dup 3))
8442    (clobber (reg:CC FLAGS_REG))]
8443   "TARGET_64BIT"
8444   "div{q}\t%2"
8445   [(set_attr "type" "idiv")
8446    (set_attr "mode" "DI")])
8447
8448 (define_split
8449   [(set (match_operand:DI 0 "register_operand" "")
8450         (udiv:DI (match_operand:DI 1 "register_operand" "")
8451                  (match_operand:DI 2 "nonimmediate_operand" "")))
8452    (set (match_operand:DI 3 "register_operand" "")
8453         (umod:DI (match_dup 1) (match_dup 2)))
8454    (clobber (reg:CC FLAGS_REG))]
8455   "TARGET_64BIT && reload_completed"
8456   [(set (match_dup 3) (const_int 0))
8457    (parallel [(set (match_dup 0)
8458                    (udiv:DI (match_dup 1) (match_dup 2)))
8459               (set (match_dup 3)
8460                    (umod:DI (match_dup 1) (match_dup 2)))
8461               (use (match_dup 3))
8462               (clobber (reg:CC FLAGS_REG))])]
8463   "")
8464
8465 (define_insn "udivmodsi4"
8466   [(set (match_operand:SI 0 "register_operand" "=a")
8467         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8468                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8469    (set (match_operand:SI 3 "register_operand" "=&d")
8470         (umod:SI (match_dup 1) (match_dup 2)))
8471    (clobber (reg:CC FLAGS_REG))]
8472   ""
8473   "xor{l}\t%3, %3\;div{l}\t%2"
8474   [(set_attr "type" "multi")
8475    (set_attr "length_immediate" "0")
8476    (set_attr "mode" "SI")])
8477
8478 (define_insn "*udivmodsi4_noext"
8479   [(set (match_operand:SI 0 "register_operand" "=a")
8480         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8481                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8482    (set (match_operand:SI 3 "register_operand" "=d")
8483         (umod:SI (match_dup 1) (match_dup 2)))
8484    (use (match_dup 3))
8485    (clobber (reg:CC FLAGS_REG))]
8486   ""
8487   "div{l}\t%2"
8488   [(set_attr "type" "idiv")
8489    (set_attr "mode" "SI")])
8490
8491 (define_split
8492   [(set (match_operand:SI 0 "register_operand" "")
8493         (udiv:SI (match_operand:SI 1 "register_operand" "")
8494                  (match_operand:SI 2 "nonimmediate_operand" "")))
8495    (set (match_operand:SI 3 "register_operand" "")
8496         (umod:SI (match_dup 1) (match_dup 2)))
8497    (clobber (reg:CC FLAGS_REG))]
8498   "reload_completed"
8499   [(set (match_dup 3) (const_int 0))
8500    (parallel [(set (match_dup 0)
8501                    (udiv:SI (match_dup 1) (match_dup 2)))
8502               (set (match_dup 3)
8503                    (umod:SI (match_dup 1) (match_dup 2)))
8504               (use (match_dup 3))
8505               (clobber (reg:CC FLAGS_REG))])]
8506   "")
8507
8508 (define_expand "udivmodhi4"
8509   [(set (match_dup 4) (const_int 0))
8510    (parallel [(set (match_operand:HI 0 "register_operand" "")
8511                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8512                             (match_operand:HI 2 "nonimmediate_operand" "")))
8513               (set (match_operand:HI 3 "register_operand" "")
8514                    (umod:HI (match_dup 1) (match_dup 2)))
8515               (use (match_dup 4))
8516               (clobber (reg:CC FLAGS_REG))])]
8517   "TARGET_HIMODE_MATH"
8518   "operands[4] = gen_reg_rtx (HImode);")
8519
8520 (define_insn "*udivmodhi_noext"
8521   [(set (match_operand:HI 0 "register_operand" "=a")
8522         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8523                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8524    (set (match_operand:HI 3 "register_operand" "=d")
8525         (umod:HI (match_dup 1) (match_dup 2)))
8526    (use (match_operand:HI 4 "register_operand" "3"))
8527    (clobber (reg:CC FLAGS_REG))]
8528   ""
8529   "div{w}\t%2"
8530   [(set_attr "type" "idiv")
8531    (set_attr "mode" "HI")])
8532
8533 ;; We cannot use div/idiv for double division, because it causes
8534 ;; "division by zero" on the overflow and that's not what we expect
8535 ;; from truncate.  Because true (non truncating) double division is
8536 ;; never generated, we can't create this insn anyway.
8537 ;
8538 ;(define_insn ""
8539 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8540 ;       (truncate:SI
8541 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8542 ;                  (zero_extend:DI
8543 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8544 ;   (set (match_operand:SI 3 "register_operand" "=d")
8545 ;       (truncate:SI
8546 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8547 ;   (clobber (reg:CC FLAGS_REG))]
8548 ;  ""
8549 ;  "div{l}\t{%2, %0|%0, %2}"
8550 ;  [(set_attr "type" "idiv")])
8551 \f
8552 ;;- Logical AND instructions
8553
8554 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8555 ;; Note that this excludes ah.
8556
8557 (define_insn "*testdi_1_rex64"
8558   [(set (reg FLAGS_REG)
8559         (compare
8560           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8561                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8562           (const_int 0)))]
8563   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8564    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8565   "@
8566    test{l}\t{%k1, %k0|%k0, %k1}
8567    test{l}\t{%k1, %k0|%k0, %k1}
8568    test{q}\t{%1, %0|%0, %1}
8569    test{q}\t{%1, %0|%0, %1}
8570    test{q}\t{%1, %0|%0, %1}"
8571   [(set_attr "type" "test")
8572    (set_attr "modrm" "0,1,0,1,1")
8573    (set_attr "mode" "SI,SI,DI,DI,DI")
8574    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8575
8576 (define_insn "testsi_1"
8577   [(set (reg FLAGS_REG)
8578         (compare
8579           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8580                   (match_operand:SI 1 "general_operand" "in,in,rin"))
8581           (const_int 0)))]
8582   "ix86_match_ccmode (insn, CCNOmode)
8583    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8584   "test{l}\t{%1, %0|%0, %1}"
8585   [(set_attr "type" "test")
8586    (set_attr "modrm" "0,1,1")
8587    (set_attr "mode" "SI")
8588    (set_attr "pent_pair" "uv,np,uv")])
8589
8590 (define_expand "testsi_ccno_1"
8591   [(set (reg:CCNO FLAGS_REG)
8592         (compare:CCNO
8593           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8594                   (match_operand:SI 1 "nonmemory_operand" ""))
8595           (const_int 0)))]
8596   ""
8597   "")
8598
8599 (define_insn "*testhi_1"
8600   [(set (reg FLAGS_REG)
8601         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8602                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8603                  (const_int 0)))]
8604   "ix86_match_ccmode (insn, CCNOmode)
8605    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8606   "test{w}\t{%1, %0|%0, %1}"
8607   [(set_attr "type" "test")
8608    (set_attr "modrm" "0,1,1")
8609    (set_attr "mode" "HI")
8610    (set_attr "pent_pair" "uv,np,uv")])
8611
8612 (define_expand "testqi_ccz_1"
8613   [(set (reg:CCZ FLAGS_REG)
8614         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8615                              (match_operand:QI 1 "nonmemory_operand" ""))
8616                  (const_int 0)))]
8617   ""
8618   "")
8619
8620 (define_insn "*testqi_1_maybe_si"
8621   [(set (reg FLAGS_REG)
8622         (compare
8623           (and:QI
8624             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8625             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8626           (const_int 0)))]
8627    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8628     && ix86_match_ccmode (insn,
8629                          CONST_INT_P (operands[1])
8630                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8631 {
8632   if (which_alternative == 3)
8633     {
8634       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8635         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8636       return "test{l}\t{%1, %k0|%k0, %1}";
8637     }
8638   return "test{b}\t{%1, %0|%0, %1}";
8639 }
8640   [(set_attr "type" "test")
8641    (set_attr "modrm" "0,1,1,1")
8642    (set_attr "mode" "QI,QI,QI,SI")
8643    (set_attr "pent_pair" "uv,np,uv,np")])
8644
8645 (define_insn "*testqi_1"
8646   [(set (reg FLAGS_REG)
8647         (compare
8648           (and:QI
8649             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8650             (match_operand:QI 1 "general_operand" "n,n,qn"))
8651           (const_int 0)))]
8652   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8653    && ix86_match_ccmode (insn, CCNOmode)"
8654   "test{b}\t{%1, %0|%0, %1}"
8655   [(set_attr "type" "test")
8656    (set_attr "modrm" "0,1,1")
8657    (set_attr "mode" "QI")
8658    (set_attr "pent_pair" "uv,np,uv")])
8659
8660 (define_expand "testqi_ext_ccno_0"
8661   [(set (reg:CCNO FLAGS_REG)
8662         (compare:CCNO
8663           (and:SI
8664             (zero_extract:SI
8665               (match_operand 0 "ext_register_operand" "")
8666               (const_int 8)
8667               (const_int 8))
8668             (match_operand 1 "const_int_operand" ""))
8669           (const_int 0)))]
8670   ""
8671   "")
8672
8673 (define_insn "*testqi_ext_0"
8674   [(set (reg FLAGS_REG)
8675         (compare
8676           (and:SI
8677             (zero_extract:SI
8678               (match_operand 0 "ext_register_operand" "Q")
8679               (const_int 8)
8680               (const_int 8))
8681             (match_operand 1 "const_int_operand" "n"))
8682           (const_int 0)))]
8683   "ix86_match_ccmode (insn, CCNOmode)"
8684   "test{b}\t{%1, %h0|%h0, %1}"
8685   [(set_attr "type" "test")
8686    (set_attr "mode" "QI")
8687    (set_attr "length_immediate" "1")
8688    (set_attr "pent_pair" "np")])
8689
8690 (define_insn "*testqi_ext_1"
8691   [(set (reg FLAGS_REG)
8692         (compare
8693           (and:SI
8694             (zero_extract:SI
8695               (match_operand 0 "ext_register_operand" "Q")
8696               (const_int 8)
8697               (const_int 8))
8698             (zero_extend:SI
8699               (match_operand:QI 1 "general_operand" "Qm")))
8700           (const_int 0)))]
8701   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8702    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8703   "test{b}\t{%1, %h0|%h0, %1}"
8704   [(set_attr "type" "test")
8705    (set_attr "mode" "QI")])
8706
8707 (define_insn "*testqi_ext_1_rex64"
8708   [(set (reg FLAGS_REG)
8709         (compare
8710           (and:SI
8711             (zero_extract:SI
8712               (match_operand 0 "ext_register_operand" "Q")
8713               (const_int 8)
8714               (const_int 8))
8715             (zero_extend:SI
8716               (match_operand:QI 1 "register_operand" "Q")))
8717           (const_int 0)))]
8718   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8719   "test{b}\t{%1, %h0|%h0, %1}"
8720   [(set_attr "type" "test")
8721    (set_attr "mode" "QI")])
8722
8723 (define_insn "*testqi_ext_2"
8724   [(set (reg FLAGS_REG)
8725         (compare
8726           (and:SI
8727             (zero_extract:SI
8728               (match_operand 0 "ext_register_operand" "Q")
8729               (const_int 8)
8730               (const_int 8))
8731             (zero_extract:SI
8732               (match_operand 1 "ext_register_operand" "Q")
8733               (const_int 8)
8734               (const_int 8)))
8735           (const_int 0)))]
8736   "ix86_match_ccmode (insn, CCNOmode)"
8737   "test{b}\t{%h1, %h0|%h0, %h1}"
8738   [(set_attr "type" "test")
8739    (set_attr "mode" "QI")])
8740
8741 ;; Combine likes to form bit extractions for some tests.  Humor it.
8742 (define_insn "*testqi_ext_3"
8743   [(set (reg FLAGS_REG)
8744         (compare (zero_extract:SI
8745                    (match_operand 0 "nonimmediate_operand" "rm")
8746                    (match_operand:SI 1 "const_int_operand" "")
8747                    (match_operand:SI 2 "const_int_operand" ""))
8748                  (const_int 0)))]
8749   "ix86_match_ccmode (insn, CCNOmode)
8750    && INTVAL (operands[1]) > 0
8751    && INTVAL (operands[2]) >= 0
8752    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8753    && (GET_MODE (operands[0]) == SImode
8754        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8755        || GET_MODE (operands[0]) == HImode
8756        || GET_MODE (operands[0]) == QImode)"
8757   "#")
8758
8759 (define_insn "*testqi_ext_3_rex64"
8760   [(set (reg FLAGS_REG)
8761         (compare (zero_extract:DI
8762                    (match_operand 0 "nonimmediate_operand" "rm")
8763                    (match_operand:DI 1 "const_int_operand" "")
8764                    (match_operand:DI 2 "const_int_operand" ""))
8765                  (const_int 0)))]
8766   "TARGET_64BIT
8767    && ix86_match_ccmode (insn, CCNOmode)
8768    && INTVAL (operands[1]) > 0
8769    && INTVAL (operands[2]) >= 0
8770    /* Ensure that resulting mask is zero or sign extended operand.  */
8771    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8772        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8773            && INTVAL (operands[1]) > 32))
8774    && (GET_MODE (operands[0]) == SImode
8775        || GET_MODE (operands[0]) == DImode
8776        || GET_MODE (operands[0]) == HImode
8777        || GET_MODE (operands[0]) == QImode)"
8778   "#")
8779
8780 (define_split
8781   [(set (match_operand 0 "flags_reg_operand" "")
8782         (match_operator 1 "compare_operator"
8783           [(zero_extract
8784              (match_operand 2 "nonimmediate_operand" "")
8785              (match_operand 3 "const_int_operand" "")
8786              (match_operand 4 "const_int_operand" ""))
8787            (const_int 0)]))]
8788   "ix86_match_ccmode (insn, CCNOmode)"
8789   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8790 {
8791   rtx val = operands[2];
8792   HOST_WIDE_INT len = INTVAL (operands[3]);
8793   HOST_WIDE_INT pos = INTVAL (operands[4]);
8794   HOST_WIDE_INT mask;
8795   enum machine_mode mode, submode;
8796
8797   mode = GET_MODE (val);
8798   if (MEM_P (val))
8799     {
8800       /* ??? Combine likes to put non-volatile mem extractions in QImode
8801          no matter the size of the test.  So find a mode that works.  */
8802       if (! MEM_VOLATILE_P (val))
8803         {
8804           mode = smallest_mode_for_size (pos + len, MODE_INT);
8805           val = adjust_address (val, mode, 0);
8806         }
8807     }
8808   else if (GET_CODE (val) == SUBREG
8809            && (submode = GET_MODE (SUBREG_REG (val)),
8810                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8811            && pos + len <= GET_MODE_BITSIZE (submode))
8812     {
8813       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8814       mode = submode;
8815       val = SUBREG_REG (val);
8816     }
8817   else if (mode == HImode && pos + len <= 8)
8818     {
8819       /* Small HImode tests can be converted to QImode.  */
8820       mode = QImode;
8821       val = gen_lowpart (QImode, val);
8822     }
8823
8824   if (len == HOST_BITS_PER_WIDE_INT)
8825     mask = -1;
8826   else
8827     mask = ((HOST_WIDE_INT)1 << len) - 1;
8828   mask <<= pos;
8829
8830   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8831 })
8832
8833 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8834 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8835 ;; this is relatively important trick.
8836 ;; Do the conversion only post-reload to avoid limiting of the register class
8837 ;; to QI regs.
8838 (define_split
8839   [(set (match_operand 0 "flags_reg_operand" "")
8840         (match_operator 1 "compare_operator"
8841           [(and (match_operand 2 "register_operand" "")
8842                 (match_operand 3 "const_int_operand" ""))
8843            (const_int 0)]))]
8844    "reload_completed
8845     && QI_REG_P (operands[2])
8846     && GET_MODE (operands[2]) != QImode
8847     && ((ix86_match_ccmode (insn, CCZmode)
8848          && !(INTVAL (operands[3]) & ~(255 << 8)))
8849         || (ix86_match_ccmode (insn, CCNOmode)
8850             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8851   [(set (match_dup 0)
8852         (match_op_dup 1
8853           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8854                    (match_dup 3))
8855            (const_int 0)]))]
8856   "operands[2] = gen_lowpart (SImode, operands[2]);
8857    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8858
8859 (define_split
8860   [(set (match_operand 0 "flags_reg_operand" "")
8861         (match_operator 1 "compare_operator"
8862           [(and (match_operand 2 "nonimmediate_operand" "")
8863                 (match_operand 3 "const_int_operand" ""))
8864            (const_int 0)]))]
8865    "reload_completed
8866     && GET_MODE (operands[2]) != QImode
8867     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8868     && ((ix86_match_ccmode (insn, CCZmode)
8869          && !(INTVAL (operands[3]) & ~255))
8870         || (ix86_match_ccmode (insn, CCNOmode)
8871             && !(INTVAL (operands[3]) & ~127)))"
8872   [(set (match_dup 0)
8873         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8874                          (const_int 0)]))]
8875   "operands[2] = gen_lowpart (QImode, operands[2]);
8876    operands[3] = gen_lowpart (QImode, operands[3]);")
8877
8878
8879 ;; %%% This used to optimize known byte-wide and operations to memory,
8880 ;; and sometimes to QImode registers.  If this is considered useful,
8881 ;; it should be done with splitters.
8882
8883 (define_expand "anddi3"
8884   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8885         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8886                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8887    (clobber (reg:CC FLAGS_REG))]
8888   "TARGET_64BIT"
8889   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8890
8891 (define_insn "*anddi_1_rex64"
8892   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8893         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8894                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8895    (clobber (reg:CC FLAGS_REG))]
8896   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8897 {
8898   switch (get_attr_type (insn))
8899     {
8900     case TYPE_IMOVX:
8901       {
8902         enum machine_mode mode;
8903
8904         gcc_assert (CONST_INT_P (operands[2]));
8905         if (INTVAL (operands[2]) == 0xff)
8906           mode = QImode;
8907         else
8908           {
8909             gcc_assert (INTVAL (operands[2]) == 0xffff);
8910             mode = HImode;
8911           }
8912
8913         operands[1] = gen_lowpart (mode, operands[1]);
8914         if (mode == QImode)
8915           return "movz{bq|x}\t{%1,%0|%0, %1}";
8916         else
8917           return "movz{wq|x}\t{%1,%0|%0, %1}";
8918       }
8919
8920     default:
8921       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8922       if (get_attr_mode (insn) == MODE_SI)
8923         return "and{l}\t{%k2, %k0|%k0, %k2}";
8924       else
8925         return "and{q}\t{%2, %0|%0, %2}";
8926     }
8927 }
8928   [(set_attr "type" "alu,alu,alu,imovx")
8929    (set_attr "length_immediate" "*,*,*,0")
8930    (set_attr "mode" "SI,DI,DI,DI")])
8931
8932 (define_insn "*anddi_2"
8933   [(set (reg FLAGS_REG)
8934         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8935                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8936                  (const_int 0)))
8937    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8938         (and:DI (match_dup 1) (match_dup 2)))]
8939   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8940    && ix86_binary_operator_ok (AND, DImode, operands)"
8941   "@
8942    and{l}\t{%k2, %k0|%k0, %k2}
8943    and{q}\t{%2, %0|%0, %2}
8944    and{q}\t{%2, %0|%0, %2}"
8945   [(set_attr "type" "alu")
8946    (set_attr "mode" "SI,DI,DI")])
8947
8948 (define_expand "andsi3"
8949   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8950         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8951                 (match_operand:SI 2 "general_operand" "")))
8952    (clobber (reg:CC FLAGS_REG))]
8953   ""
8954   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8955
8956 (define_insn "*andsi_1"
8957   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8958         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8959                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8960    (clobber (reg:CC FLAGS_REG))]
8961   "ix86_binary_operator_ok (AND, SImode, operands)"
8962 {
8963   switch (get_attr_type (insn))
8964     {
8965     case TYPE_IMOVX:
8966       {
8967         enum machine_mode mode;
8968
8969         gcc_assert (CONST_INT_P (operands[2]));
8970         if (INTVAL (operands[2]) == 0xff)
8971           mode = QImode;
8972         else
8973           {
8974             gcc_assert (INTVAL (operands[2]) == 0xffff);
8975             mode = HImode;
8976           }
8977
8978         operands[1] = gen_lowpart (mode, operands[1]);
8979         if (mode == QImode)
8980           return "movz{bl|x}\t{%1,%0|%0, %1}";
8981         else
8982           return "movz{wl|x}\t{%1,%0|%0, %1}";
8983       }
8984
8985     default:
8986       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8987       return "and{l}\t{%2, %0|%0, %2}";
8988     }
8989 }
8990   [(set_attr "type" "alu,alu,imovx")
8991    (set_attr "length_immediate" "*,*,0")
8992    (set_attr "mode" "SI")])
8993
8994 (define_split
8995   [(set (match_operand 0 "register_operand" "")
8996         (and (match_dup 0)
8997              (const_int -65536)))
8998    (clobber (reg:CC FLAGS_REG))]
8999   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9000   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9001   "operands[1] = gen_lowpart (HImode, operands[0]);")
9002
9003 (define_split
9004   [(set (match_operand 0 "ext_register_operand" "")
9005         (and (match_dup 0)
9006              (const_int -256)))
9007    (clobber (reg:CC FLAGS_REG))]
9008   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9009   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9010   "operands[1] = gen_lowpart (QImode, operands[0]);")
9011
9012 (define_split
9013   [(set (match_operand 0 "ext_register_operand" "")
9014         (and (match_dup 0)
9015              (const_int -65281)))
9016    (clobber (reg:CC FLAGS_REG))]
9017   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9018   [(parallel [(set (zero_extract:SI (match_dup 0)
9019                                     (const_int 8)
9020                                     (const_int 8))
9021                    (xor:SI
9022                      (zero_extract:SI (match_dup 0)
9023                                       (const_int 8)
9024                                       (const_int 8))
9025                      (zero_extract:SI (match_dup 0)
9026                                       (const_int 8)
9027                                       (const_int 8))))
9028               (clobber (reg:CC FLAGS_REG))])]
9029   "operands[0] = gen_lowpart (SImode, operands[0]);")
9030
9031 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9032 (define_insn "*andsi_1_zext"
9033   [(set (match_operand:DI 0 "register_operand" "=r")
9034         (zero_extend:DI
9035           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9036                   (match_operand:SI 2 "general_operand" "g"))))
9037    (clobber (reg:CC FLAGS_REG))]
9038   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9039   "and{l}\t{%2, %k0|%k0, %2}"
9040   [(set_attr "type" "alu")
9041    (set_attr "mode" "SI")])
9042
9043 (define_insn "*andsi_2"
9044   [(set (reg FLAGS_REG)
9045         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9046                          (match_operand:SI 2 "general_operand" "g,ri"))
9047                  (const_int 0)))
9048    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9049         (and:SI (match_dup 1) (match_dup 2)))]
9050   "ix86_match_ccmode (insn, CCNOmode)
9051    && ix86_binary_operator_ok (AND, SImode, operands)"
9052   "and{l}\t{%2, %0|%0, %2}"
9053   [(set_attr "type" "alu")
9054    (set_attr "mode" "SI")])
9055
9056 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9057 (define_insn "*andsi_2_zext"
9058   [(set (reg FLAGS_REG)
9059         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9060                          (match_operand:SI 2 "general_operand" "g"))
9061                  (const_int 0)))
9062    (set (match_operand:DI 0 "register_operand" "=r")
9063         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9064   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9065    && ix86_binary_operator_ok (AND, SImode, operands)"
9066   "and{l}\t{%2, %k0|%k0, %2}"
9067   [(set_attr "type" "alu")
9068    (set_attr "mode" "SI")])
9069
9070 (define_expand "andhi3"
9071   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9072         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9073                 (match_operand:HI 2 "general_operand" "")))
9074    (clobber (reg:CC FLAGS_REG))]
9075   "TARGET_HIMODE_MATH"
9076   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9077
9078 (define_insn "*andhi_1"
9079   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9080         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9081                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
9082    (clobber (reg:CC FLAGS_REG))]
9083   "ix86_binary_operator_ok (AND, HImode, operands)"
9084 {
9085   switch (get_attr_type (insn))
9086     {
9087     case TYPE_IMOVX:
9088       gcc_assert (CONST_INT_P (operands[2]));
9089       gcc_assert (INTVAL (operands[2]) == 0xff);
9090       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9091
9092     default:
9093       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9094
9095       return "and{w}\t{%2, %0|%0, %2}";
9096     }
9097 }
9098   [(set_attr "type" "alu,alu,imovx")
9099    (set_attr "length_immediate" "*,*,0")
9100    (set_attr "mode" "HI,HI,SI")])
9101
9102 (define_insn "*andhi_2"
9103   [(set (reg FLAGS_REG)
9104         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9105                          (match_operand:HI 2 "general_operand" "g,ri"))
9106                  (const_int 0)))
9107    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9108         (and:HI (match_dup 1) (match_dup 2)))]
9109   "ix86_match_ccmode (insn, CCNOmode)
9110    && ix86_binary_operator_ok (AND, HImode, operands)"
9111   "and{w}\t{%2, %0|%0, %2}"
9112   [(set_attr "type" "alu")
9113    (set_attr "mode" "HI")])
9114
9115 (define_expand "andqi3"
9116   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9117         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9118                 (match_operand:QI 2 "general_operand" "")))
9119    (clobber (reg:CC FLAGS_REG))]
9120   "TARGET_QIMODE_MATH"
9121   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9122
9123 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9124 (define_insn "*andqi_1"
9125   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9126         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9127                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
9128    (clobber (reg:CC FLAGS_REG))]
9129   "ix86_binary_operator_ok (AND, QImode, operands)"
9130   "@
9131    and{b}\t{%2, %0|%0, %2}
9132    and{b}\t{%2, %0|%0, %2}
9133    and{l}\t{%k2, %k0|%k0, %k2}"
9134   [(set_attr "type" "alu")
9135    (set_attr "mode" "QI,QI,SI")])
9136
9137 (define_insn "*andqi_1_slp"
9138   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9139         (and:QI (match_dup 0)
9140                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9141    (clobber (reg:CC FLAGS_REG))]
9142   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9143    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9144   "and{b}\t{%1, %0|%0, %1}"
9145   [(set_attr "type" "alu1")
9146    (set_attr "mode" "QI")])
9147
9148 (define_insn "*andqi_2_maybe_si"
9149   [(set (reg FLAGS_REG)
9150         (compare (and:QI
9151                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9152                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
9153                  (const_int 0)))
9154    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9155         (and:QI (match_dup 1) (match_dup 2)))]
9156   "ix86_binary_operator_ok (AND, QImode, operands)
9157    && ix86_match_ccmode (insn,
9158                          CONST_INT_P (operands[2])
9159                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9160 {
9161   if (which_alternative == 2)
9162     {
9163       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9164         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9165       return "and{l}\t{%2, %k0|%k0, %2}";
9166     }
9167   return "and{b}\t{%2, %0|%0, %2}";
9168 }
9169   [(set_attr "type" "alu")
9170    (set_attr "mode" "QI,QI,SI")])
9171
9172 (define_insn "*andqi_2"
9173   [(set (reg FLAGS_REG)
9174         (compare (and:QI
9175                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9176                    (match_operand:QI 2 "general_operand" "qim,qi"))
9177                  (const_int 0)))
9178    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9179         (and:QI (match_dup 1) (match_dup 2)))]
9180   "ix86_match_ccmode (insn, CCNOmode)
9181    && ix86_binary_operator_ok (AND, QImode, operands)"
9182   "and{b}\t{%2, %0|%0, %2}"
9183   [(set_attr "type" "alu")
9184    (set_attr "mode" "QI")])
9185
9186 (define_insn "*andqi_2_slp"
9187   [(set (reg FLAGS_REG)
9188         (compare (and:QI
9189                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9190                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
9191                  (const_int 0)))
9192    (set (strict_low_part (match_dup 0))
9193         (and:QI (match_dup 0) (match_dup 1)))]
9194   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9195    && ix86_match_ccmode (insn, CCNOmode)
9196    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9197   "and{b}\t{%1, %0|%0, %1}"
9198   [(set_attr "type" "alu1")
9199    (set_attr "mode" "QI")])
9200
9201 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9202 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
9203 ;; for a QImode operand, which of course failed.
9204
9205 (define_insn "andqi_ext_0"
9206   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9207                          (const_int 8)
9208                          (const_int 8))
9209         (and:SI
9210           (zero_extract:SI
9211             (match_operand 1 "ext_register_operand" "0")
9212             (const_int 8)
9213             (const_int 8))
9214           (match_operand 2 "const_int_operand" "n")))
9215    (clobber (reg:CC FLAGS_REG))]
9216   ""
9217   "and{b}\t{%2, %h0|%h0, %2}"
9218   [(set_attr "type" "alu")
9219    (set_attr "length_immediate" "1")
9220    (set_attr "mode" "QI")])
9221
9222 ;; Generated by peephole translating test to and.  This shows up
9223 ;; often in fp comparisons.
9224
9225 (define_insn "*andqi_ext_0_cc"
9226   [(set (reg FLAGS_REG)
9227         (compare
9228           (and:SI
9229             (zero_extract:SI
9230               (match_operand 1 "ext_register_operand" "0")
9231               (const_int 8)
9232               (const_int 8))
9233             (match_operand 2 "const_int_operand" "n"))
9234           (const_int 0)))
9235    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9236                          (const_int 8)
9237                          (const_int 8))
9238         (and:SI
9239           (zero_extract:SI
9240             (match_dup 1)
9241             (const_int 8)
9242             (const_int 8))
9243           (match_dup 2)))]
9244   "ix86_match_ccmode (insn, CCNOmode)"
9245   "and{b}\t{%2, %h0|%h0, %2}"
9246   [(set_attr "type" "alu")
9247    (set_attr "length_immediate" "1")
9248    (set_attr "mode" "QI")])
9249
9250 (define_insn "*andqi_ext_1"
9251   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9252                          (const_int 8)
9253                          (const_int 8))
9254         (and:SI
9255           (zero_extract:SI
9256             (match_operand 1 "ext_register_operand" "0")
9257             (const_int 8)
9258             (const_int 8))
9259           (zero_extend:SI
9260             (match_operand:QI 2 "general_operand" "Qm"))))
9261    (clobber (reg:CC FLAGS_REG))]
9262   "!TARGET_64BIT"
9263   "and{b}\t{%2, %h0|%h0, %2}"
9264   [(set_attr "type" "alu")
9265    (set_attr "length_immediate" "0")
9266    (set_attr "mode" "QI")])
9267
9268 (define_insn "*andqi_ext_1_rex64"
9269   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9270                          (const_int 8)
9271                          (const_int 8))
9272         (and:SI
9273           (zero_extract:SI
9274             (match_operand 1 "ext_register_operand" "0")
9275             (const_int 8)
9276             (const_int 8))
9277           (zero_extend:SI
9278             (match_operand 2 "ext_register_operand" "Q"))))
9279    (clobber (reg:CC FLAGS_REG))]
9280   "TARGET_64BIT"
9281   "and{b}\t{%2, %h0|%h0, %2}"
9282   [(set_attr "type" "alu")
9283    (set_attr "length_immediate" "0")
9284    (set_attr "mode" "QI")])
9285
9286 (define_insn "*andqi_ext_2"
9287   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9288                          (const_int 8)
9289                          (const_int 8))
9290         (and:SI
9291           (zero_extract:SI
9292             (match_operand 1 "ext_register_operand" "%0")
9293             (const_int 8)
9294             (const_int 8))
9295           (zero_extract:SI
9296             (match_operand 2 "ext_register_operand" "Q")
9297             (const_int 8)
9298             (const_int 8))))
9299    (clobber (reg:CC FLAGS_REG))]
9300   ""
9301   "and{b}\t{%h2, %h0|%h0, %h2}"
9302   [(set_attr "type" "alu")
9303    (set_attr "length_immediate" "0")
9304    (set_attr "mode" "QI")])
9305
9306 ;; Convert wide AND instructions with immediate operand to shorter QImode
9307 ;; equivalents when possible.
9308 ;; Don't do the splitting with memory operands, since it introduces risk
9309 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9310 ;; for size, but that can (should?) be handled by generic code instead.
9311 (define_split
9312   [(set (match_operand 0 "register_operand" "")
9313         (and (match_operand 1 "register_operand" "")
9314              (match_operand 2 "const_int_operand" "")))
9315    (clobber (reg:CC FLAGS_REG))]
9316    "reload_completed
9317     && QI_REG_P (operands[0])
9318     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9319     && !(~INTVAL (operands[2]) & ~(255 << 8))
9320     && GET_MODE (operands[0]) != QImode"
9321   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9322                    (and:SI (zero_extract:SI (match_dup 1)
9323                                             (const_int 8) (const_int 8))
9324                            (match_dup 2)))
9325               (clobber (reg:CC FLAGS_REG))])]
9326   "operands[0] = gen_lowpart (SImode, operands[0]);
9327    operands[1] = gen_lowpart (SImode, operands[1]);
9328    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9329
9330 ;; Since AND can be encoded with sign extended immediate, this is only
9331 ;; profitable when 7th bit is not set.
9332 (define_split
9333   [(set (match_operand 0 "register_operand" "")
9334         (and (match_operand 1 "general_operand" "")
9335              (match_operand 2 "const_int_operand" "")))
9336    (clobber (reg:CC FLAGS_REG))]
9337    "reload_completed
9338     && ANY_QI_REG_P (operands[0])
9339     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9340     && !(~INTVAL (operands[2]) & ~255)
9341     && !(INTVAL (operands[2]) & 128)
9342     && GET_MODE (operands[0]) != QImode"
9343   [(parallel [(set (strict_low_part (match_dup 0))
9344                    (and:QI (match_dup 1)
9345                            (match_dup 2)))
9346               (clobber (reg:CC FLAGS_REG))])]
9347   "operands[0] = gen_lowpart (QImode, operands[0]);
9348    operands[1] = gen_lowpart (QImode, operands[1]);
9349    operands[2] = gen_lowpart (QImode, operands[2]);")
9350 \f
9351 ;; Logical inclusive OR instructions
9352
9353 ;; %%% This used to optimize known byte-wide and operations to memory.
9354 ;; If this is considered useful, it should be done with splitters.
9355
9356 (define_expand "iordi3"
9357   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9358         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9359                 (match_operand:DI 2 "x86_64_general_operand" "")))
9360    (clobber (reg:CC FLAGS_REG))]
9361   "TARGET_64BIT"
9362   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9363
9364 (define_insn "*iordi_1_rex64"
9365   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9366         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9367                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9368    (clobber (reg:CC FLAGS_REG))]
9369   "TARGET_64BIT
9370    && ix86_binary_operator_ok (IOR, DImode, operands)"
9371   "or{q}\t{%2, %0|%0, %2}"
9372   [(set_attr "type" "alu")
9373    (set_attr "mode" "DI")])
9374
9375 (define_insn "*iordi_2_rex64"
9376   [(set (reg FLAGS_REG)
9377         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9378                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9379                  (const_int 0)))
9380    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9381         (ior:DI (match_dup 1) (match_dup 2)))]
9382   "TARGET_64BIT
9383    && ix86_match_ccmode (insn, CCNOmode)
9384    && ix86_binary_operator_ok (IOR, DImode, operands)"
9385   "or{q}\t{%2, %0|%0, %2}"
9386   [(set_attr "type" "alu")
9387    (set_attr "mode" "DI")])
9388
9389 (define_insn "*iordi_3_rex64"
9390   [(set (reg FLAGS_REG)
9391         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9392                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9393                  (const_int 0)))
9394    (clobber (match_scratch:DI 0 "=r"))]
9395   "TARGET_64BIT
9396    && ix86_match_ccmode (insn, CCNOmode)
9397    && ix86_binary_operator_ok (IOR, DImode, operands)"
9398   "or{q}\t{%2, %0|%0, %2}"
9399   [(set_attr "type" "alu")
9400    (set_attr "mode" "DI")])
9401
9402
9403 (define_expand "iorsi3"
9404   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9405         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9406                 (match_operand:SI 2 "general_operand" "")))
9407    (clobber (reg:CC FLAGS_REG))]
9408   ""
9409   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9410
9411 (define_insn "*iorsi_1"
9412   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9413         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9414                 (match_operand:SI 2 "general_operand" "ri,g")))
9415    (clobber (reg:CC FLAGS_REG))]
9416   "ix86_binary_operator_ok (IOR, SImode, operands)"
9417   "or{l}\t{%2, %0|%0, %2}"
9418   [(set_attr "type" "alu")
9419    (set_attr "mode" "SI")])
9420
9421 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9422 (define_insn "*iorsi_1_zext"
9423   [(set (match_operand:DI 0 "register_operand" "=r")
9424         (zero_extend:DI
9425           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9426                   (match_operand:SI 2 "general_operand" "g"))))
9427    (clobber (reg:CC FLAGS_REG))]
9428   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9429   "or{l}\t{%2, %k0|%k0, %2}"
9430   [(set_attr "type" "alu")
9431    (set_attr "mode" "SI")])
9432
9433 (define_insn "*iorsi_1_zext_imm"
9434   [(set (match_operand:DI 0 "register_operand" "=r")
9435         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9436                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9437    (clobber (reg:CC FLAGS_REG))]
9438   "TARGET_64BIT"
9439   "or{l}\t{%2, %k0|%k0, %2}"
9440   [(set_attr "type" "alu")
9441    (set_attr "mode" "SI")])
9442
9443 (define_insn "*iorsi_2"
9444   [(set (reg FLAGS_REG)
9445         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9446                          (match_operand:SI 2 "general_operand" "g,ri"))
9447                  (const_int 0)))
9448    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9449         (ior:SI (match_dup 1) (match_dup 2)))]
9450   "ix86_match_ccmode (insn, CCNOmode)
9451    && ix86_binary_operator_ok (IOR, SImode, operands)"
9452   "or{l}\t{%2, %0|%0, %2}"
9453   [(set_attr "type" "alu")
9454    (set_attr "mode" "SI")])
9455
9456 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9457 ;; ??? Special case for immediate operand is missing - it is tricky.
9458 (define_insn "*iorsi_2_zext"
9459   [(set (reg FLAGS_REG)
9460         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9461                          (match_operand:SI 2 "general_operand" "g"))
9462                  (const_int 0)))
9463    (set (match_operand:DI 0 "register_operand" "=r")
9464         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9465   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9466    && ix86_binary_operator_ok (IOR, SImode, operands)"
9467   "or{l}\t{%2, %k0|%k0, %2}"
9468   [(set_attr "type" "alu")
9469    (set_attr "mode" "SI")])
9470
9471 (define_insn "*iorsi_2_zext_imm"
9472   [(set (reg FLAGS_REG)
9473         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9474                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9475                  (const_int 0)))
9476    (set (match_operand:DI 0 "register_operand" "=r")
9477         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9478   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9479    && ix86_binary_operator_ok (IOR, SImode, operands)"
9480   "or{l}\t{%2, %k0|%k0, %2}"
9481   [(set_attr "type" "alu")
9482    (set_attr "mode" "SI")])
9483
9484 (define_insn "*iorsi_3"
9485   [(set (reg FLAGS_REG)
9486         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9487                          (match_operand:SI 2 "general_operand" "g"))
9488                  (const_int 0)))
9489    (clobber (match_scratch:SI 0 "=r"))]
9490   "ix86_match_ccmode (insn, CCNOmode)
9491    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9492   "or{l}\t{%2, %0|%0, %2}"
9493   [(set_attr "type" "alu")
9494    (set_attr "mode" "SI")])
9495
9496 (define_expand "iorhi3"
9497   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9498         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9499                 (match_operand:HI 2 "general_operand" "")))
9500    (clobber (reg:CC FLAGS_REG))]
9501   "TARGET_HIMODE_MATH"
9502   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9503
9504 (define_insn "*iorhi_1"
9505   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9506         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9507                 (match_operand:HI 2 "general_operand" "g,ri")))
9508    (clobber (reg:CC FLAGS_REG))]
9509   "ix86_binary_operator_ok (IOR, HImode, operands)"
9510   "or{w}\t{%2, %0|%0, %2}"
9511   [(set_attr "type" "alu")
9512    (set_attr "mode" "HI")])
9513
9514 (define_insn "*iorhi_2"
9515   [(set (reg FLAGS_REG)
9516         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9517                          (match_operand:HI 2 "general_operand" "g,ri"))
9518                  (const_int 0)))
9519    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9520         (ior:HI (match_dup 1) (match_dup 2)))]
9521   "ix86_match_ccmode (insn, CCNOmode)
9522    && ix86_binary_operator_ok (IOR, HImode, operands)"
9523   "or{w}\t{%2, %0|%0, %2}"
9524   [(set_attr "type" "alu")
9525    (set_attr "mode" "HI")])
9526
9527 (define_insn "*iorhi_3"
9528   [(set (reg FLAGS_REG)
9529         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9530                          (match_operand:HI 2 "general_operand" "g"))
9531                  (const_int 0)))
9532    (clobber (match_scratch:HI 0 "=r"))]
9533   "ix86_match_ccmode (insn, CCNOmode)
9534    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9535   "or{w}\t{%2, %0|%0, %2}"
9536   [(set_attr "type" "alu")
9537    (set_attr "mode" "HI")])
9538
9539 (define_expand "iorqi3"
9540   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9541         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9542                 (match_operand:QI 2 "general_operand" "")))
9543    (clobber (reg:CC FLAGS_REG))]
9544   "TARGET_QIMODE_MATH"
9545   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9546
9547 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9548 (define_insn "*iorqi_1"
9549   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9550         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9551                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9552    (clobber (reg:CC FLAGS_REG))]
9553   "ix86_binary_operator_ok (IOR, QImode, operands)"
9554   "@
9555    or{b}\t{%2, %0|%0, %2}
9556    or{b}\t{%2, %0|%0, %2}
9557    or{l}\t{%k2, %k0|%k0, %k2}"
9558   [(set_attr "type" "alu")
9559    (set_attr "mode" "QI,QI,SI")])
9560
9561 (define_insn "*iorqi_1_slp"
9562   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9563         (ior:QI (match_dup 0)
9564                 (match_operand:QI 1 "general_operand" "qmi,qi")))
9565    (clobber (reg:CC FLAGS_REG))]
9566   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9567    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9568   "or{b}\t{%1, %0|%0, %1}"
9569   [(set_attr "type" "alu1")
9570    (set_attr "mode" "QI")])
9571
9572 (define_insn "*iorqi_2"
9573   [(set (reg FLAGS_REG)
9574         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9575                          (match_operand:QI 2 "general_operand" "qim,qi"))
9576                  (const_int 0)))
9577    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9578         (ior:QI (match_dup 1) (match_dup 2)))]
9579   "ix86_match_ccmode (insn, CCNOmode)
9580    && ix86_binary_operator_ok (IOR, QImode, operands)"
9581   "or{b}\t{%2, %0|%0, %2}"
9582   [(set_attr "type" "alu")
9583    (set_attr "mode" "QI")])
9584
9585 (define_insn "*iorqi_2_slp"
9586   [(set (reg FLAGS_REG)
9587         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9588                          (match_operand:QI 1 "general_operand" "qim,qi"))
9589                  (const_int 0)))
9590    (set (strict_low_part (match_dup 0))
9591         (ior:QI (match_dup 0) (match_dup 1)))]
9592   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9593    && ix86_match_ccmode (insn, CCNOmode)
9594    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9595   "or{b}\t{%1, %0|%0, %1}"
9596   [(set_attr "type" "alu1")
9597    (set_attr "mode" "QI")])
9598
9599 (define_insn "*iorqi_3"
9600   [(set (reg FLAGS_REG)
9601         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9602                          (match_operand:QI 2 "general_operand" "qim"))
9603                  (const_int 0)))
9604    (clobber (match_scratch:QI 0 "=q"))]
9605   "ix86_match_ccmode (insn, CCNOmode)
9606    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9607   "or{b}\t{%2, %0|%0, %2}"
9608   [(set_attr "type" "alu")
9609    (set_attr "mode" "QI")])
9610
9611 (define_insn "iorqi_ext_0"
9612   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9613                          (const_int 8)
9614                          (const_int 8))
9615         (ior:SI
9616           (zero_extract:SI
9617             (match_operand 1 "ext_register_operand" "0")
9618             (const_int 8)
9619             (const_int 8))
9620           (match_operand 2 "const_int_operand" "n")))
9621    (clobber (reg:CC FLAGS_REG))]
9622   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9623   "or{b}\t{%2, %h0|%h0, %2}"
9624   [(set_attr "type" "alu")
9625    (set_attr "length_immediate" "1")
9626    (set_attr "mode" "QI")])
9627
9628 (define_insn "*iorqi_ext_1"
9629   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9630                          (const_int 8)
9631                          (const_int 8))
9632         (ior:SI
9633           (zero_extract:SI
9634             (match_operand 1 "ext_register_operand" "0")
9635             (const_int 8)
9636             (const_int 8))
9637           (zero_extend:SI
9638             (match_operand:QI 2 "general_operand" "Qm"))))
9639    (clobber (reg:CC FLAGS_REG))]
9640   "!TARGET_64BIT
9641    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9642   "or{b}\t{%2, %h0|%h0, %2}"
9643   [(set_attr "type" "alu")
9644    (set_attr "length_immediate" "0")
9645    (set_attr "mode" "QI")])
9646
9647 (define_insn "*iorqi_ext_1_rex64"
9648   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9649                          (const_int 8)
9650                          (const_int 8))
9651         (ior:SI
9652           (zero_extract:SI
9653             (match_operand 1 "ext_register_operand" "0")
9654             (const_int 8)
9655             (const_int 8))
9656           (zero_extend:SI
9657             (match_operand 2 "ext_register_operand" "Q"))))
9658    (clobber (reg:CC FLAGS_REG))]
9659   "TARGET_64BIT
9660    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9661   "or{b}\t{%2, %h0|%h0, %2}"
9662   [(set_attr "type" "alu")
9663    (set_attr "length_immediate" "0")
9664    (set_attr "mode" "QI")])
9665
9666 (define_insn "*iorqi_ext_2"
9667   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9668                          (const_int 8)
9669                          (const_int 8))
9670         (ior:SI
9671           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9672                            (const_int 8)
9673                            (const_int 8))
9674           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9675                            (const_int 8)
9676                            (const_int 8))))
9677    (clobber (reg:CC FLAGS_REG))]
9678   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9679   "ior{b}\t{%h2, %h0|%h0, %h2}"
9680   [(set_attr "type" "alu")
9681    (set_attr "length_immediate" "0")
9682    (set_attr "mode" "QI")])
9683
9684 (define_split
9685   [(set (match_operand 0 "register_operand" "")
9686         (ior (match_operand 1 "register_operand" "")
9687              (match_operand 2 "const_int_operand" "")))
9688    (clobber (reg:CC FLAGS_REG))]
9689    "reload_completed
9690     && QI_REG_P (operands[0])
9691     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9692     && !(INTVAL (operands[2]) & ~(255 << 8))
9693     && GET_MODE (operands[0]) != QImode"
9694   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9695                    (ior:SI (zero_extract:SI (match_dup 1)
9696                                             (const_int 8) (const_int 8))
9697                            (match_dup 2)))
9698               (clobber (reg:CC FLAGS_REG))])]
9699   "operands[0] = gen_lowpart (SImode, operands[0]);
9700    operands[1] = gen_lowpart (SImode, operands[1]);
9701    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9702
9703 ;; Since OR can be encoded with sign extended immediate, this is only
9704 ;; profitable when 7th bit is set.
9705 (define_split
9706   [(set (match_operand 0 "register_operand" "")
9707         (ior (match_operand 1 "general_operand" "")
9708              (match_operand 2 "const_int_operand" "")))
9709    (clobber (reg:CC FLAGS_REG))]
9710    "reload_completed
9711     && ANY_QI_REG_P (operands[0])
9712     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9713     && !(INTVAL (operands[2]) & ~255)
9714     && (INTVAL (operands[2]) & 128)
9715     && GET_MODE (operands[0]) != QImode"
9716   [(parallel [(set (strict_low_part (match_dup 0))
9717                    (ior:QI (match_dup 1)
9718                            (match_dup 2)))
9719               (clobber (reg:CC FLAGS_REG))])]
9720   "operands[0] = gen_lowpart (QImode, operands[0]);
9721    operands[1] = gen_lowpart (QImode, operands[1]);
9722    operands[2] = gen_lowpart (QImode, operands[2]);")
9723 \f
9724 ;; Logical XOR instructions
9725
9726 ;; %%% This used to optimize known byte-wide and operations to memory.
9727 ;; If this is considered useful, it should be done with splitters.
9728
9729 (define_expand "xordi3"
9730   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9731         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9732                 (match_operand:DI 2 "x86_64_general_operand" "")))
9733    (clobber (reg:CC FLAGS_REG))]
9734   "TARGET_64BIT"
9735   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9736
9737 (define_insn "*xordi_1_rex64"
9738   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9739         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9740                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9741    (clobber (reg:CC FLAGS_REG))]
9742   "TARGET_64BIT
9743    && ix86_binary_operator_ok (XOR, DImode, operands)"
9744   "@
9745    xor{q}\t{%2, %0|%0, %2}
9746    xor{q}\t{%2, %0|%0, %2}"
9747   [(set_attr "type" "alu")
9748    (set_attr "mode" "DI,DI")])
9749
9750 (define_insn "*xordi_2_rex64"
9751   [(set (reg FLAGS_REG)
9752         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9753                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9754                  (const_int 0)))
9755    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9756         (xor:DI (match_dup 1) (match_dup 2)))]
9757   "TARGET_64BIT
9758    && ix86_match_ccmode (insn, CCNOmode)
9759    && ix86_binary_operator_ok (XOR, DImode, operands)"
9760   "@
9761    xor{q}\t{%2, %0|%0, %2}
9762    xor{q}\t{%2, %0|%0, %2}"
9763   [(set_attr "type" "alu")
9764    (set_attr "mode" "DI,DI")])
9765
9766 (define_insn "*xordi_3_rex64"
9767   [(set (reg FLAGS_REG)
9768         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9769                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9770                  (const_int 0)))
9771    (clobber (match_scratch:DI 0 "=r"))]
9772   "TARGET_64BIT
9773    && ix86_match_ccmode (insn, CCNOmode)
9774    && ix86_binary_operator_ok (XOR, DImode, operands)"
9775   "xor{q}\t{%2, %0|%0, %2}"
9776   [(set_attr "type" "alu")
9777    (set_attr "mode" "DI")])
9778
9779 (define_expand "xorsi3"
9780   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9781         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9782                 (match_operand:SI 2 "general_operand" "")))
9783    (clobber (reg:CC FLAGS_REG))]
9784   ""
9785   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9786
9787 (define_insn "*xorsi_1"
9788   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9789         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9790                 (match_operand:SI 2 "general_operand" "ri,rm")))
9791    (clobber (reg:CC FLAGS_REG))]
9792   "ix86_binary_operator_ok (XOR, SImode, operands)"
9793   "xor{l}\t{%2, %0|%0, %2}"
9794   [(set_attr "type" "alu")
9795    (set_attr "mode" "SI")])
9796
9797 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9798 ;; Add speccase for immediates
9799 (define_insn "*xorsi_1_zext"
9800   [(set (match_operand:DI 0 "register_operand" "=r")
9801         (zero_extend:DI
9802           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9803                   (match_operand:SI 2 "general_operand" "g"))))
9804    (clobber (reg:CC FLAGS_REG))]
9805   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9806   "xor{l}\t{%2, %k0|%k0, %2}"
9807   [(set_attr "type" "alu")
9808    (set_attr "mode" "SI")])
9809
9810 (define_insn "*xorsi_1_zext_imm"
9811   [(set (match_operand:DI 0 "register_operand" "=r")
9812         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9813                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9814    (clobber (reg:CC FLAGS_REG))]
9815   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9816   "xor{l}\t{%2, %k0|%k0, %2}"
9817   [(set_attr "type" "alu")
9818    (set_attr "mode" "SI")])
9819
9820 (define_insn "*xorsi_2"
9821   [(set (reg FLAGS_REG)
9822         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9823                          (match_operand:SI 2 "general_operand" "g,ri"))
9824                  (const_int 0)))
9825    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9826         (xor:SI (match_dup 1) (match_dup 2)))]
9827   "ix86_match_ccmode (insn, CCNOmode)
9828    && ix86_binary_operator_ok (XOR, SImode, operands)"
9829   "xor{l}\t{%2, %0|%0, %2}"
9830   [(set_attr "type" "alu")
9831    (set_attr "mode" "SI")])
9832
9833 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9834 ;; ??? Special case for immediate operand is missing - it is tricky.
9835 (define_insn "*xorsi_2_zext"
9836   [(set (reg FLAGS_REG)
9837         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9838                          (match_operand:SI 2 "general_operand" "g"))
9839                  (const_int 0)))
9840    (set (match_operand:DI 0 "register_operand" "=r")
9841         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9842   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9843    && ix86_binary_operator_ok (XOR, SImode, operands)"
9844   "xor{l}\t{%2, %k0|%k0, %2}"
9845   [(set_attr "type" "alu")
9846    (set_attr "mode" "SI")])
9847
9848 (define_insn "*xorsi_2_zext_imm"
9849   [(set (reg FLAGS_REG)
9850         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9851                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9852                  (const_int 0)))
9853    (set (match_operand:DI 0 "register_operand" "=r")
9854         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9855   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9856    && ix86_binary_operator_ok (XOR, SImode, operands)"
9857   "xor{l}\t{%2, %k0|%k0, %2}"
9858   [(set_attr "type" "alu")
9859    (set_attr "mode" "SI")])
9860
9861 (define_insn "*xorsi_3"
9862   [(set (reg FLAGS_REG)
9863         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9864                          (match_operand:SI 2 "general_operand" "g"))
9865                  (const_int 0)))
9866    (clobber (match_scratch:SI 0 "=r"))]
9867   "ix86_match_ccmode (insn, CCNOmode)
9868    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9869   "xor{l}\t{%2, %0|%0, %2}"
9870   [(set_attr "type" "alu")
9871    (set_attr "mode" "SI")])
9872
9873 (define_expand "xorhi3"
9874   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9875         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9876                 (match_operand:HI 2 "general_operand" "")))
9877    (clobber (reg:CC FLAGS_REG))]
9878   "TARGET_HIMODE_MATH"
9879   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9880
9881 (define_insn "*xorhi_1"
9882   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9883         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9884                 (match_operand:HI 2 "general_operand" "g,ri")))
9885    (clobber (reg:CC FLAGS_REG))]
9886   "ix86_binary_operator_ok (XOR, HImode, operands)"
9887   "xor{w}\t{%2, %0|%0, %2}"
9888   [(set_attr "type" "alu")
9889    (set_attr "mode" "HI")])
9890
9891 (define_insn "*xorhi_2"
9892   [(set (reg FLAGS_REG)
9893         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9894                          (match_operand:HI 2 "general_operand" "g,ri"))
9895                  (const_int 0)))
9896    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9897         (xor:HI (match_dup 1) (match_dup 2)))]
9898   "ix86_match_ccmode (insn, CCNOmode)
9899    && ix86_binary_operator_ok (XOR, HImode, operands)"
9900   "xor{w}\t{%2, %0|%0, %2}"
9901   [(set_attr "type" "alu")
9902    (set_attr "mode" "HI")])
9903
9904 (define_insn "*xorhi_3"
9905   [(set (reg FLAGS_REG)
9906         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9907                          (match_operand:HI 2 "general_operand" "g"))
9908                  (const_int 0)))
9909    (clobber (match_scratch:HI 0 "=r"))]
9910   "ix86_match_ccmode (insn, CCNOmode)
9911    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9912   "xor{w}\t{%2, %0|%0, %2}"
9913   [(set_attr "type" "alu")
9914    (set_attr "mode" "HI")])
9915
9916 (define_expand "xorqi3"
9917   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9918         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9919                 (match_operand:QI 2 "general_operand" "")))
9920    (clobber (reg:CC FLAGS_REG))]
9921   "TARGET_QIMODE_MATH"
9922   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9923
9924 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9925 (define_insn "*xorqi_1"
9926   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9927         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9928                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9929    (clobber (reg:CC FLAGS_REG))]
9930   "ix86_binary_operator_ok (XOR, QImode, operands)"
9931   "@
9932    xor{b}\t{%2, %0|%0, %2}
9933    xor{b}\t{%2, %0|%0, %2}
9934    xor{l}\t{%k2, %k0|%k0, %k2}"
9935   [(set_attr "type" "alu")
9936    (set_attr "mode" "QI,QI,SI")])
9937
9938 (define_insn "*xorqi_1_slp"
9939   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9940         (xor:QI (match_dup 0)
9941                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9942    (clobber (reg:CC FLAGS_REG))]
9943   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9944    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9945   "xor{b}\t{%1, %0|%0, %1}"
9946   [(set_attr "type" "alu1")
9947    (set_attr "mode" "QI")])
9948
9949 (define_insn "xorqi_ext_0"
9950   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9951                          (const_int 8)
9952                          (const_int 8))
9953         (xor:SI
9954           (zero_extract:SI
9955             (match_operand 1 "ext_register_operand" "0")
9956             (const_int 8)
9957             (const_int 8))
9958           (match_operand 2 "const_int_operand" "n")))
9959    (clobber (reg:CC FLAGS_REG))]
9960   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9961   "xor{b}\t{%2, %h0|%h0, %2}"
9962   [(set_attr "type" "alu")
9963    (set_attr "length_immediate" "1")
9964    (set_attr "mode" "QI")])
9965
9966 (define_insn "*xorqi_ext_1"
9967   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9968                          (const_int 8)
9969                          (const_int 8))
9970         (xor:SI
9971           (zero_extract:SI
9972             (match_operand 1 "ext_register_operand" "0")
9973             (const_int 8)
9974             (const_int 8))
9975           (zero_extend:SI
9976             (match_operand:QI 2 "general_operand" "Qm"))))
9977    (clobber (reg:CC FLAGS_REG))]
9978   "!TARGET_64BIT
9979    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9980   "xor{b}\t{%2, %h0|%h0, %2}"
9981   [(set_attr "type" "alu")
9982    (set_attr "length_immediate" "0")
9983    (set_attr "mode" "QI")])
9984
9985 (define_insn "*xorqi_ext_1_rex64"
9986   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9987                          (const_int 8)
9988                          (const_int 8))
9989         (xor:SI
9990           (zero_extract:SI
9991             (match_operand 1 "ext_register_operand" "0")
9992             (const_int 8)
9993             (const_int 8))
9994           (zero_extend:SI
9995             (match_operand 2 "ext_register_operand" "Q"))))
9996    (clobber (reg:CC FLAGS_REG))]
9997   "TARGET_64BIT
9998    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9999   "xor{b}\t{%2, %h0|%h0, %2}"
10000   [(set_attr "type" "alu")
10001    (set_attr "length_immediate" "0")
10002    (set_attr "mode" "QI")])
10003
10004 (define_insn "*xorqi_ext_2"
10005   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10006                          (const_int 8)
10007                          (const_int 8))
10008         (xor:SI
10009           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10010                            (const_int 8)
10011                            (const_int 8))
10012           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10013                            (const_int 8)
10014                            (const_int 8))))
10015    (clobber (reg:CC FLAGS_REG))]
10016   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
10017   "xor{b}\t{%h2, %h0|%h0, %h2}"
10018   [(set_attr "type" "alu")
10019    (set_attr "length_immediate" "0")
10020    (set_attr "mode" "QI")])
10021
10022 (define_insn "*xorqi_cc_1"
10023   [(set (reg FLAGS_REG)
10024         (compare
10025           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10026                   (match_operand:QI 2 "general_operand" "qim,qi"))
10027           (const_int 0)))
10028    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10029         (xor:QI (match_dup 1) (match_dup 2)))]
10030   "ix86_match_ccmode (insn, CCNOmode)
10031    && ix86_binary_operator_ok (XOR, QImode, operands)"
10032   "xor{b}\t{%2, %0|%0, %2}"
10033   [(set_attr "type" "alu")
10034    (set_attr "mode" "QI")])
10035
10036 (define_insn "*xorqi_2_slp"
10037   [(set (reg FLAGS_REG)
10038         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10039                          (match_operand:QI 1 "general_operand" "qim,qi"))
10040                  (const_int 0)))
10041    (set (strict_low_part (match_dup 0))
10042         (xor:QI (match_dup 0) (match_dup 1)))]
10043   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
10044    && ix86_match_ccmode (insn, CCNOmode)
10045    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10046   "xor{b}\t{%1, %0|%0, %1}"
10047   [(set_attr "type" "alu1")
10048    (set_attr "mode" "QI")])
10049
10050 (define_insn "*xorqi_cc_2"
10051   [(set (reg FLAGS_REG)
10052         (compare
10053           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10054                   (match_operand:QI 2 "general_operand" "qim"))
10055           (const_int 0)))
10056    (clobber (match_scratch:QI 0 "=q"))]
10057   "ix86_match_ccmode (insn, CCNOmode)
10058    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10059   "xor{b}\t{%2, %0|%0, %2}"
10060   [(set_attr "type" "alu")
10061    (set_attr "mode" "QI")])
10062
10063 (define_insn "*xorqi_cc_ext_1"
10064   [(set (reg FLAGS_REG)
10065         (compare
10066           (xor:SI
10067             (zero_extract:SI
10068               (match_operand 1 "ext_register_operand" "0")
10069               (const_int 8)
10070               (const_int 8))
10071             (match_operand:QI 2 "general_operand" "qmn"))
10072           (const_int 0)))
10073    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10074                          (const_int 8)
10075                          (const_int 8))
10076         (xor:SI
10077           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10078           (match_dup 2)))]
10079   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10080   "xor{b}\t{%2, %h0|%h0, %2}"
10081   [(set_attr "type" "alu")
10082    (set_attr "mode" "QI")])
10083
10084 (define_insn "*xorqi_cc_ext_1_rex64"
10085   [(set (reg FLAGS_REG)
10086         (compare
10087           (xor:SI
10088             (zero_extract:SI
10089               (match_operand 1 "ext_register_operand" "0")
10090               (const_int 8)
10091               (const_int 8))
10092             (match_operand:QI 2 "nonmemory_operand" "Qn"))
10093           (const_int 0)))
10094    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10095                          (const_int 8)
10096                          (const_int 8))
10097         (xor:SI
10098           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10099           (match_dup 2)))]
10100   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10101   "xor{b}\t{%2, %h0|%h0, %2}"
10102   [(set_attr "type" "alu")
10103    (set_attr "mode" "QI")])
10104
10105 (define_expand "xorqi_cc_ext_1"
10106   [(parallel [
10107      (set (reg:CCNO FLAGS_REG)
10108           (compare:CCNO
10109             (xor:SI
10110               (zero_extract:SI
10111                 (match_operand 1 "ext_register_operand" "")
10112                 (const_int 8)
10113                 (const_int 8))
10114               (match_operand:QI 2 "general_operand" ""))
10115             (const_int 0)))
10116      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10117                            (const_int 8)
10118                            (const_int 8))
10119           (xor:SI
10120             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10121             (match_dup 2)))])]
10122   ""
10123   "")
10124
10125 (define_split
10126   [(set (match_operand 0 "register_operand" "")
10127         (xor (match_operand 1 "register_operand" "")
10128              (match_operand 2 "const_int_operand" "")))
10129    (clobber (reg:CC FLAGS_REG))]
10130    "reload_completed
10131     && QI_REG_P (operands[0])
10132     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10133     && !(INTVAL (operands[2]) & ~(255 << 8))
10134     && GET_MODE (operands[0]) != QImode"
10135   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10136                    (xor:SI (zero_extract:SI (match_dup 1)
10137                                             (const_int 8) (const_int 8))
10138                            (match_dup 2)))
10139               (clobber (reg:CC FLAGS_REG))])]
10140   "operands[0] = gen_lowpart (SImode, operands[0]);
10141    operands[1] = gen_lowpart (SImode, operands[1]);
10142    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10143
10144 ;; Since XOR can be encoded with sign extended immediate, this is only
10145 ;; profitable when 7th bit is set.
10146 (define_split
10147   [(set (match_operand 0 "register_operand" "")
10148         (xor (match_operand 1 "general_operand" "")
10149              (match_operand 2 "const_int_operand" "")))
10150    (clobber (reg:CC FLAGS_REG))]
10151    "reload_completed
10152     && ANY_QI_REG_P (operands[0])
10153     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10154     && !(INTVAL (operands[2]) & ~255)
10155     && (INTVAL (operands[2]) & 128)
10156     && GET_MODE (operands[0]) != QImode"
10157   [(parallel [(set (strict_low_part (match_dup 0))
10158                    (xor:QI (match_dup 1)
10159                            (match_dup 2)))
10160               (clobber (reg:CC FLAGS_REG))])]
10161   "operands[0] = gen_lowpart (QImode, operands[0]);
10162    operands[1] = gen_lowpart (QImode, operands[1]);
10163    operands[2] = gen_lowpart (QImode, operands[2]);")
10164 \f
10165 ;; Negation instructions
10166
10167 (define_expand "negti2"
10168   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
10169                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10170               (clobber (reg:CC FLAGS_REG))])]
10171   "TARGET_64BIT"
10172   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10173
10174 (define_insn "*negti2_1"
10175   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10176         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10177    (clobber (reg:CC FLAGS_REG))]
10178   "TARGET_64BIT
10179    && ix86_unary_operator_ok (NEG, TImode, operands)"
10180   "#")
10181
10182 (define_split
10183   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10184         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10185    (clobber (reg:CC FLAGS_REG))]
10186   "TARGET_64BIT && reload_completed"
10187   [(parallel
10188     [(set (reg:CCZ FLAGS_REG)
10189           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
10190      (set (match_dup 0) (neg:DI (match_dup 2)))])
10191    (parallel
10192     [(set (match_dup 1)
10193           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10194                             (match_dup 3))
10195                    (const_int 0)))
10196      (clobber (reg:CC FLAGS_REG))])
10197    (parallel
10198     [(set (match_dup 1)
10199           (neg:DI (match_dup 1)))
10200      (clobber (reg:CC FLAGS_REG))])]
10201   "split_ti (operands+1, 1, operands+2, operands+3);
10202    split_ti (operands+0, 1, operands+0, operands+1);")
10203
10204 (define_expand "negdi2"
10205   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
10206                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
10207               (clobber (reg:CC FLAGS_REG))])]
10208   ""
10209   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10210
10211 (define_insn "*negdi2_1"
10212   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10213         (neg:DI (match_operand:DI 1 "general_operand" "0")))
10214    (clobber (reg:CC FLAGS_REG))]
10215   "!TARGET_64BIT
10216    && ix86_unary_operator_ok (NEG, DImode, operands)"
10217   "#")
10218
10219 (define_split
10220   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10221         (neg:DI (match_operand:DI 1 "general_operand" "")))
10222    (clobber (reg:CC FLAGS_REG))]
10223   "!TARGET_64BIT && reload_completed"
10224   [(parallel
10225     [(set (reg:CCZ FLAGS_REG)
10226           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
10227      (set (match_dup 0) (neg:SI (match_dup 2)))])
10228    (parallel
10229     [(set (match_dup 1)
10230           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10231                             (match_dup 3))
10232                    (const_int 0)))
10233      (clobber (reg:CC FLAGS_REG))])
10234    (parallel
10235     [(set (match_dup 1)
10236           (neg:SI (match_dup 1)))
10237      (clobber (reg:CC FLAGS_REG))])]
10238   "split_di (operands+1, 1, operands+2, operands+3);
10239    split_di (operands+0, 1, operands+0, operands+1);")
10240
10241 (define_insn "*negdi2_1_rex64"
10242   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10243         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10244    (clobber (reg:CC FLAGS_REG))]
10245   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10246   "neg{q}\t%0"
10247   [(set_attr "type" "negnot")
10248    (set_attr "mode" "DI")])
10249
10250 ;; The problem with neg is that it does not perform (compare x 0),
10251 ;; it really performs (compare 0 x), which leaves us with the zero
10252 ;; flag being the only useful item.
10253
10254 (define_insn "*negdi2_cmpz_rex64"
10255   [(set (reg:CCZ FLAGS_REG)
10256         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10257                      (const_int 0)))
10258    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10259         (neg:DI (match_dup 1)))]
10260   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10261   "neg{q}\t%0"
10262   [(set_attr "type" "negnot")
10263    (set_attr "mode" "DI")])
10264
10265
10266 (define_expand "negsi2"
10267   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
10268                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
10269               (clobber (reg:CC FLAGS_REG))])]
10270   ""
10271   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10272
10273 (define_insn "*negsi2_1"
10274   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10275         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10276    (clobber (reg:CC FLAGS_REG))]
10277   "ix86_unary_operator_ok (NEG, SImode, operands)"
10278   "neg{l}\t%0"
10279   [(set_attr "type" "negnot")
10280    (set_attr "mode" "SI")])
10281
10282 ;; Combine is quite creative about this pattern.
10283 (define_insn "*negsi2_1_zext"
10284   [(set (match_operand:DI 0 "register_operand" "=r")
10285         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10286                                         (const_int 32)))
10287                      (const_int 32)))
10288    (clobber (reg:CC FLAGS_REG))]
10289   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10290   "neg{l}\t%k0"
10291   [(set_attr "type" "negnot")
10292    (set_attr "mode" "SI")])
10293
10294 ;; The problem with neg is that it does not perform (compare x 0),
10295 ;; it really performs (compare 0 x), which leaves us with the zero
10296 ;; flag being the only useful item.
10297
10298 (define_insn "*negsi2_cmpz"
10299   [(set (reg:CCZ FLAGS_REG)
10300         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10301                      (const_int 0)))
10302    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10303         (neg:SI (match_dup 1)))]
10304   "ix86_unary_operator_ok (NEG, SImode, operands)"
10305   "neg{l}\t%0"
10306   [(set_attr "type" "negnot")
10307    (set_attr "mode" "SI")])
10308
10309 (define_insn "*negsi2_cmpz_zext"
10310   [(set (reg:CCZ FLAGS_REG)
10311         (compare:CCZ (lshiftrt:DI
10312                        (neg:DI (ashift:DI
10313                                  (match_operand:DI 1 "register_operand" "0")
10314                                  (const_int 32)))
10315                        (const_int 32))
10316                      (const_int 0)))
10317    (set (match_operand:DI 0 "register_operand" "=r")
10318         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10319                                         (const_int 32)))
10320                      (const_int 32)))]
10321   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10322   "neg{l}\t%k0"
10323   [(set_attr "type" "negnot")
10324    (set_attr "mode" "SI")])
10325
10326 (define_expand "neghi2"
10327   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
10328                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10329               (clobber (reg:CC FLAGS_REG))])]
10330   "TARGET_HIMODE_MATH"
10331   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10332
10333 (define_insn "*neghi2_1"
10334   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10335         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10336    (clobber (reg:CC FLAGS_REG))]
10337   "ix86_unary_operator_ok (NEG, HImode, operands)"
10338   "neg{w}\t%0"
10339   [(set_attr "type" "negnot")
10340    (set_attr "mode" "HI")])
10341
10342 (define_insn "*neghi2_cmpz"
10343   [(set (reg:CCZ FLAGS_REG)
10344         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10345                      (const_int 0)))
10346    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10347         (neg:HI (match_dup 1)))]
10348   "ix86_unary_operator_ok (NEG, HImode, operands)"
10349   "neg{w}\t%0"
10350   [(set_attr "type" "negnot")
10351    (set_attr "mode" "HI")])
10352
10353 (define_expand "negqi2"
10354   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10355                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10356               (clobber (reg:CC FLAGS_REG))])]
10357   "TARGET_QIMODE_MATH"
10358   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10359
10360 (define_insn "*negqi2_1"
10361   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10362         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10363    (clobber (reg:CC FLAGS_REG))]
10364   "ix86_unary_operator_ok (NEG, QImode, operands)"
10365   "neg{b}\t%0"
10366   [(set_attr "type" "negnot")
10367    (set_attr "mode" "QI")])
10368
10369 (define_insn "*negqi2_cmpz"
10370   [(set (reg:CCZ FLAGS_REG)
10371         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10372                      (const_int 0)))
10373    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10374         (neg:QI (match_dup 1)))]
10375   "ix86_unary_operator_ok (NEG, QImode, operands)"
10376   "neg{b}\t%0"
10377   [(set_attr "type" "negnot")
10378    (set_attr "mode" "QI")])
10379
10380 ;; Changing of sign for FP values is doable using integer unit too.
10381
10382 (define_expand "neg<mode>2"
10383   [(set (match_operand:X87MODEF 0 "register_operand" "")
10384         (neg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10385   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10386   "ix86_expand_fp_absneg_operator (NEG, <MODE>mode, operands); DONE;")
10387
10388 (define_expand "abs<mode>2"
10389   [(set (match_operand:X87MODEF 0 "register_operand" "")
10390         (abs:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10391   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10392   "ix86_expand_fp_absneg_operator (ABS, <MODE>mode, operands); DONE;")
10393
10394 (define_insn "*absneg<mode>2_mixed"
10395   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10396         (match_operator:MODEF 3 "absneg_operator"
10397           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10398    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10399    (clobber (reg:CC FLAGS_REG))]
10400   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10401   "#")
10402
10403 (define_insn "*absneg<mode>2_sse"
10404   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10405         (match_operator:MODEF 3 "absneg_operator"
10406           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10407    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10408    (clobber (reg:CC FLAGS_REG))]
10409   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10410   "#")
10411
10412 (define_insn "*absneg<mode>2_i387"
10413   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10414         (match_operator:X87MODEF 3 "absneg_operator"
10415           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10416    (use (match_operand 2 "" ""))
10417    (clobber (reg:CC FLAGS_REG))]
10418   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10419   "#")
10420
10421 (define_expand "negtf2"
10422   [(set (match_operand:TF 0 "register_operand" "")
10423         (neg:TF (match_operand:TF 1 "register_operand" "")))]
10424   "TARGET_64BIT"
10425   "ix86_expand_fp_absneg_operator (NEG, TFmode, operands); DONE;")
10426
10427 (define_expand "abstf2"
10428   [(set (match_operand:TF 0 "register_operand" "")
10429         (abs:TF (match_operand:TF 1 "register_operand" "")))]
10430   "TARGET_64BIT"
10431   "ix86_expand_fp_absneg_operator (ABS, TFmode, operands); DONE;")
10432
10433 (define_insn "*absnegtf2_sse"
10434   [(set (match_operand:TF 0 "register_operand" "=x,x")
10435         (match_operator:TF 3 "absneg_operator"
10436           [(match_operand:TF 1 "register_operand" "0,x")]))
10437    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10438    (clobber (reg:CC FLAGS_REG))]
10439   "TARGET_64BIT"
10440   "#")
10441
10442 ;; Splitters for fp abs and neg.
10443
10444 (define_split
10445   [(set (match_operand 0 "fp_register_operand" "")
10446         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10447    (use (match_operand 2 "" ""))
10448    (clobber (reg:CC FLAGS_REG))]
10449   "reload_completed"
10450   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10451
10452 (define_split
10453   [(set (match_operand 0 "register_operand" "")
10454         (match_operator 3 "absneg_operator"
10455           [(match_operand 1 "register_operand" "")]))
10456    (use (match_operand 2 "nonimmediate_operand" ""))
10457    (clobber (reg:CC FLAGS_REG))]
10458   "reload_completed && SSE_REG_P (operands[0])"
10459   [(set (match_dup 0) (match_dup 3))]
10460 {
10461   enum machine_mode mode = GET_MODE (operands[0]);
10462   enum machine_mode vmode = GET_MODE (operands[2]);
10463   rtx tmp;
10464
10465   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10466   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10467   if (operands_match_p (operands[0], operands[2]))
10468     {
10469       tmp = operands[1];
10470       operands[1] = operands[2];
10471       operands[2] = tmp;
10472     }
10473   if (GET_CODE (operands[3]) == ABS)
10474     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10475   else
10476     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10477   operands[3] = tmp;
10478 })
10479
10480 (define_split
10481   [(set (match_operand:SF 0 "register_operand" "")
10482         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10483    (use (match_operand:V4SF 2 "" ""))
10484    (clobber (reg:CC FLAGS_REG))]
10485   "reload_completed"
10486   [(parallel [(set (match_dup 0) (match_dup 1))
10487               (clobber (reg:CC FLAGS_REG))])]
10488 {
10489   rtx tmp;
10490   operands[0] = gen_lowpart (SImode, operands[0]);
10491   if (GET_CODE (operands[1]) == ABS)
10492     {
10493       tmp = gen_int_mode (0x7fffffff, SImode);
10494       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10495     }
10496   else
10497     {
10498       tmp = gen_int_mode (0x80000000, SImode);
10499       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10500     }
10501   operands[1] = tmp;
10502 })
10503
10504 (define_split
10505   [(set (match_operand:DF 0 "register_operand" "")
10506         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10507    (use (match_operand 2 "" ""))
10508    (clobber (reg:CC FLAGS_REG))]
10509   "reload_completed"
10510   [(parallel [(set (match_dup 0) (match_dup 1))
10511               (clobber (reg:CC FLAGS_REG))])]
10512 {
10513   rtx tmp;
10514   if (TARGET_64BIT)
10515     {
10516       tmp = gen_lowpart (DImode, operands[0]);
10517       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10518       operands[0] = tmp;
10519
10520       if (GET_CODE (operands[1]) == ABS)
10521         tmp = const0_rtx;
10522       else
10523         tmp = gen_rtx_NOT (DImode, tmp);
10524     }
10525   else
10526     {
10527       operands[0] = gen_highpart (SImode, operands[0]);
10528       if (GET_CODE (operands[1]) == ABS)
10529         {
10530           tmp = gen_int_mode (0x7fffffff, SImode);
10531           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10532         }
10533       else
10534         {
10535           tmp = gen_int_mode (0x80000000, SImode);
10536           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10537         }
10538     }
10539   operands[1] = tmp;
10540 })
10541
10542 (define_split
10543   [(set (match_operand:XF 0 "register_operand" "")
10544         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10545    (use (match_operand 2 "" ""))
10546    (clobber (reg:CC FLAGS_REG))]
10547   "reload_completed"
10548   [(parallel [(set (match_dup 0) (match_dup 1))
10549               (clobber (reg:CC FLAGS_REG))])]
10550 {
10551   rtx tmp;
10552   operands[0] = gen_rtx_REG (SImode,
10553                              true_regnum (operands[0])
10554                              + (TARGET_64BIT ? 1 : 2));
10555   if (GET_CODE (operands[1]) == ABS)
10556     {
10557       tmp = GEN_INT (0x7fff);
10558       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10559     }
10560   else
10561     {
10562       tmp = GEN_INT (0x8000);
10563       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10564     }
10565   operands[1] = tmp;
10566 })
10567
10568 ;; Conditionalize these after reload. If they match before reload, we
10569 ;; lose the clobber and ability to use integer instructions.
10570
10571 (define_insn "*neg<mode>2_1"
10572   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10573         (neg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10574   "TARGET_80387
10575    && (reload_completed || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10576   "fchs"
10577   [(set_attr "type" "fsgn")
10578    (set_attr "mode" "<MODE>")])
10579
10580 (define_insn "*abs<mode>2_1"
10581   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10582         (abs:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10583   "TARGET_80387
10584    && (reload_completed || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10585   "fabs"
10586   [(set_attr "type" "fsgn")
10587    (set_attr "mode" "<MODE>")])
10588
10589 (define_insn "*negextendsfdf2"
10590   [(set (match_operand:DF 0 "register_operand" "=f")
10591         (neg:DF (float_extend:DF
10592                   (match_operand:SF 1 "register_operand" "0"))))]
10593   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10594   "fchs"
10595   [(set_attr "type" "fsgn")
10596    (set_attr "mode" "DF")])
10597
10598 (define_insn "*negextenddfxf2"
10599   [(set (match_operand:XF 0 "register_operand" "=f")
10600         (neg:XF (float_extend:XF
10601                   (match_operand:DF 1 "register_operand" "0"))))]
10602   "TARGET_80387"
10603   "fchs"
10604   [(set_attr "type" "fsgn")
10605    (set_attr "mode" "XF")])
10606
10607 (define_insn "*negextendsfxf2"
10608   [(set (match_operand:XF 0 "register_operand" "=f")
10609         (neg:XF (float_extend:XF
10610                   (match_operand:SF 1 "register_operand" "0"))))]
10611   "TARGET_80387"
10612   "fchs"
10613   [(set_attr "type" "fsgn")
10614    (set_attr "mode" "XF")])
10615
10616 (define_insn "*absextendsfdf2"
10617   [(set (match_operand:DF 0 "register_operand" "=f")
10618         (abs:DF (float_extend:DF
10619                   (match_operand:SF 1 "register_operand" "0"))))]
10620   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10621   "fabs"
10622   [(set_attr "type" "fsgn")
10623    (set_attr "mode" "DF")])
10624
10625 (define_insn "*absextenddfxf2"
10626   [(set (match_operand:XF 0 "register_operand" "=f")
10627         (abs:XF (float_extend:XF
10628           (match_operand:DF 1 "register_operand" "0"))))]
10629   "TARGET_80387"
10630   "fabs"
10631   [(set_attr "type" "fsgn")
10632    (set_attr "mode" "XF")])
10633
10634 (define_insn "*absextendsfxf2"
10635   [(set (match_operand:XF 0 "register_operand" "=f")
10636         (abs:XF (float_extend:XF
10637           (match_operand:SF 1 "register_operand" "0"))))]
10638   "TARGET_80387"
10639   "fabs"
10640   [(set_attr "type" "fsgn")
10641    (set_attr "mode" "XF")])
10642
10643 ;; Copysign instructions
10644
10645 (define_mode_iterator CSGNMODE [SF DF TF])
10646 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10647
10648 (define_expand "copysign<mode>3"
10649   [(match_operand:CSGNMODE 0 "register_operand" "")
10650    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10651    (match_operand:CSGNMODE 2 "register_operand" "")]
10652   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10653    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10654 {
10655   ix86_expand_copysign (operands);
10656   DONE;
10657 })
10658
10659 (define_insn_and_split "copysign<mode>3_const"
10660   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10661         (unspec:CSGNMODE
10662           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10663            (match_operand:CSGNMODE 2 "register_operand" "0")
10664            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10665           UNSPEC_COPYSIGN))]
10666   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10667    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10668   "#"
10669   "&& reload_completed"
10670   [(const_int 0)]
10671 {
10672   ix86_split_copysign_const (operands);
10673   DONE;
10674 })
10675
10676 (define_insn "copysign<mode>3_var"
10677   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10678         (unspec:CSGNMODE
10679           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10680            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10681            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10682            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10683           UNSPEC_COPYSIGN))
10684    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10685   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10686    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10687   "#")
10688
10689 (define_split
10690   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10691         (unspec:CSGNMODE
10692           [(match_operand:CSGNMODE 2 "register_operand" "")
10693            (match_operand:CSGNMODE 3 "register_operand" "")
10694            (match_operand:<CSGNVMODE> 4 "" "")
10695            (match_operand:<CSGNVMODE> 5 "" "")]
10696           UNSPEC_COPYSIGN))
10697    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10698   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10699     || (TARGET_64BIT && (<MODE>mode == TFmode)))
10700    && reload_completed"
10701   [(const_int 0)]
10702 {
10703   ix86_split_copysign_var (operands);
10704   DONE;
10705 })
10706 \f
10707 ;; One complement instructions
10708
10709 (define_expand "one_cmpldi2"
10710   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10711         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10712   "TARGET_64BIT"
10713   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10714
10715 (define_insn "*one_cmpldi2_1_rex64"
10716   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10717         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10718   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10719   "not{q}\t%0"
10720   [(set_attr "type" "negnot")
10721    (set_attr "mode" "DI")])
10722
10723 (define_insn "*one_cmpldi2_2_rex64"
10724   [(set (reg FLAGS_REG)
10725         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10726                  (const_int 0)))
10727    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10728         (not:DI (match_dup 1)))]
10729   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10730    && ix86_unary_operator_ok (NOT, DImode, operands)"
10731   "#"
10732   [(set_attr "type" "alu1")
10733    (set_attr "mode" "DI")])
10734
10735 (define_split
10736   [(set (match_operand 0 "flags_reg_operand" "")
10737         (match_operator 2 "compare_operator"
10738           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10739            (const_int 0)]))
10740    (set (match_operand:DI 1 "nonimmediate_operand" "")
10741         (not:DI (match_dup 3)))]
10742   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10743   [(parallel [(set (match_dup 0)
10744                    (match_op_dup 2
10745                      [(xor:DI (match_dup 3) (const_int -1))
10746                       (const_int 0)]))
10747               (set (match_dup 1)
10748                    (xor:DI (match_dup 3) (const_int -1)))])]
10749   "")
10750
10751 (define_expand "one_cmplsi2"
10752   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10753         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10754   ""
10755   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10756
10757 (define_insn "*one_cmplsi2_1"
10758   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10759         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10760   "ix86_unary_operator_ok (NOT, SImode, operands)"
10761   "not{l}\t%0"
10762   [(set_attr "type" "negnot")
10763    (set_attr "mode" "SI")])
10764
10765 ;; ??? Currently never generated - xor is used instead.
10766 (define_insn "*one_cmplsi2_1_zext"
10767   [(set (match_operand:DI 0 "register_operand" "=r")
10768         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10769   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10770   "not{l}\t%k0"
10771   [(set_attr "type" "negnot")
10772    (set_attr "mode" "SI")])
10773
10774 (define_insn "*one_cmplsi2_2"
10775   [(set (reg FLAGS_REG)
10776         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10777                  (const_int 0)))
10778    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10779         (not:SI (match_dup 1)))]
10780   "ix86_match_ccmode (insn, CCNOmode)
10781    && ix86_unary_operator_ok (NOT, SImode, operands)"
10782   "#"
10783   [(set_attr "type" "alu1")
10784    (set_attr "mode" "SI")])
10785
10786 (define_split
10787   [(set (match_operand 0 "flags_reg_operand" "")
10788         (match_operator 2 "compare_operator"
10789           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10790            (const_int 0)]))
10791    (set (match_operand:SI 1 "nonimmediate_operand" "")
10792         (not:SI (match_dup 3)))]
10793   "ix86_match_ccmode (insn, CCNOmode)"
10794   [(parallel [(set (match_dup 0)
10795                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10796                                     (const_int 0)]))
10797               (set (match_dup 1)
10798                    (xor:SI (match_dup 3) (const_int -1)))])]
10799   "")
10800
10801 ;; ??? Currently never generated - xor is used instead.
10802 (define_insn "*one_cmplsi2_2_zext"
10803   [(set (reg FLAGS_REG)
10804         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10805                  (const_int 0)))
10806    (set (match_operand:DI 0 "register_operand" "=r")
10807         (zero_extend:DI (not:SI (match_dup 1))))]
10808   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10809    && ix86_unary_operator_ok (NOT, SImode, operands)"
10810   "#"
10811   [(set_attr "type" "alu1")
10812    (set_attr "mode" "SI")])
10813
10814 (define_split
10815   [(set (match_operand 0 "flags_reg_operand" "")
10816         (match_operator 2 "compare_operator"
10817           [(not:SI (match_operand:SI 3 "register_operand" ""))
10818            (const_int 0)]))
10819    (set (match_operand:DI 1 "register_operand" "")
10820         (zero_extend:DI (not:SI (match_dup 3))))]
10821   "ix86_match_ccmode (insn, CCNOmode)"
10822   [(parallel [(set (match_dup 0)
10823                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10824                                     (const_int 0)]))
10825               (set (match_dup 1)
10826                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10827   "")
10828
10829 (define_expand "one_cmplhi2"
10830   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10831         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10832   "TARGET_HIMODE_MATH"
10833   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10834
10835 (define_insn "*one_cmplhi2_1"
10836   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10837         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10838   "ix86_unary_operator_ok (NOT, HImode, operands)"
10839   "not{w}\t%0"
10840   [(set_attr "type" "negnot")
10841    (set_attr "mode" "HI")])
10842
10843 (define_insn "*one_cmplhi2_2"
10844   [(set (reg FLAGS_REG)
10845         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10846                  (const_int 0)))
10847    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10848         (not:HI (match_dup 1)))]
10849   "ix86_match_ccmode (insn, CCNOmode)
10850    && ix86_unary_operator_ok (NEG, HImode, operands)"
10851   "#"
10852   [(set_attr "type" "alu1")
10853    (set_attr "mode" "HI")])
10854
10855 (define_split
10856   [(set (match_operand 0 "flags_reg_operand" "")
10857         (match_operator 2 "compare_operator"
10858           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10859            (const_int 0)]))
10860    (set (match_operand:HI 1 "nonimmediate_operand" "")
10861         (not:HI (match_dup 3)))]
10862   "ix86_match_ccmode (insn, CCNOmode)"
10863   [(parallel [(set (match_dup 0)
10864                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10865                                     (const_int 0)]))
10866               (set (match_dup 1)
10867                    (xor:HI (match_dup 3) (const_int -1)))])]
10868   "")
10869
10870 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10871 (define_expand "one_cmplqi2"
10872   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10873         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10874   "TARGET_QIMODE_MATH"
10875   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10876
10877 (define_insn "*one_cmplqi2_1"
10878   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10879         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10880   "ix86_unary_operator_ok (NOT, QImode, operands)"
10881   "@
10882    not{b}\t%0
10883    not{l}\t%k0"
10884   [(set_attr "type" "negnot")
10885    (set_attr "mode" "QI,SI")])
10886
10887 (define_insn "*one_cmplqi2_2"
10888   [(set (reg FLAGS_REG)
10889         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10890                  (const_int 0)))
10891    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10892         (not:QI (match_dup 1)))]
10893   "ix86_match_ccmode (insn, CCNOmode)
10894    && ix86_unary_operator_ok (NOT, QImode, operands)"
10895   "#"
10896   [(set_attr "type" "alu1")
10897    (set_attr "mode" "QI")])
10898
10899 (define_split
10900   [(set (match_operand 0 "flags_reg_operand" "")
10901         (match_operator 2 "compare_operator"
10902           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10903            (const_int 0)]))
10904    (set (match_operand:QI 1 "nonimmediate_operand" "")
10905         (not:QI (match_dup 3)))]
10906   "ix86_match_ccmode (insn, CCNOmode)"
10907   [(parallel [(set (match_dup 0)
10908                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10909                                     (const_int 0)]))
10910               (set (match_dup 1)
10911                    (xor:QI (match_dup 3) (const_int -1)))])]
10912   "")
10913 \f
10914 ;; Arithmetic shift instructions
10915
10916 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10917 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10918 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10919 ;; from the assembler input.
10920 ;;
10921 ;; This instruction shifts the target reg/mem as usual, but instead of
10922 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10923 ;; is a left shift double, bits are taken from the high order bits of
10924 ;; reg, else if the insn is a shift right double, bits are taken from the
10925 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10926 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10927 ;;
10928 ;; Since sh[lr]d does not change the `reg' operand, that is done
10929 ;; separately, making all shifts emit pairs of shift double and normal
10930 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10931 ;; support a 63 bit shift, each shift where the count is in a reg expands
10932 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10933 ;;
10934 ;; If the shift count is a constant, we need never emit more than one
10935 ;; shift pair, instead using moves and sign extension for counts greater
10936 ;; than 31.
10937
10938 (define_expand "ashlti3"
10939   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10940                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10941                               (match_operand:QI 2 "nonmemory_operand" "")))
10942               (clobber (reg:CC FLAGS_REG))])]
10943   "TARGET_64BIT"
10944 {
10945   if (! immediate_operand (operands[2], QImode))
10946     {
10947       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10948       DONE;
10949     }
10950   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10951   DONE;
10952 })
10953
10954 (define_insn "ashlti3_1"
10955   [(set (match_operand:TI 0 "register_operand" "=r")
10956         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10957                    (match_operand:QI 2 "register_operand" "c")))
10958    (clobber (match_scratch:DI 3 "=&r"))
10959    (clobber (reg:CC FLAGS_REG))]
10960   "TARGET_64BIT"
10961   "#"
10962   [(set_attr "type" "multi")])
10963
10964 ;; This pattern must be defined before *ashlti3_2 to prevent
10965 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10966
10967 (define_insn "sse2_ashlti3"
10968   [(set (match_operand:TI 0 "register_operand" "=x")
10969         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10970                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10971   "TARGET_SSE2"
10972 {
10973   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10974   return "pslldq\t{%2, %0|%0, %2}";
10975 }
10976   [(set_attr "type" "sseishft")
10977    (set_attr "prefix_data16" "1")
10978    (set_attr "mode" "TI")])
10979
10980 (define_insn "*ashlti3_2"
10981   [(set (match_operand:TI 0 "register_operand" "=r")
10982         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10983                    (match_operand:QI 2 "immediate_operand" "O")))
10984    (clobber (reg:CC FLAGS_REG))]
10985   "TARGET_64BIT"
10986   "#"
10987   [(set_attr "type" "multi")])
10988
10989 (define_split
10990   [(set (match_operand:TI 0 "register_operand" "")
10991         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10992                    (match_operand:QI 2 "register_operand" "")))
10993    (clobber (match_scratch:DI 3 ""))
10994    (clobber (reg:CC FLAGS_REG))]
10995   "TARGET_64BIT && reload_completed"
10996   [(const_int 0)]
10997   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10998
10999 (define_split
11000   [(set (match_operand:TI 0 "register_operand" "")
11001         (ashift:TI (match_operand:TI 1 "register_operand" "")
11002                    (match_operand:QI 2 "immediate_operand" "")))
11003    (clobber (reg:CC FLAGS_REG))]
11004   "TARGET_64BIT && reload_completed"
11005   [(const_int 0)]
11006   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
11007
11008 (define_insn "x86_64_shld"
11009   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11010         (ior:DI (ashift:DI (match_dup 0)
11011                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11012                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
11013                   (minus:QI (const_int 64) (match_dup 2)))))
11014    (clobber (reg:CC FLAGS_REG))]
11015   "TARGET_64BIT"
11016   "@
11017    shld{q}\t{%2, %1, %0|%0, %1, %2}
11018    shld{q}\t{%s2%1, %0|%0, %1, %2}"
11019   [(set_attr "type" "ishift")
11020    (set_attr "prefix_0f" "1")
11021    (set_attr "mode" "DI")
11022    (set_attr "athlon_decode" "vector")
11023    (set_attr "amdfam10_decode" "vector")])
11024
11025 (define_expand "x86_64_shift_adj"
11026   [(set (reg:CCZ FLAGS_REG)
11027         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11028                              (const_int 64))
11029                      (const_int 0)))
11030    (set (match_operand:DI 0 "register_operand" "")
11031         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11032                          (match_operand:DI 1 "register_operand" "")
11033                          (match_dup 0)))
11034    (set (match_dup 1)
11035         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11036                          (match_operand:DI 3 "register_operand" "r")
11037                          (match_dup 1)))]
11038   "TARGET_64BIT"
11039   "")
11040
11041 (define_expand "ashldi3"
11042   [(set (match_operand:DI 0 "shiftdi_operand" "")
11043         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11044                    (match_operand:QI 2 "nonmemory_operand" "")))]
11045   ""
11046   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11047
11048 (define_insn "*ashldi3_1_rex64"
11049   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11050         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11051                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11052    (clobber (reg:CC FLAGS_REG))]
11053   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11054 {
11055   switch (get_attr_type (insn))
11056     {
11057     case TYPE_ALU:
11058       gcc_assert (operands[2] == const1_rtx);
11059       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11060       return "add{q}\t%0, %0";
11061
11062     case TYPE_LEA:
11063       gcc_assert (CONST_INT_P (operands[2]));
11064       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11065       operands[1] = gen_rtx_MULT (DImode, operands[1],
11066                                   GEN_INT (1 << INTVAL (operands[2])));
11067       return "lea{q}\t{%a1, %0|%0, %a1}";
11068
11069     default:
11070       if (REG_P (operands[2]))
11071         return "sal{q}\t{%b2, %0|%0, %b2}";
11072       else if (operands[2] == const1_rtx
11073                && (TARGET_SHIFT1 || optimize_size))
11074         return "sal{q}\t%0";
11075       else
11076         return "sal{q}\t{%2, %0|%0, %2}";
11077     }
11078 }
11079   [(set (attr "type")
11080      (cond [(eq_attr "alternative" "1")
11081               (const_string "lea")
11082             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11083                           (const_int 0))
11084                       (match_operand 0 "register_operand" ""))
11085                  (match_operand 2 "const1_operand" ""))
11086               (const_string "alu")
11087            ]
11088            (const_string "ishift")))
11089    (set_attr "mode" "DI")])
11090
11091 ;; Convert lea to the lea pattern to avoid flags dependency.
11092 (define_split
11093   [(set (match_operand:DI 0 "register_operand" "")
11094         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11095                    (match_operand:QI 2 "immediate_operand" "")))
11096    (clobber (reg:CC FLAGS_REG))]
11097   "TARGET_64BIT && reload_completed
11098    && true_regnum (operands[0]) != true_regnum (operands[1])"
11099   [(set (match_dup 0)
11100         (mult:DI (match_dup 1)
11101                  (match_dup 2)))]
11102   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11103
11104 ;; This pattern can't accept a variable shift count, since shifts by
11105 ;; zero don't affect the flags.  We assume that shifts by constant
11106 ;; zero are optimized away.
11107 (define_insn "*ashldi3_cmp_rex64"
11108   [(set (reg FLAGS_REG)
11109         (compare
11110           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11111                      (match_operand:QI 2 "immediate_operand" "e"))
11112           (const_int 0)))
11113    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11114         (ashift:DI (match_dup 1) (match_dup 2)))]
11115   "TARGET_64BIT
11116    && (optimize_size
11117        || !TARGET_PARTIAL_FLAG_REG_STALL
11118        || (operands[2] == const1_rtx
11119            && (TARGET_SHIFT1
11120                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11121    && ix86_match_ccmode (insn, CCGOCmode)
11122    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11123 {
11124   switch (get_attr_type (insn))
11125     {
11126     case TYPE_ALU:
11127       gcc_assert (operands[2] == const1_rtx);
11128       return "add{q}\t%0, %0";
11129
11130     default:
11131       if (REG_P (operands[2]))
11132         return "sal{q}\t{%b2, %0|%0, %b2}";
11133       else if (operands[2] == const1_rtx
11134                && (TARGET_SHIFT1 || optimize_size))
11135         return "sal{q}\t%0";
11136       else
11137         return "sal{q}\t{%2, %0|%0, %2}";
11138     }
11139 }
11140   [(set (attr "type")
11141      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11142                           (const_int 0))
11143                       (match_operand 0 "register_operand" ""))
11144                  (match_operand 2 "const1_operand" ""))
11145               (const_string "alu")
11146            ]
11147            (const_string "ishift")))
11148    (set_attr "mode" "DI")])
11149
11150 (define_insn "*ashldi3_cconly_rex64"
11151   [(set (reg FLAGS_REG)
11152         (compare
11153           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11154                      (match_operand:QI 2 "immediate_operand" "e"))
11155           (const_int 0)))
11156    (clobber (match_scratch:DI 0 "=r"))]
11157   "TARGET_64BIT
11158    && (optimize_size
11159        || !TARGET_PARTIAL_FLAG_REG_STALL
11160        || (operands[2] == const1_rtx
11161            && (TARGET_SHIFT1
11162                || TARGET_DOUBLE_WITH_ADD)))
11163    && ix86_match_ccmode (insn, CCGOCmode)
11164    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11165 {
11166   switch (get_attr_type (insn))
11167     {
11168     case TYPE_ALU:
11169       gcc_assert (operands[2] == const1_rtx);
11170       return "add{q}\t%0, %0";
11171
11172     default:
11173       if (REG_P (operands[2]))
11174         return "sal{q}\t{%b2, %0|%0, %b2}";
11175       else if (operands[2] == const1_rtx
11176                && (TARGET_SHIFT1 || optimize_size))
11177         return "sal{q}\t%0";
11178       else
11179         return "sal{q}\t{%2, %0|%0, %2}";
11180     }
11181 }
11182   [(set (attr "type")
11183      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11184                           (const_int 0))
11185                       (match_operand 0 "register_operand" ""))
11186                  (match_operand 2 "const1_operand" ""))
11187               (const_string "alu")
11188            ]
11189            (const_string "ishift")))
11190    (set_attr "mode" "DI")])
11191
11192 (define_insn "*ashldi3_1"
11193   [(set (match_operand:DI 0 "register_operand" "=&r,r")
11194         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11195                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11196    (clobber (reg:CC FLAGS_REG))]
11197   "!TARGET_64BIT"
11198   "#"
11199   [(set_attr "type" "multi")])
11200
11201 ;; By default we don't ask for a scratch register, because when DImode
11202 ;; values are manipulated, registers are already at a premium.  But if
11203 ;; we have one handy, we won't turn it away.
11204 (define_peephole2
11205   [(match_scratch:SI 3 "r")
11206    (parallel [(set (match_operand:DI 0 "register_operand" "")
11207                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11208                               (match_operand:QI 2 "nonmemory_operand" "")))
11209               (clobber (reg:CC FLAGS_REG))])
11210    (match_dup 3)]
11211   "!TARGET_64BIT && TARGET_CMOVE"
11212   [(const_int 0)]
11213   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11214
11215 (define_split
11216   [(set (match_operand:DI 0 "register_operand" "")
11217         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11218                    (match_operand:QI 2 "nonmemory_operand" "")))
11219    (clobber (reg:CC FLAGS_REG))]
11220   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11221                      ? epilogue_completed : reload_completed)"
11222   [(const_int 0)]
11223   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11224
11225 (define_insn "x86_shld_1"
11226   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11227         (ior:SI (ashift:SI (match_dup 0)
11228                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11229                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11230                   (minus:QI (const_int 32) (match_dup 2)))))
11231    (clobber (reg:CC FLAGS_REG))]
11232   ""
11233   "@
11234    shld{l}\t{%2, %1, %0|%0, %1, %2}
11235    shld{l}\t{%s2%1, %0|%0, %1, %2}"
11236   [(set_attr "type" "ishift")
11237    (set_attr "prefix_0f" "1")
11238    (set_attr "mode" "SI")
11239    (set_attr "pent_pair" "np")
11240    (set_attr "athlon_decode" "vector")
11241    (set_attr "amdfam10_decode" "vector")])
11242
11243 (define_expand "x86_shift_adj_1"
11244   [(set (reg:CCZ FLAGS_REG)
11245         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11246                              (const_int 32))
11247                      (const_int 0)))
11248    (set (match_operand:SI 0 "register_operand" "")
11249         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11250                          (match_operand:SI 1 "register_operand" "")
11251                          (match_dup 0)))
11252    (set (match_dup 1)
11253         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11254                          (match_operand:SI 3 "register_operand" "r")
11255                          (match_dup 1)))]
11256   "TARGET_CMOVE"
11257   "")
11258
11259 (define_expand "x86_shift_adj_2"
11260   [(use (match_operand:SI 0 "register_operand" ""))
11261    (use (match_operand:SI 1 "register_operand" ""))
11262    (use (match_operand:QI 2 "register_operand" ""))]
11263   ""
11264 {
11265   rtx label = gen_label_rtx ();
11266   rtx tmp;
11267
11268   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11269
11270   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11271   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11272   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11273                               gen_rtx_LABEL_REF (VOIDmode, label),
11274                               pc_rtx);
11275   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11276   JUMP_LABEL (tmp) = label;
11277
11278   emit_move_insn (operands[0], operands[1]);
11279   ix86_expand_clear (operands[1]);
11280
11281   emit_label (label);
11282   LABEL_NUSES (label) = 1;
11283
11284   DONE;
11285 })
11286
11287 (define_expand "ashlsi3"
11288   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11289         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11290                    (match_operand:QI 2 "nonmemory_operand" "")))
11291    (clobber (reg:CC FLAGS_REG))]
11292   ""
11293   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11294
11295 (define_insn "*ashlsi3_1"
11296   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11297         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11298                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11299    (clobber (reg:CC FLAGS_REG))]
11300   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11301 {
11302   switch (get_attr_type (insn))
11303     {
11304     case TYPE_ALU:
11305       gcc_assert (operands[2] == const1_rtx);
11306       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11307       return "add{l}\t%0, %0";
11308
11309     case TYPE_LEA:
11310       return "#";
11311
11312     default:
11313       if (REG_P (operands[2]))
11314         return "sal{l}\t{%b2, %0|%0, %b2}";
11315       else if (operands[2] == const1_rtx
11316                && (TARGET_SHIFT1 || optimize_size))
11317         return "sal{l}\t%0";
11318       else
11319         return "sal{l}\t{%2, %0|%0, %2}";
11320     }
11321 }
11322   [(set (attr "type")
11323      (cond [(eq_attr "alternative" "1")
11324               (const_string "lea")
11325             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11326                           (const_int 0))
11327                       (match_operand 0 "register_operand" ""))
11328                  (match_operand 2 "const1_operand" ""))
11329               (const_string "alu")
11330            ]
11331            (const_string "ishift")))
11332    (set_attr "mode" "SI")])
11333
11334 ;; Convert lea to the lea pattern to avoid flags dependency.
11335 (define_split
11336   [(set (match_operand 0 "register_operand" "")
11337         (ashift (match_operand 1 "index_register_operand" "")
11338                 (match_operand:QI 2 "const_int_operand" "")))
11339    (clobber (reg:CC FLAGS_REG))]
11340   "reload_completed
11341    && true_regnum (operands[0]) != true_regnum (operands[1])
11342    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11343   [(const_int 0)]
11344 {
11345   rtx pat;
11346   enum machine_mode mode = GET_MODE (operands[0]);
11347
11348   if (GET_MODE_SIZE (mode) < 4)
11349     operands[0] = gen_lowpart (SImode, operands[0]);
11350   if (mode != Pmode)
11351     operands[1] = gen_lowpart (Pmode, operands[1]);
11352   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11353
11354   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11355   if (Pmode != SImode)
11356     pat = gen_rtx_SUBREG (SImode, pat, 0);
11357   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11358   DONE;
11359 })
11360
11361 ;; Rare case of shifting RSP is handled by generating move and shift
11362 (define_split
11363   [(set (match_operand 0 "register_operand" "")
11364         (ashift (match_operand 1 "register_operand" "")
11365                 (match_operand:QI 2 "const_int_operand" "")))
11366    (clobber (reg:CC FLAGS_REG))]
11367   "reload_completed
11368    && true_regnum (operands[0]) != true_regnum (operands[1])"
11369   [(const_int 0)]
11370 {
11371   rtx pat, clob;
11372   emit_move_insn (operands[0], operands[1]);
11373   pat = gen_rtx_SET (VOIDmode, operands[0],
11374                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11375                                      operands[0], operands[2]));
11376   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11377   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11378   DONE;
11379 })
11380
11381 (define_insn "*ashlsi3_1_zext"
11382   [(set (match_operand:DI 0 "register_operand" "=r,r")
11383         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11384                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11385    (clobber (reg:CC FLAGS_REG))]
11386   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11387 {
11388   switch (get_attr_type (insn))
11389     {
11390     case TYPE_ALU:
11391       gcc_assert (operands[2] == const1_rtx);
11392       return "add{l}\t%k0, %k0";
11393
11394     case TYPE_LEA:
11395       return "#";
11396
11397     default:
11398       if (REG_P (operands[2]))
11399         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11400       else if (operands[2] == const1_rtx
11401                && (TARGET_SHIFT1 || optimize_size))
11402         return "sal{l}\t%k0";
11403       else
11404         return "sal{l}\t{%2, %k0|%k0, %2}";
11405     }
11406 }
11407   [(set (attr "type")
11408      (cond [(eq_attr "alternative" "1")
11409               (const_string "lea")
11410             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11411                      (const_int 0))
11412                  (match_operand 2 "const1_operand" ""))
11413               (const_string "alu")
11414            ]
11415            (const_string "ishift")))
11416    (set_attr "mode" "SI")])
11417
11418 ;; Convert lea to the lea pattern to avoid flags dependency.
11419 (define_split
11420   [(set (match_operand:DI 0 "register_operand" "")
11421         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11422                                 (match_operand:QI 2 "const_int_operand" ""))))
11423    (clobber (reg:CC FLAGS_REG))]
11424   "TARGET_64BIT && reload_completed
11425    && true_regnum (operands[0]) != true_regnum (operands[1])"
11426   [(set (match_dup 0) (zero_extend:DI
11427                         (subreg:SI (mult:SI (match_dup 1)
11428                                             (match_dup 2)) 0)))]
11429 {
11430   operands[1] = gen_lowpart (Pmode, operands[1]);
11431   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11432 })
11433
11434 ;; This pattern can't accept a variable shift count, since shifts by
11435 ;; zero don't affect the flags.  We assume that shifts by constant
11436 ;; zero are optimized away.
11437 (define_insn "*ashlsi3_cmp"
11438   [(set (reg FLAGS_REG)
11439         (compare
11440           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11441                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11442           (const_int 0)))
11443    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11444         (ashift:SI (match_dup 1) (match_dup 2)))]
11445    "(optimize_size
11446      || !TARGET_PARTIAL_FLAG_REG_STALL
11447      || (operands[2] == const1_rtx
11448          && (TARGET_SHIFT1
11449              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11450    && ix86_match_ccmode (insn, CCGOCmode)
11451    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11452 {
11453   switch (get_attr_type (insn))
11454     {
11455     case TYPE_ALU:
11456       gcc_assert (operands[2] == const1_rtx);
11457       return "add{l}\t%0, %0";
11458
11459     default:
11460       if (REG_P (operands[2]))
11461         return "sal{l}\t{%b2, %0|%0, %b2}";
11462       else if (operands[2] == const1_rtx
11463                && (TARGET_SHIFT1 || optimize_size))
11464         return "sal{l}\t%0";
11465       else
11466         return "sal{l}\t{%2, %0|%0, %2}";
11467     }
11468 }
11469   [(set (attr "type")
11470      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11471                           (const_int 0))
11472                       (match_operand 0 "register_operand" ""))
11473                  (match_operand 2 "const1_operand" ""))
11474               (const_string "alu")
11475            ]
11476            (const_string "ishift")))
11477    (set_attr "mode" "SI")])
11478
11479 (define_insn "*ashlsi3_cconly"
11480   [(set (reg FLAGS_REG)
11481         (compare
11482           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11483                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11484           (const_int 0)))
11485    (clobber (match_scratch:SI 0 "=r"))]
11486   "(optimize_size
11487     || !TARGET_PARTIAL_FLAG_REG_STALL
11488     || (operands[2] == const1_rtx
11489         && (TARGET_SHIFT1
11490             || TARGET_DOUBLE_WITH_ADD)))
11491    && ix86_match_ccmode (insn, CCGOCmode)
11492    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11493 {
11494   switch (get_attr_type (insn))
11495     {
11496     case TYPE_ALU:
11497       gcc_assert (operands[2] == const1_rtx);
11498       return "add{l}\t%0, %0";
11499
11500     default:
11501       if (REG_P (operands[2]))
11502         return "sal{l}\t{%b2, %0|%0, %b2}";
11503       else if (operands[2] == const1_rtx
11504                && (TARGET_SHIFT1 || optimize_size))
11505         return "sal{l}\t%0";
11506       else
11507         return "sal{l}\t{%2, %0|%0, %2}";
11508     }
11509 }
11510   [(set (attr "type")
11511      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11512                           (const_int 0))
11513                       (match_operand 0 "register_operand" ""))
11514                  (match_operand 2 "const1_operand" ""))
11515               (const_string "alu")
11516            ]
11517            (const_string "ishift")))
11518    (set_attr "mode" "SI")])
11519
11520 (define_insn "*ashlsi3_cmp_zext"
11521   [(set (reg FLAGS_REG)
11522         (compare
11523           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11524                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11525           (const_int 0)))
11526    (set (match_operand:DI 0 "register_operand" "=r")
11527         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11528   "TARGET_64BIT
11529    && (optimize_size
11530        || !TARGET_PARTIAL_FLAG_REG_STALL
11531        || (operands[2] == const1_rtx
11532            && (TARGET_SHIFT1
11533                || TARGET_DOUBLE_WITH_ADD)))
11534    && ix86_match_ccmode (insn, CCGOCmode)
11535    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11536 {
11537   switch (get_attr_type (insn))
11538     {
11539     case TYPE_ALU:
11540       gcc_assert (operands[2] == const1_rtx);
11541       return "add{l}\t%k0, %k0";
11542
11543     default:
11544       if (REG_P (operands[2]))
11545         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11546       else if (operands[2] == const1_rtx
11547                && (TARGET_SHIFT1 || optimize_size))
11548         return "sal{l}\t%k0";
11549       else
11550         return "sal{l}\t{%2, %k0|%k0, %2}";
11551     }
11552 }
11553   [(set (attr "type")
11554      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11555                      (const_int 0))
11556                  (match_operand 2 "const1_operand" ""))
11557               (const_string "alu")
11558            ]
11559            (const_string "ishift")))
11560    (set_attr "mode" "SI")])
11561
11562 (define_expand "ashlhi3"
11563   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11564         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11565                    (match_operand:QI 2 "nonmemory_operand" "")))
11566    (clobber (reg:CC FLAGS_REG))]
11567   "TARGET_HIMODE_MATH"
11568   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11569
11570 (define_insn "*ashlhi3_1_lea"
11571   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11572         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11573                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11574    (clobber (reg:CC FLAGS_REG))]
11575   "!TARGET_PARTIAL_REG_STALL
11576    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11577 {
11578   switch (get_attr_type (insn))
11579     {
11580     case TYPE_LEA:
11581       return "#";
11582     case TYPE_ALU:
11583       gcc_assert (operands[2] == const1_rtx);
11584       return "add{w}\t%0, %0";
11585
11586     default:
11587       if (REG_P (operands[2]))
11588         return "sal{w}\t{%b2, %0|%0, %b2}";
11589       else if (operands[2] == const1_rtx
11590                && (TARGET_SHIFT1 || optimize_size))
11591         return "sal{w}\t%0";
11592       else
11593         return "sal{w}\t{%2, %0|%0, %2}";
11594     }
11595 }
11596   [(set (attr "type")
11597      (cond [(eq_attr "alternative" "1")
11598               (const_string "lea")
11599             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11600                           (const_int 0))
11601                       (match_operand 0 "register_operand" ""))
11602                  (match_operand 2 "const1_operand" ""))
11603               (const_string "alu")
11604            ]
11605            (const_string "ishift")))
11606    (set_attr "mode" "HI,SI")])
11607
11608 (define_insn "*ashlhi3_1"
11609   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11610         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11611                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11612    (clobber (reg:CC FLAGS_REG))]
11613   "TARGET_PARTIAL_REG_STALL
11614    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11615 {
11616   switch (get_attr_type (insn))
11617     {
11618     case TYPE_ALU:
11619       gcc_assert (operands[2] == const1_rtx);
11620       return "add{w}\t%0, %0";
11621
11622     default:
11623       if (REG_P (operands[2]))
11624         return "sal{w}\t{%b2, %0|%0, %b2}";
11625       else if (operands[2] == const1_rtx
11626                && (TARGET_SHIFT1 || optimize_size))
11627         return "sal{w}\t%0";
11628       else
11629         return "sal{w}\t{%2, %0|%0, %2}";
11630     }
11631 }
11632   [(set (attr "type")
11633      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11634                           (const_int 0))
11635                       (match_operand 0 "register_operand" ""))
11636                  (match_operand 2 "const1_operand" ""))
11637               (const_string "alu")
11638            ]
11639            (const_string "ishift")))
11640    (set_attr "mode" "HI")])
11641
11642 ;; This pattern can't accept a variable shift count, since shifts by
11643 ;; zero don't affect the flags.  We assume that shifts by constant
11644 ;; zero are optimized away.
11645 (define_insn "*ashlhi3_cmp"
11646   [(set (reg FLAGS_REG)
11647         (compare
11648           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11649                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11650           (const_int 0)))
11651    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11652         (ashift:HI (match_dup 1) (match_dup 2)))]
11653   "(optimize_size
11654     || !TARGET_PARTIAL_FLAG_REG_STALL
11655     || (operands[2] == const1_rtx
11656         && (TARGET_SHIFT1
11657             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11658    && ix86_match_ccmode (insn, CCGOCmode)
11659    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11660 {
11661   switch (get_attr_type (insn))
11662     {
11663     case TYPE_ALU:
11664       gcc_assert (operands[2] == const1_rtx);
11665       return "add{w}\t%0, %0";
11666
11667     default:
11668       if (REG_P (operands[2]))
11669         return "sal{w}\t{%b2, %0|%0, %b2}";
11670       else if (operands[2] == const1_rtx
11671                && (TARGET_SHIFT1 || optimize_size))
11672         return "sal{w}\t%0";
11673       else
11674         return "sal{w}\t{%2, %0|%0, %2}";
11675     }
11676 }
11677   [(set (attr "type")
11678      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11679                           (const_int 0))
11680                       (match_operand 0 "register_operand" ""))
11681                  (match_operand 2 "const1_operand" ""))
11682               (const_string "alu")
11683            ]
11684            (const_string "ishift")))
11685    (set_attr "mode" "HI")])
11686
11687 (define_insn "*ashlhi3_cconly"
11688   [(set (reg FLAGS_REG)
11689         (compare
11690           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11691                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11692           (const_int 0)))
11693    (clobber (match_scratch:HI 0 "=r"))]
11694   "(optimize_size
11695     || !TARGET_PARTIAL_FLAG_REG_STALL
11696     || (operands[2] == const1_rtx
11697         && (TARGET_SHIFT1
11698             || TARGET_DOUBLE_WITH_ADD)))
11699    && ix86_match_ccmode (insn, CCGOCmode)
11700    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11701 {
11702   switch (get_attr_type (insn))
11703     {
11704     case TYPE_ALU:
11705       gcc_assert (operands[2] == const1_rtx);
11706       return "add{w}\t%0, %0";
11707
11708     default:
11709       if (REG_P (operands[2]))
11710         return "sal{w}\t{%b2, %0|%0, %b2}";
11711       else if (operands[2] == const1_rtx
11712                && (TARGET_SHIFT1 || optimize_size))
11713         return "sal{w}\t%0";
11714       else
11715         return "sal{w}\t{%2, %0|%0, %2}";
11716     }
11717 }
11718   [(set (attr "type")
11719      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11720                           (const_int 0))
11721                       (match_operand 0 "register_operand" ""))
11722                  (match_operand 2 "const1_operand" ""))
11723               (const_string "alu")
11724            ]
11725            (const_string "ishift")))
11726    (set_attr "mode" "HI")])
11727
11728 (define_expand "ashlqi3"
11729   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11730         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11731                    (match_operand:QI 2 "nonmemory_operand" "")))
11732    (clobber (reg:CC FLAGS_REG))]
11733   "TARGET_QIMODE_MATH"
11734   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11735
11736 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11737
11738 (define_insn "*ashlqi3_1_lea"
11739   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11740         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11741                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11742    (clobber (reg:CC FLAGS_REG))]
11743   "!TARGET_PARTIAL_REG_STALL
11744    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11745 {
11746   switch (get_attr_type (insn))
11747     {
11748     case TYPE_LEA:
11749       return "#";
11750     case TYPE_ALU:
11751       gcc_assert (operands[2] == const1_rtx);
11752       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11753         return "add{l}\t%k0, %k0";
11754       else
11755         return "add{b}\t%0, %0";
11756
11757     default:
11758       if (REG_P (operands[2]))
11759         {
11760           if (get_attr_mode (insn) == MODE_SI)
11761             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11762           else
11763             return "sal{b}\t{%b2, %0|%0, %b2}";
11764         }
11765       else if (operands[2] == const1_rtx
11766                && (TARGET_SHIFT1 || optimize_size))
11767         {
11768           if (get_attr_mode (insn) == MODE_SI)
11769             return "sal{l}\t%0";
11770           else
11771             return "sal{b}\t%0";
11772         }
11773       else
11774         {
11775           if (get_attr_mode (insn) == MODE_SI)
11776             return "sal{l}\t{%2, %k0|%k0, %2}";
11777           else
11778             return "sal{b}\t{%2, %0|%0, %2}";
11779         }
11780     }
11781 }
11782   [(set (attr "type")
11783      (cond [(eq_attr "alternative" "2")
11784               (const_string "lea")
11785             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11786                           (const_int 0))
11787                       (match_operand 0 "register_operand" ""))
11788                  (match_operand 2 "const1_operand" ""))
11789               (const_string "alu")
11790            ]
11791            (const_string "ishift")))
11792    (set_attr "mode" "QI,SI,SI")])
11793
11794 (define_insn "*ashlqi3_1"
11795   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11796         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11797                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11798    (clobber (reg:CC FLAGS_REG))]
11799   "TARGET_PARTIAL_REG_STALL
11800    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11801 {
11802   switch (get_attr_type (insn))
11803     {
11804     case TYPE_ALU:
11805       gcc_assert (operands[2] == const1_rtx);
11806       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11807         return "add{l}\t%k0, %k0";
11808       else
11809         return "add{b}\t%0, %0";
11810
11811     default:
11812       if (REG_P (operands[2]))
11813         {
11814           if (get_attr_mode (insn) == MODE_SI)
11815             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11816           else
11817             return "sal{b}\t{%b2, %0|%0, %b2}";
11818         }
11819       else if (operands[2] == const1_rtx
11820                && (TARGET_SHIFT1 || optimize_size))
11821         {
11822           if (get_attr_mode (insn) == MODE_SI)
11823             return "sal{l}\t%0";
11824           else
11825             return "sal{b}\t%0";
11826         }
11827       else
11828         {
11829           if (get_attr_mode (insn) == MODE_SI)
11830             return "sal{l}\t{%2, %k0|%k0, %2}";
11831           else
11832             return "sal{b}\t{%2, %0|%0, %2}";
11833         }
11834     }
11835 }
11836   [(set (attr "type")
11837      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11838                           (const_int 0))
11839                       (match_operand 0 "register_operand" ""))
11840                  (match_operand 2 "const1_operand" ""))
11841               (const_string "alu")
11842            ]
11843            (const_string "ishift")))
11844    (set_attr "mode" "QI,SI")])
11845
11846 ;; This pattern can't accept a variable shift count, since shifts by
11847 ;; zero don't affect the flags.  We assume that shifts by constant
11848 ;; zero are optimized away.
11849 (define_insn "*ashlqi3_cmp"
11850   [(set (reg FLAGS_REG)
11851         (compare
11852           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11853                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11854           (const_int 0)))
11855    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11856         (ashift:QI (match_dup 1) (match_dup 2)))]
11857   "(optimize_size
11858     || !TARGET_PARTIAL_FLAG_REG_STALL
11859     || (operands[2] == const1_rtx
11860         && (TARGET_SHIFT1
11861             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11862    && ix86_match_ccmode (insn, CCGOCmode)
11863    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11864 {
11865   switch (get_attr_type (insn))
11866     {
11867     case TYPE_ALU:
11868       gcc_assert (operands[2] == const1_rtx);
11869       return "add{b}\t%0, %0";
11870
11871     default:
11872       if (REG_P (operands[2]))
11873         return "sal{b}\t{%b2, %0|%0, %b2}";
11874       else if (operands[2] == const1_rtx
11875                && (TARGET_SHIFT1 || optimize_size))
11876         return "sal{b}\t%0";
11877       else
11878         return "sal{b}\t{%2, %0|%0, %2}";
11879     }
11880 }
11881   [(set (attr "type")
11882      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11883                           (const_int 0))
11884                       (match_operand 0 "register_operand" ""))
11885                  (match_operand 2 "const1_operand" ""))
11886               (const_string "alu")
11887            ]
11888            (const_string "ishift")))
11889    (set_attr "mode" "QI")])
11890
11891 (define_insn "*ashlqi3_cconly"
11892   [(set (reg FLAGS_REG)
11893         (compare
11894           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11895                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11896           (const_int 0)))
11897    (clobber (match_scratch:QI 0 "=q"))]
11898   "(optimize_size
11899     || !TARGET_PARTIAL_FLAG_REG_STALL
11900     || (operands[2] == const1_rtx
11901         && (TARGET_SHIFT1
11902             || TARGET_DOUBLE_WITH_ADD)))
11903    && ix86_match_ccmode (insn, CCGOCmode)
11904    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11905 {
11906   switch (get_attr_type (insn))
11907     {
11908     case TYPE_ALU:
11909       gcc_assert (operands[2] == const1_rtx);
11910       return "add{b}\t%0, %0";
11911
11912     default:
11913       if (REG_P (operands[2]))
11914         return "sal{b}\t{%b2, %0|%0, %b2}";
11915       else if (operands[2] == const1_rtx
11916                && (TARGET_SHIFT1 || optimize_size))
11917         return "sal{b}\t%0";
11918       else
11919         return "sal{b}\t{%2, %0|%0, %2}";
11920     }
11921 }
11922   [(set (attr "type")
11923      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11924                           (const_int 0))
11925                       (match_operand 0 "register_operand" ""))
11926                  (match_operand 2 "const1_operand" ""))
11927               (const_string "alu")
11928            ]
11929            (const_string "ishift")))
11930    (set_attr "mode" "QI")])
11931
11932 ;; See comment above `ashldi3' about how this works.
11933
11934 (define_expand "ashrti3"
11935   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11936                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11937                                 (match_operand:QI 2 "nonmemory_operand" "")))
11938               (clobber (reg:CC FLAGS_REG))])]
11939   "TARGET_64BIT"
11940 {
11941   if (! immediate_operand (operands[2], QImode))
11942     {
11943       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11944       DONE;
11945     }
11946   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11947   DONE;
11948 })
11949
11950 (define_insn "ashrti3_1"
11951   [(set (match_operand:TI 0 "register_operand" "=r")
11952         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11953                      (match_operand:QI 2 "register_operand" "c")))
11954    (clobber (match_scratch:DI 3 "=&r"))
11955    (clobber (reg:CC FLAGS_REG))]
11956   "TARGET_64BIT"
11957   "#"
11958   [(set_attr "type" "multi")])
11959
11960 (define_insn "*ashrti3_2"
11961   [(set (match_operand:TI 0 "register_operand" "=r")
11962         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11963                      (match_operand:QI 2 "immediate_operand" "O")))
11964    (clobber (reg:CC FLAGS_REG))]
11965   "TARGET_64BIT"
11966   "#"
11967   [(set_attr "type" "multi")])
11968
11969 (define_split
11970   [(set (match_operand:TI 0 "register_operand" "")
11971         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11972                      (match_operand:QI 2 "register_operand" "")))
11973    (clobber (match_scratch:DI 3 ""))
11974    (clobber (reg:CC FLAGS_REG))]
11975   "TARGET_64BIT && reload_completed"
11976   [(const_int 0)]
11977   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11978
11979 (define_split
11980   [(set (match_operand:TI 0 "register_operand" "")
11981         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11982                      (match_operand:QI 2 "immediate_operand" "")))
11983    (clobber (reg:CC FLAGS_REG))]
11984   "TARGET_64BIT && reload_completed"
11985   [(const_int 0)]
11986   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11987
11988 (define_insn "x86_64_shrd"
11989   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11990         (ior:DI (ashiftrt:DI (match_dup 0)
11991                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11992                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11993                   (minus:QI (const_int 64) (match_dup 2)))))
11994    (clobber (reg:CC FLAGS_REG))]
11995   "TARGET_64BIT"
11996   "@
11997    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11998    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11999   [(set_attr "type" "ishift")
12000    (set_attr "prefix_0f" "1")
12001    (set_attr "mode" "DI")
12002    (set_attr "athlon_decode" "vector")
12003    (set_attr "amdfam10_decode" "vector")])
12004
12005 (define_expand "ashrdi3"
12006   [(set (match_operand:DI 0 "shiftdi_operand" "")
12007         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12008                      (match_operand:QI 2 "nonmemory_operand" "")))]
12009   ""
12010   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
12011
12012 (define_insn "*ashrdi3_63_rex64"
12013   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
12014         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
12015                      (match_operand:DI 2 "const_int_operand" "i,i")))
12016    (clobber (reg:CC FLAGS_REG))]
12017   "TARGET_64BIT && INTVAL (operands[2]) == 63
12018    && (TARGET_USE_CLTD || optimize_size)
12019    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12020   "@
12021    {cqto|cqo}
12022    sar{q}\t{%2, %0|%0, %2}"
12023   [(set_attr "type" "imovx,ishift")
12024    (set_attr "prefix_0f" "0,*")
12025    (set_attr "length_immediate" "0,*")
12026    (set_attr "modrm" "0,1")
12027    (set_attr "mode" "DI")])
12028
12029 (define_insn "*ashrdi3_1_one_bit_rex64"
12030   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12031         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12032                      (match_operand:QI 2 "const1_operand" "")))
12033    (clobber (reg:CC FLAGS_REG))]
12034   "TARGET_64BIT
12035    && (TARGET_SHIFT1 || optimize_size)
12036    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12037   "sar{q}\t%0"
12038   [(set_attr "type" "ishift")
12039    (set (attr "length")
12040      (if_then_else (match_operand:DI 0 "register_operand" "")
12041         (const_string "2")
12042         (const_string "*")))])
12043
12044 (define_insn "*ashrdi3_1_rex64"
12045   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12046         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12047                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12048    (clobber (reg:CC FLAGS_REG))]
12049   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12050   "@
12051    sar{q}\t{%2, %0|%0, %2}
12052    sar{q}\t{%b2, %0|%0, %b2}"
12053   [(set_attr "type" "ishift")
12054    (set_attr "mode" "DI")])
12055
12056 ;; This pattern can't accept a variable shift count, since shifts by
12057 ;; zero don't affect the flags.  We assume that shifts by constant
12058 ;; zero are optimized away.
12059 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12060   [(set (reg FLAGS_REG)
12061         (compare
12062           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12063                        (match_operand:QI 2 "const1_operand" ""))
12064           (const_int 0)))
12065    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12066         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12067   "TARGET_64BIT
12068    && (TARGET_SHIFT1 || optimize_size)
12069    && ix86_match_ccmode (insn, CCGOCmode)
12070    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12071   "sar{q}\t%0"
12072   [(set_attr "type" "ishift")
12073    (set (attr "length")
12074      (if_then_else (match_operand:DI 0 "register_operand" "")
12075         (const_string "2")
12076         (const_string "*")))])
12077
12078 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12079   [(set (reg FLAGS_REG)
12080         (compare
12081           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12082                        (match_operand:QI 2 "const1_operand" ""))
12083           (const_int 0)))
12084    (clobber (match_scratch:DI 0 "=r"))]
12085   "TARGET_64BIT
12086    && (TARGET_SHIFT1 || optimize_size)
12087    && ix86_match_ccmode (insn, CCGOCmode)
12088    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12089   "sar{q}\t%0"
12090   [(set_attr "type" "ishift")
12091    (set_attr "length" "2")])
12092
12093 ;; This pattern can't accept a variable shift count, since shifts by
12094 ;; zero don't affect the flags.  We assume that shifts by constant
12095 ;; zero are optimized away.
12096 (define_insn "*ashrdi3_cmp_rex64"
12097   [(set (reg FLAGS_REG)
12098         (compare
12099           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12100                        (match_operand:QI 2 "const_int_operand" "n"))
12101           (const_int 0)))
12102    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12103         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12104   "TARGET_64BIT
12105    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12106    && ix86_match_ccmode (insn, CCGOCmode)
12107    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12108   "sar{q}\t{%2, %0|%0, %2}"
12109   [(set_attr "type" "ishift")
12110    (set_attr "mode" "DI")])
12111
12112 (define_insn "*ashrdi3_cconly_rex64"
12113   [(set (reg FLAGS_REG)
12114         (compare
12115           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12116                        (match_operand:QI 2 "const_int_operand" "n"))
12117           (const_int 0)))
12118    (clobber (match_scratch:DI 0 "=r"))]
12119   "TARGET_64BIT
12120    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12121    && ix86_match_ccmode (insn, CCGOCmode)
12122    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12123   "sar{q}\t{%2, %0|%0, %2}"
12124   [(set_attr "type" "ishift")
12125    (set_attr "mode" "DI")])
12126
12127 (define_insn "*ashrdi3_1"
12128   [(set (match_operand:DI 0 "register_operand" "=r")
12129         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12130                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12131    (clobber (reg:CC FLAGS_REG))]
12132   "!TARGET_64BIT"
12133   "#"
12134   [(set_attr "type" "multi")])
12135
12136 ;; By default we don't ask for a scratch register, because when DImode
12137 ;; values are manipulated, registers are already at a premium.  But if
12138 ;; we have one handy, we won't turn it away.
12139 (define_peephole2
12140   [(match_scratch:SI 3 "r")
12141    (parallel [(set (match_operand:DI 0 "register_operand" "")
12142                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12143                                 (match_operand:QI 2 "nonmemory_operand" "")))
12144               (clobber (reg:CC FLAGS_REG))])
12145    (match_dup 3)]
12146   "!TARGET_64BIT && TARGET_CMOVE"
12147   [(const_int 0)]
12148   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12149
12150 (define_split
12151   [(set (match_operand:DI 0 "register_operand" "")
12152         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12153                      (match_operand:QI 2 "nonmemory_operand" "")))
12154    (clobber (reg:CC FLAGS_REG))]
12155   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12156                      ? epilogue_completed : reload_completed)"
12157   [(const_int 0)]
12158   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12159
12160 (define_insn "x86_shrd_1"
12161   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
12162         (ior:SI (ashiftrt:SI (match_dup 0)
12163                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
12164                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
12165                   (minus:QI (const_int 32) (match_dup 2)))))
12166    (clobber (reg:CC FLAGS_REG))]
12167   ""
12168   "@
12169    shrd{l}\t{%2, %1, %0|%0, %1, %2}
12170    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12171   [(set_attr "type" "ishift")
12172    (set_attr "prefix_0f" "1")
12173    (set_attr "pent_pair" "np")
12174    (set_attr "mode" "SI")])
12175
12176 (define_expand "x86_shift_adj_3"
12177   [(use (match_operand:SI 0 "register_operand" ""))
12178    (use (match_operand:SI 1 "register_operand" ""))
12179    (use (match_operand:QI 2 "register_operand" ""))]
12180   ""
12181 {
12182   rtx label = gen_label_rtx ();
12183   rtx tmp;
12184
12185   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12186
12187   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12188   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12189   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12190                               gen_rtx_LABEL_REF (VOIDmode, label),
12191                               pc_rtx);
12192   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12193   JUMP_LABEL (tmp) = label;
12194
12195   emit_move_insn (operands[0], operands[1]);
12196   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12197
12198   emit_label (label);
12199   LABEL_NUSES (label) = 1;
12200
12201   DONE;
12202 })
12203
12204 (define_insn "ashrsi3_31"
12205   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12206         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12207                      (match_operand:SI 2 "const_int_operand" "i,i")))
12208    (clobber (reg:CC FLAGS_REG))]
12209   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12210    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12211   "@
12212    {cltd|cdq}
12213    sar{l}\t{%2, %0|%0, %2}"
12214   [(set_attr "type" "imovx,ishift")
12215    (set_attr "prefix_0f" "0,*")
12216    (set_attr "length_immediate" "0,*")
12217    (set_attr "modrm" "0,1")
12218    (set_attr "mode" "SI")])
12219
12220 (define_insn "*ashrsi3_31_zext"
12221   [(set (match_operand:DI 0 "register_operand" "=*d,r")
12222         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12223                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
12224    (clobber (reg:CC FLAGS_REG))]
12225   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12226    && INTVAL (operands[2]) == 31
12227    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12228   "@
12229    {cltd|cdq}
12230    sar{l}\t{%2, %k0|%k0, %2}"
12231   [(set_attr "type" "imovx,ishift")
12232    (set_attr "prefix_0f" "0,*")
12233    (set_attr "length_immediate" "0,*")
12234    (set_attr "modrm" "0,1")
12235    (set_attr "mode" "SI")])
12236
12237 (define_expand "ashrsi3"
12238   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12239         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12240                      (match_operand:QI 2 "nonmemory_operand" "")))
12241    (clobber (reg:CC FLAGS_REG))]
12242   ""
12243   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12244
12245 (define_insn "*ashrsi3_1_one_bit"
12246   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12247         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12248                      (match_operand:QI 2 "const1_operand" "")))
12249    (clobber (reg:CC FLAGS_REG))]
12250   "(TARGET_SHIFT1 || optimize_size)
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_1_one_bit_zext"
12260   [(set (match_operand:DI 0 "register_operand" "=r")
12261         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12262                                      (match_operand:QI 2 "const1_operand" ""))))
12263    (clobber (reg:CC FLAGS_REG))]
12264   "TARGET_64BIT
12265    && (TARGET_SHIFT1 || optimize_size)
12266    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12267   "sar{l}\t%k0"
12268   [(set_attr "type" "ishift")
12269    (set_attr "length" "2")])
12270
12271 (define_insn "*ashrsi3_1"
12272   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12273         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12274                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12275    (clobber (reg:CC FLAGS_REG))]
12276   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12277   "@
12278    sar{l}\t{%2, %0|%0, %2}
12279    sar{l}\t{%b2, %0|%0, %b2}"
12280   [(set_attr "type" "ishift")
12281    (set_attr "mode" "SI")])
12282
12283 (define_insn "*ashrsi3_1_zext"
12284   [(set (match_operand:DI 0 "register_operand" "=r,r")
12285         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12286                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12287    (clobber (reg:CC FLAGS_REG))]
12288   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12289   "@
12290    sar{l}\t{%2, %k0|%k0, %2}
12291    sar{l}\t{%b2, %k0|%k0, %b2}"
12292   [(set_attr "type" "ishift")
12293    (set_attr "mode" "SI")])
12294
12295 ;; This pattern can't accept a variable shift count, since shifts by
12296 ;; zero don't affect the flags.  We assume that shifts by constant
12297 ;; zero are optimized away.
12298 (define_insn "*ashrsi3_one_bit_cmp"
12299   [(set (reg FLAGS_REG)
12300         (compare
12301           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12302                        (match_operand:QI 2 "const1_operand" ""))
12303           (const_int 0)))
12304    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12305         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12306   "(TARGET_SHIFT1 || optimize_size)
12307    && ix86_match_ccmode (insn, CCGOCmode)
12308    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12309   "sar{l}\t%0"
12310   [(set_attr "type" "ishift")
12311    (set (attr "length")
12312      (if_then_else (match_operand:SI 0 "register_operand" "")
12313         (const_string "2")
12314         (const_string "*")))])
12315
12316 (define_insn "*ashrsi3_one_bit_cconly"
12317   [(set (reg FLAGS_REG)
12318         (compare
12319           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12320                        (match_operand:QI 2 "const1_operand" ""))
12321           (const_int 0)))
12322    (clobber (match_scratch:SI 0 "=r"))]
12323   "(TARGET_SHIFT1 || optimize_size)
12324    && ix86_match_ccmode (insn, CCGOCmode)
12325    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12326   "sar{l}\t%0"
12327   [(set_attr "type" "ishift")
12328    (set_attr "length" "2")])
12329
12330 (define_insn "*ashrsi3_one_bit_cmp_zext"
12331   [(set (reg FLAGS_REG)
12332         (compare
12333           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12334                        (match_operand:QI 2 "const1_operand" ""))
12335           (const_int 0)))
12336    (set (match_operand:DI 0 "register_operand" "=r")
12337         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12338   "TARGET_64BIT
12339    && (TARGET_SHIFT1 || optimize_size)
12340    && ix86_match_ccmode (insn, CCmode)
12341    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12342   "sar{l}\t%k0"
12343   [(set_attr "type" "ishift")
12344    (set_attr "length" "2")])
12345
12346 ;; This pattern can't accept a variable shift count, since shifts by
12347 ;; zero don't affect the flags.  We assume that shifts by constant
12348 ;; zero are optimized away.
12349 (define_insn "*ashrsi3_cmp"
12350   [(set (reg FLAGS_REG)
12351         (compare
12352           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12353                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12354           (const_int 0)))
12355    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12356         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12357   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12358    && ix86_match_ccmode (insn, CCGOCmode)
12359    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12360   "sar{l}\t{%2, %0|%0, %2}"
12361   [(set_attr "type" "ishift")
12362    (set_attr "mode" "SI")])
12363
12364 (define_insn "*ashrsi3_cconly"
12365   [(set (reg FLAGS_REG)
12366         (compare
12367           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12368                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12369           (const_int 0)))
12370    (clobber (match_scratch:SI 0 "=r"))]
12371   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12372    && ix86_match_ccmode (insn, CCGOCmode)
12373    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12374   "sar{l}\t{%2, %0|%0, %2}"
12375   [(set_attr "type" "ishift")
12376    (set_attr "mode" "SI")])
12377
12378 (define_insn "*ashrsi3_cmp_zext"
12379   [(set (reg FLAGS_REG)
12380         (compare
12381           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12382                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12383           (const_int 0)))
12384    (set (match_operand:DI 0 "register_operand" "=r")
12385         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12386   "TARGET_64BIT
12387    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12388    && ix86_match_ccmode (insn, CCGOCmode)
12389    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12390   "sar{l}\t{%2, %k0|%k0, %2}"
12391   [(set_attr "type" "ishift")
12392    (set_attr "mode" "SI")])
12393
12394 (define_expand "ashrhi3"
12395   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12396         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12397                      (match_operand:QI 2 "nonmemory_operand" "")))
12398    (clobber (reg:CC FLAGS_REG))]
12399   "TARGET_HIMODE_MATH"
12400   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12401
12402 (define_insn "*ashrhi3_1_one_bit"
12403   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12404         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12405                      (match_operand:QI 2 "const1_operand" "")))
12406    (clobber (reg:CC FLAGS_REG))]
12407   "(TARGET_SHIFT1 || optimize_size)
12408    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12409   "sar{w}\t%0"
12410   [(set_attr "type" "ishift")
12411    (set (attr "length")
12412      (if_then_else (match_operand 0 "register_operand" "")
12413         (const_string "2")
12414         (const_string "*")))])
12415
12416 (define_insn "*ashrhi3_1"
12417   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12418         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12419                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12420    (clobber (reg:CC FLAGS_REG))]
12421   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12422   "@
12423    sar{w}\t{%2, %0|%0, %2}
12424    sar{w}\t{%b2, %0|%0, %b2}"
12425   [(set_attr "type" "ishift")
12426    (set_attr "mode" "HI")])
12427
12428 ;; This pattern can't accept a variable shift count, since shifts by
12429 ;; zero don't affect the flags.  We assume that shifts by constant
12430 ;; zero are optimized away.
12431 (define_insn "*ashrhi3_one_bit_cmp"
12432   [(set (reg FLAGS_REG)
12433         (compare
12434           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12435                        (match_operand:QI 2 "const1_operand" ""))
12436           (const_int 0)))
12437    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12438         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12439   "(TARGET_SHIFT1 || optimize_size)
12440    && ix86_match_ccmode (insn, CCGOCmode)
12441    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12442   "sar{w}\t%0"
12443   [(set_attr "type" "ishift")
12444    (set (attr "length")
12445      (if_then_else (match_operand 0 "register_operand" "")
12446         (const_string "2")
12447         (const_string "*")))])
12448
12449 (define_insn "*ashrhi3_one_bit_cconly"
12450   [(set (reg FLAGS_REG)
12451         (compare
12452           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12453                        (match_operand:QI 2 "const1_operand" ""))
12454           (const_int 0)))
12455    (clobber (match_scratch:HI 0 "=r"))]
12456   "(TARGET_SHIFT1 || optimize_size)
12457    && ix86_match_ccmode (insn, CCGOCmode)
12458    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12459   "sar{w}\t%0"
12460   [(set_attr "type" "ishift")
12461    (set_attr "length" "2")])
12462
12463 ;; This pattern can't accept a variable shift count, since shifts by
12464 ;; zero don't affect the flags.  We assume that shifts by constant
12465 ;; zero are optimized away.
12466 (define_insn "*ashrhi3_cmp"
12467   [(set (reg FLAGS_REG)
12468         (compare
12469           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12470                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12471           (const_int 0)))
12472    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12473         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12474   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12475    && ix86_match_ccmode (insn, CCGOCmode)
12476    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12477   "sar{w}\t{%2, %0|%0, %2}"
12478   [(set_attr "type" "ishift")
12479    (set_attr "mode" "HI")])
12480
12481 (define_insn "*ashrhi3_cconly"
12482   [(set (reg FLAGS_REG)
12483         (compare
12484           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12485                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12486           (const_int 0)))
12487    (clobber (match_scratch:HI 0 "=r"))]
12488   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12489    && ix86_match_ccmode (insn, CCGOCmode)
12490    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12491   "sar{w}\t{%2, %0|%0, %2}"
12492   [(set_attr "type" "ishift")
12493    (set_attr "mode" "HI")])
12494
12495 (define_expand "ashrqi3"
12496   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12497         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12498                      (match_operand:QI 2 "nonmemory_operand" "")))
12499    (clobber (reg:CC FLAGS_REG))]
12500   "TARGET_QIMODE_MATH"
12501   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12502
12503 (define_insn "*ashrqi3_1_one_bit"
12504   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12505         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12506                      (match_operand:QI 2 "const1_operand" "")))
12507    (clobber (reg:CC FLAGS_REG))]
12508   "(TARGET_SHIFT1 || optimize_size)
12509    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12510   "sar{b}\t%0"
12511   [(set_attr "type" "ishift")
12512    (set (attr "length")
12513      (if_then_else (match_operand 0 "register_operand" "")
12514         (const_string "2")
12515         (const_string "*")))])
12516
12517 (define_insn "*ashrqi3_1_one_bit_slp"
12518   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12519         (ashiftrt:QI (match_dup 0)
12520                      (match_operand:QI 1 "const1_operand" "")))
12521    (clobber (reg:CC FLAGS_REG))]
12522   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12523    && (TARGET_SHIFT1 || optimize_size)
12524    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12525   "sar{b}\t%0"
12526   [(set_attr "type" "ishift1")
12527    (set (attr "length")
12528      (if_then_else (match_operand 0 "register_operand" "")
12529         (const_string "2")
12530         (const_string "*")))])
12531
12532 (define_insn "*ashrqi3_1"
12533   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12534         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12535                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12536    (clobber (reg:CC FLAGS_REG))]
12537   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12538   "@
12539    sar{b}\t{%2, %0|%0, %2}
12540    sar{b}\t{%b2, %0|%0, %b2}"
12541   [(set_attr "type" "ishift")
12542    (set_attr "mode" "QI")])
12543
12544 (define_insn "*ashrqi3_1_slp"
12545   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12546         (ashiftrt:QI (match_dup 0)
12547                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12548    (clobber (reg:CC FLAGS_REG))]
12549   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12550    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12551   "@
12552    sar{b}\t{%1, %0|%0, %1}
12553    sar{b}\t{%b1, %0|%0, %b1}"
12554   [(set_attr "type" "ishift1")
12555    (set_attr "mode" "QI")])
12556
12557 ;; This pattern can't accept a variable shift count, since shifts by
12558 ;; zero don't affect the flags.  We assume that shifts by constant
12559 ;; zero are optimized away.
12560 (define_insn "*ashrqi3_one_bit_cmp"
12561   [(set (reg FLAGS_REG)
12562         (compare
12563           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12564                        (match_operand:QI 2 "const1_operand" "I"))
12565           (const_int 0)))
12566    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12567         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12568   "(TARGET_SHIFT1 || optimize_size)
12569    && ix86_match_ccmode (insn, CCGOCmode)
12570    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12571   "sar{b}\t%0"
12572   [(set_attr "type" "ishift")
12573    (set (attr "length")
12574      (if_then_else (match_operand 0 "register_operand" "")
12575         (const_string "2")
12576         (const_string "*")))])
12577
12578 (define_insn "*ashrqi3_one_bit_cconly"
12579   [(set (reg FLAGS_REG)
12580         (compare
12581           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12582                        (match_operand:QI 2 "const1_operand" "I"))
12583           (const_int 0)))
12584    (clobber (match_scratch:QI 0 "=q"))]
12585   "(TARGET_SHIFT1 || optimize_size)
12586    && ix86_match_ccmode (insn, CCGOCmode)
12587    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12588   "sar{b}\t%0"
12589   [(set_attr "type" "ishift")
12590    (set_attr "length" "2")])
12591
12592 ;; This pattern can't accept a variable shift count, since shifts by
12593 ;; zero don't affect the flags.  We assume that shifts by constant
12594 ;; zero are optimized away.
12595 (define_insn "*ashrqi3_cmp"
12596   [(set (reg FLAGS_REG)
12597         (compare
12598           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12599                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12600           (const_int 0)))
12601    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12602         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12603   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12604    && ix86_match_ccmode (insn, CCGOCmode)
12605    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12606   "sar{b}\t{%2, %0|%0, %2}"
12607   [(set_attr "type" "ishift")
12608    (set_attr "mode" "QI")])
12609
12610 (define_insn "*ashrqi3_cconly"
12611   [(set (reg FLAGS_REG)
12612         (compare
12613           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12614                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12615           (const_int 0)))
12616    (clobber (match_scratch:QI 0 "=q"))]
12617   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12618    && ix86_match_ccmode (insn, CCGOCmode)
12619    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12620   "sar{b}\t{%2, %0|%0, %2}"
12621   [(set_attr "type" "ishift")
12622    (set_attr "mode" "QI")])
12623
12624 \f
12625 ;; Logical shift instructions
12626
12627 ;; See comment above `ashldi3' about how this works.
12628
12629 (define_expand "lshrti3"
12630   [(parallel [(set (match_operand:TI 0 "register_operand" "")
12631                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12632                                 (match_operand:QI 2 "nonmemory_operand" "")))
12633               (clobber (reg:CC FLAGS_REG))])]
12634   "TARGET_64BIT"
12635 {
12636   if (! immediate_operand (operands[2], QImode))
12637     {
12638       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12639       DONE;
12640     }
12641   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12642   DONE;
12643 })
12644
12645 (define_insn "lshrti3_1"
12646   [(set (match_operand:TI 0 "register_operand" "=r")
12647         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12648                      (match_operand:QI 2 "register_operand" "c")))
12649    (clobber (match_scratch:DI 3 "=&r"))
12650    (clobber (reg:CC FLAGS_REG))]
12651   "TARGET_64BIT"
12652   "#"
12653   [(set_attr "type" "multi")])
12654
12655 ;; This pattern must be defined before *lshrti3_2 to prevent
12656 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12657
12658 (define_insn "sse2_lshrti3"
12659   [(set (match_operand:TI 0 "register_operand" "=x")
12660         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12661                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12662   "TARGET_SSE2"
12663 {
12664   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12665   return "psrldq\t{%2, %0|%0, %2}";
12666 }
12667   [(set_attr "type" "sseishft")
12668    (set_attr "prefix_data16" "1")
12669    (set_attr "mode" "TI")])
12670
12671 (define_insn "*lshrti3_2"
12672   [(set (match_operand:TI 0 "register_operand" "=r")
12673         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12674                      (match_operand:QI 2 "immediate_operand" "O")))
12675    (clobber (reg:CC FLAGS_REG))]
12676   "TARGET_64BIT"
12677   "#"
12678   [(set_attr "type" "multi")])
12679
12680 (define_split
12681   [(set (match_operand:TI 0 "register_operand" "")
12682         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12683                      (match_operand:QI 2 "register_operand" "")))
12684    (clobber (match_scratch:DI 3 ""))
12685    (clobber (reg:CC FLAGS_REG))]
12686   "TARGET_64BIT && reload_completed"
12687   [(const_int 0)]
12688   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12689
12690 (define_split
12691   [(set (match_operand:TI 0 "register_operand" "")
12692         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12693                      (match_operand:QI 2 "immediate_operand" "")))
12694    (clobber (reg:CC FLAGS_REG))]
12695   "TARGET_64BIT && reload_completed"
12696   [(const_int 0)]
12697   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12698
12699 (define_expand "lshrdi3"
12700   [(set (match_operand:DI 0 "shiftdi_operand" "")
12701         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12702                      (match_operand:QI 2 "nonmemory_operand" "")))]
12703   ""
12704   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12705
12706 (define_insn "*lshrdi3_1_one_bit_rex64"
12707   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12708         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12709                      (match_operand:QI 2 "const1_operand" "")))
12710    (clobber (reg:CC FLAGS_REG))]
12711   "TARGET_64BIT
12712    && (TARGET_SHIFT1 || optimize_size)
12713    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12714   "shr{q}\t%0"
12715   [(set_attr "type" "ishift")
12716    (set (attr "length")
12717      (if_then_else (match_operand:DI 0 "register_operand" "")
12718         (const_string "2")
12719         (const_string "*")))])
12720
12721 (define_insn "*lshrdi3_1_rex64"
12722   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12723         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12724                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12725    (clobber (reg:CC FLAGS_REG))]
12726   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12727   "@
12728    shr{q}\t{%2, %0|%0, %2}
12729    shr{q}\t{%b2, %0|%0, %b2}"
12730   [(set_attr "type" "ishift")
12731    (set_attr "mode" "DI")])
12732
12733 ;; This pattern can't accept a variable shift count, since shifts by
12734 ;; zero don't affect the flags.  We assume that shifts by constant
12735 ;; zero are optimized away.
12736 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12737   [(set (reg FLAGS_REG)
12738         (compare
12739           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12740                        (match_operand:QI 2 "const1_operand" ""))
12741           (const_int 0)))
12742    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12743         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12744   "TARGET_64BIT
12745    && (TARGET_SHIFT1 || optimize_size)
12746    && ix86_match_ccmode (insn, CCGOCmode)
12747    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12748   "shr{q}\t%0"
12749   [(set_attr "type" "ishift")
12750    (set (attr "length")
12751      (if_then_else (match_operand:DI 0 "register_operand" "")
12752         (const_string "2")
12753         (const_string "*")))])
12754
12755 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12756   [(set (reg FLAGS_REG)
12757         (compare
12758           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12759                        (match_operand:QI 2 "const1_operand" ""))
12760           (const_int 0)))
12761    (clobber (match_scratch:DI 0 "=r"))]
12762   "TARGET_64BIT
12763    && (TARGET_SHIFT1 || optimize_size)
12764    && ix86_match_ccmode (insn, CCGOCmode)
12765    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12766   "shr{q}\t%0"
12767   [(set_attr "type" "ishift")
12768    (set_attr "length" "2")])
12769
12770 ;; This pattern can't accept a variable shift count, since shifts by
12771 ;; zero don't affect the flags.  We assume that shifts by constant
12772 ;; zero are optimized away.
12773 (define_insn "*lshrdi3_cmp_rex64"
12774   [(set (reg FLAGS_REG)
12775         (compare
12776           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12777                        (match_operand:QI 2 "const_int_operand" "e"))
12778           (const_int 0)))
12779    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12780         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12781   "TARGET_64BIT
12782    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12783    && ix86_match_ccmode (insn, CCGOCmode)
12784    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12785   "shr{q}\t{%2, %0|%0, %2}"
12786   [(set_attr "type" "ishift")
12787    (set_attr "mode" "DI")])
12788
12789 (define_insn "*lshrdi3_cconly_rex64"
12790   [(set (reg FLAGS_REG)
12791         (compare
12792           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12793                        (match_operand:QI 2 "const_int_operand" "e"))
12794           (const_int 0)))
12795    (clobber (match_scratch:DI 0 "=r"))]
12796   "TARGET_64BIT
12797    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12798    && ix86_match_ccmode (insn, CCGOCmode)
12799    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12800   "shr{q}\t{%2, %0|%0, %2}"
12801   [(set_attr "type" "ishift")
12802    (set_attr "mode" "DI")])
12803
12804 (define_insn "*lshrdi3_1"
12805   [(set (match_operand:DI 0 "register_operand" "=r")
12806         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12807                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12808    (clobber (reg:CC FLAGS_REG))]
12809   "!TARGET_64BIT"
12810   "#"
12811   [(set_attr "type" "multi")])
12812
12813 ;; By default we don't ask for a scratch register, because when DImode
12814 ;; values are manipulated, registers are already at a premium.  But if
12815 ;; we have one handy, we won't turn it away.
12816 (define_peephole2
12817   [(match_scratch:SI 3 "r")
12818    (parallel [(set (match_operand:DI 0 "register_operand" "")
12819                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12820                                 (match_operand:QI 2 "nonmemory_operand" "")))
12821               (clobber (reg:CC FLAGS_REG))])
12822    (match_dup 3)]
12823   "!TARGET_64BIT && TARGET_CMOVE"
12824   [(const_int 0)]
12825   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12826
12827 (define_split
12828   [(set (match_operand:DI 0 "register_operand" "")
12829         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12830                      (match_operand:QI 2 "nonmemory_operand" "")))
12831    (clobber (reg:CC FLAGS_REG))]
12832   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12833                      ? epilogue_completed : reload_completed)"
12834   [(const_int 0)]
12835   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12836
12837 (define_expand "lshrsi3"
12838   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12839         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12840                      (match_operand:QI 2 "nonmemory_operand" "")))
12841    (clobber (reg:CC FLAGS_REG))]
12842   ""
12843   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12844
12845 (define_insn "*lshrsi3_1_one_bit"
12846   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12847         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12848                      (match_operand:QI 2 "const1_operand" "")))
12849    (clobber (reg:CC FLAGS_REG))]
12850   "(TARGET_SHIFT1 || optimize_size)
12851    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12852   "shr{l}\t%0"
12853   [(set_attr "type" "ishift")
12854    (set (attr "length")
12855      (if_then_else (match_operand:SI 0 "register_operand" "")
12856         (const_string "2")
12857         (const_string "*")))])
12858
12859 (define_insn "*lshrsi3_1_one_bit_zext"
12860   [(set (match_operand:DI 0 "register_operand" "=r")
12861         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12862                      (match_operand:QI 2 "const1_operand" "")))
12863    (clobber (reg:CC FLAGS_REG))]
12864   "TARGET_64BIT
12865    && (TARGET_SHIFT1 || optimize_size)
12866    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12867   "shr{l}\t%k0"
12868   [(set_attr "type" "ishift")
12869    (set_attr "length" "2")])
12870
12871 (define_insn "*lshrsi3_1"
12872   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12873         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12874                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12875    (clobber (reg:CC FLAGS_REG))]
12876   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12877   "@
12878    shr{l}\t{%2, %0|%0, %2}
12879    shr{l}\t{%b2, %0|%0, %b2}"
12880   [(set_attr "type" "ishift")
12881    (set_attr "mode" "SI")])
12882
12883 (define_insn "*lshrsi3_1_zext"
12884   [(set (match_operand:DI 0 "register_operand" "=r,r")
12885         (zero_extend:DI
12886           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12887                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12888    (clobber (reg:CC FLAGS_REG))]
12889   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12890   "@
12891    shr{l}\t{%2, %k0|%k0, %2}
12892    shr{l}\t{%b2, %k0|%k0, %b2}"
12893   [(set_attr "type" "ishift")
12894    (set_attr "mode" "SI")])
12895
12896 ;; This pattern can't accept a variable shift count, since shifts by
12897 ;; zero don't affect the flags.  We assume that shifts by constant
12898 ;; zero are optimized away.
12899 (define_insn "*lshrsi3_one_bit_cmp"
12900   [(set (reg FLAGS_REG)
12901         (compare
12902           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12903                        (match_operand:QI 2 "const1_operand" ""))
12904           (const_int 0)))
12905    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12906         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12907   "(TARGET_SHIFT1 || optimize_size)
12908    && ix86_match_ccmode (insn, CCGOCmode)
12909    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12910   "shr{l}\t%0"
12911   [(set_attr "type" "ishift")
12912    (set (attr "length")
12913      (if_then_else (match_operand:SI 0 "register_operand" "")
12914         (const_string "2")
12915         (const_string "*")))])
12916
12917 (define_insn "*lshrsi3_one_bit_cconly"
12918   [(set (reg FLAGS_REG)
12919         (compare
12920           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12921                        (match_operand:QI 2 "const1_operand" ""))
12922           (const_int 0)))
12923    (clobber (match_scratch:SI 0 "=r"))]
12924   "(TARGET_SHIFT1 || optimize_size)
12925    && ix86_match_ccmode (insn, CCGOCmode)
12926    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12927   "shr{l}\t%0"
12928   [(set_attr "type" "ishift")
12929    (set_attr "length" "2")])
12930
12931 (define_insn "*lshrsi3_cmp_one_bit_zext"
12932   [(set (reg FLAGS_REG)
12933         (compare
12934           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12935                        (match_operand:QI 2 "const1_operand" ""))
12936           (const_int 0)))
12937    (set (match_operand:DI 0 "register_operand" "=r")
12938         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12939   "TARGET_64BIT
12940    && (TARGET_SHIFT1 || optimize_size)
12941    && ix86_match_ccmode (insn, CCGOCmode)
12942    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12943   "shr{l}\t%k0"
12944   [(set_attr "type" "ishift")
12945    (set_attr "length" "2")])
12946
12947 ;; This pattern can't accept a variable shift count, since shifts by
12948 ;; zero don't affect the flags.  We assume that shifts by constant
12949 ;; zero are optimized away.
12950 (define_insn "*lshrsi3_cmp"
12951   [(set (reg FLAGS_REG)
12952         (compare
12953           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12954                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12955           (const_int 0)))
12956    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12957         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12958   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12959    && ix86_match_ccmode (insn, CCGOCmode)
12960    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12961   "shr{l}\t{%2, %0|%0, %2}"
12962   [(set_attr "type" "ishift")
12963    (set_attr "mode" "SI")])
12964
12965 (define_insn "*lshrsi3_cconly"
12966   [(set (reg FLAGS_REG)
12967       (compare
12968         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12969                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12970         (const_int 0)))
12971    (clobber (match_scratch:SI 0 "=r"))]
12972   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12973    && ix86_match_ccmode (insn, CCGOCmode)
12974    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12975   "shr{l}\t{%2, %0|%0, %2}"
12976   [(set_attr "type" "ishift")
12977    (set_attr "mode" "SI")])
12978
12979 (define_insn "*lshrsi3_cmp_zext"
12980   [(set (reg FLAGS_REG)
12981         (compare
12982           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12983                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12984           (const_int 0)))
12985    (set (match_operand:DI 0 "register_operand" "=r")
12986         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12987   "TARGET_64BIT
12988    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12989    && ix86_match_ccmode (insn, CCGOCmode)
12990    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12991   "shr{l}\t{%2, %k0|%k0, %2}"
12992   [(set_attr "type" "ishift")
12993    (set_attr "mode" "SI")])
12994
12995 (define_expand "lshrhi3"
12996   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12997         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12998                      (match_operand:QI 2 "nonmemory_operand" "")))
12999    (clobber (reg:CC FLAGS_REG))]
13000   "TARGET_HIMODE_MATH"
13001   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
13002
13003 (define_insn "*lshrhi3_1_one_bit"
13004   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13005         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13006                      (match_operand:QI 2 "const1_operand" "")))
13007    (clobber (reg:CC FLAGS_REG))]
13008   "(TARGET_SHIFT1 || optimize_size)
13009    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13010   "shr{w}\t%0"
13011   [(set_attr "type" "ishift")
13012    (set (attr "length")
13013      (if_then_else (match_operand 0 "register_operand" "")
13014         (const_string "2")
13015         (const_string "*")))])
13016
13017 (define_insn "*lshrhi3_1"
13018   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13019         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13020                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13021    (clobber (reg:CC FLAGS_REG))]
13022   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13023   "@
13024    shr{w}\t{%2, %0|%0, %2}
13025    shr{w}\t{%b2, %0|%0, %b2}"
13026   [(set_attr "type" "ishift")
13027    (set_attr "mode" "HI")])
13028
13029 ;; This pattern can't accept a variable shift count, since shifts by
13030 ;; zero don't affect the flags.  We assume that shifts by constant
13031 ;; zero are optimized away.
13032 (define_insn "*lshrhi3_one_bit_cmp"
13033   [(set (reg FLAGS_REG)
13034         (compare
13035           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13036                        (match_operand:QI 2 "const1_operand" ""))
13037           (const_int 0)))
13038    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13039         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13040   "(TARGET_SHIFT1 || optimize_size)
13041    && ix86_match_ccmode (insn, CCGOCmode)
13042    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13043   "shr{w}\t%0"
13044   [(set_attr "type" "ishift")
13045    (set (attr "length")
13046      (if_then_else (match_operand:SI 0 "register_operand" "")
13047         (const_string "2")
13048         (const_string "*")))])
13049
13050 (define_insn "*lshrhi3_one_bit_cconly"
13051   [(set (reg FLAGS_REG)
13052         (compare
13053           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13054                        (match_operand:QI 2 "const1_operand" ""))
13055           (const_int 0)))
13056    (clobber (match_scratch:HI 0 "=r"))]
13057   "(TARGET_SHIFT1 || optimize_size)
13058    && ix86_match_ccmode (insn, CCGOCmode)
13059    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13060   "shr{w}\t%0"
13061   [(set_attr "type" "ishift")
13062    (set_attr "length" "2")])
13063
13064 ;; This pattern can't accept a variable shift count, since shifts by
13065 ;; zero don't affect the flags.  We assume that shifts by constant
13066 ;; zero are optimized away.
13067 (define_insn "*lshrhi3_cmp"
13068   [(set (reg FLAGS_REG)
13069         (compare
13070           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13071                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13072           (const_int 0)))
13073    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13074         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13075   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13076    && ix86_match_ccmode (insn, CCGOCmode)
13077    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13078   "shr{w}\t{%2, %0|%0, %2}"
13079   [(set_attr "type" "ishift")
13080    (set_attr "mode" "HI")])
13081
13082 (define_insn "*lshrhi3_cconly"
13083   [(set (reg FLAGS_REG)
13084         (compare
13085           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13086                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13087           (const_int 0)))
13088    (clobber (match_scratch:HI 0 "=r"))]
13089   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13090    && ix86_match_ccmode (insn, CCGOCmode)
13091    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13092   "shr{w}\t{%2, %0|%0, %2}"
13093   [(set_attr "type" "ishift")
13094    (set_attr "mode" "HI")])
13095
13096 (define_expand "lshrqi3"
13097   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13098         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13099                      (match_operand:QI 2 "nonmemory_operand" "")))
13100    (clobber (reg:CC FLAGS_REG))]
13101   "TARGET_QIMODE_MATH"
13102   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13103
13104 (define_insn "*lshrqi3_1_one_bit"
13105   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13106         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13107                      (match_operand:QI 2 "const1_operand" "")))
13108    (clobber (reg:CC FLAGS_REG))]
13109   "(TARGET_SHIFT1 || optimize_size)
13110    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13111   "shr{b}\t%0"
13112   [(set_attr "type" "ishift")
13113    (set (attr "length")
13114      (if_then_else (match_operand 0 "register_operand" "")
13115         (const_string "2")
13116         (const_string "*")))])
13117
13118 (define_insn "*lshrqi3_1_one_bit_slp"
13119   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13120         (lshiftrt:QI (match_dup 0)
13121                      (match_operand:QI 1 "const1_operand" "")))
13122    (clobber (reg:CC FLAGS_REG))]
13123   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13124    && (TARGET_SHIFT1 || optimize_size)"
13125   "shr{b}\t%0"
13126   [(set_attr "type" "ishift1")
13127    (set (attr "length")
13128      (if_then_else (match_operand 0 "register_operand" "")
13129         (const_string "2")
13130         (const_string "*")))])
13131
13132 (define_insn "*lshrqi3_1"
13133   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13134         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13135                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13136    (clobber (reg:CC FLAGS_REG))]
13137   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13138   "@
13139    shr{b}\t{%2, %0|%0, %2}
13140    shr{b}\t{%b2, %0|%0, %b2}"
13141   [(set_attr "type" "ishift")
13142    (set_attr "mode" "QI")])
13143
13144 (define_insn "*lshrqi3_1_slp"
13145   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13146         (lshiftrt:QI (match_dup 0)
13147                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13148    (clobber (reg:CC FLAGS_REG))]
13149   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13150    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13151   "@
13152    shr{b}\t{%1, %0|%0, %1}
13153    shr{b}\t{%b1, %0|%0, %b1}"
13154   [(set_attr "type" "ishift1")
13155    (set_attr "mode" "QI")])
13156
13157 ;; This pattern can't accept a variable shift count, since shifts by
13158 ;; zero don't affect the flags.  We assume that shifts by constant
13159 ;; zero are optimized away.
13160 (define_insn "*lshrqi2_one_bit_cmp"
13161   [(set (reg FLAGS_REG)
13162         (compare
13163           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13164                        (match_operand:QI 2 "const1_operand" ""))
13165           (const_int 0)))
13166    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13167         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13168   "(TARGET_SHIFT1 || optimize_size)
13169    && ix86_match_ccmode (insn, CCGOCmode)
13170    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13171   "shr{b}\t%0"
13172   [(set_attr "type" "ishift")
13173    (set (attr "length")
13174      (if_then_else (match_operand:SI 0 "register_operand" "")
13175         (const_string "2")
13176         (const_string "*")))])
13177
13178 (define_insn "*lshrqi2_one_bit_cconly"
13179   [(set (reg FLAGS_REG)
13180         (compare
13181           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13182                        (match_operand:QI 2 "const1_operand" ""))
13183           (const_int 0)))
13184    (clobber (match_scratch:QI 0 "=q"))]
13185   "(TARGET_SHIFT1 || optimize_size)
13186    && ix86_match_ccmode (insn, CCGOCmode)
13187    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13188   "shr{b}\t%0"
13189   [(set_attr "type" "ishift")
13190    (set_attr "length" "2")])
13191
13192 ;; This pattern can't accept a variable shift count, since shifts by
13193 ;; zero don't affect the flags.  We assume that shifts by constant
13194 ;; zero are optimized away.
13195 (define_insn "*lshrqi2_cmp"
13196   [(set (reg FLAGS_REG)
13197         (compare
13198           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13199                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13200           (const_int 0)))
13201    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13202         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13203   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13204    && ix86_match_ccmode (insn, CCGOCmode)
13205    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13206   "shr{b}\t{%2, %0|%0, %2}"
13207   [(set_attr "type" "ishift")
13208    (set_attr "mode" "QI")])
13209
13210 (define_insn "*lshrqi2_cconly"
13211   [(set (reg FLAGS_REG)
13212         (compare
13213           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13214                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13215           (const_int 0)))
13216    (clobber (match_scratch:QI 0 "=q"))]
13217   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13218    && ix86_match_ccmode (insn, CCGOCmode)
13219    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13220   "shr{b}\t{%2, %0|%0, %2}"
13221   [(set_attr "type" "ishift")
13222    (set_attr "mode" "QI")])
13223 \f
13224 ;; Rotate instructions
13225
13226 (define_expand "rotldi3"
13227   [(set (match_operand:DI 0 "shiftdi_operand" "")
13228         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13229                    (match_operand:QI 2 "nonmemory_operand" "")))
13230    (clobber (reg:CC FLAGS_REG))]
13231  ""
13232 {
13233   if (TARGET_64BIT)
13234     {
13235       ix86_expand_binary_operator (ROTATE, DImode, operands);
13236       DONE;
13237     }
13238   if (!const_1_to_31_operand (operands[2], VOIDmode))
13239     FAIL;
13240   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13241   DONE;
13242 })
13243
13244 ;; Implement rotation using two double-precision shift instructions
13245 ;; and a scratch register.
13246 (define_insn_and_split "ix86_rotldi3"
13247  [(set (match_operand:DI 0 "register_operand" "=r")
13248        (rotate:DI (match_operand:DI 1 "register_operand" "0")
13249                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
13250   (clobber (reg:CC FLAGS_REG))
13251   (clobber (match_scratch:SI 3 "=&r"))]
13252  "!TARGET_64BIT"
13253  ""
13254  "&& reload_completed"
13255  [(set (match_dup 3) (match_dup 4))
13256   (parallel
13257    [(set (match_dup 4)
13258          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13259                  (lshiftrt:SI (match_dup 5)
13260                               (minus:QI (const_int 32) (match_dup 2)))))
13261     (clobber (reg:CC FLAGS_REG))])
13262   (parallel
13263    [(set (match_dup 5)
13264          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13265                  (lshiftrt:SI (match_dup 3)
13266                               (minus:QI (const_int 32) (match_dup 2)))))
13267     (clobber (reg:CC FLAGS_REG))])]
13268  "split_di (operands, 1, operands + 4, operands + 5);")
13269
13270 (define_insn "*rotlsi3_1_one_bit_rex64"
13271   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13272         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13273                    (match_operand:QI 2 "const1_operand" "")))
13274    (clobber (reg:CC FLAGS_REG))]
13275   "TARGET_64BIT
13276    && (TARGET_SHIFT1 || optimize_size)
13277    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13278   "rol{q}\t%0"
13279   [(set_attr "type" "rotate")
13280    (set (attr "length")
13281      (if_then_else (match_operand:DI 0 "register_operand" "")
13282         (const_string "2")
13283         (const_string "*")))])
13284
13285 (define_insn "*rotldi3_1_rex64"
13286   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13287         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13288                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
13289    (clobber (reg:CC FLAGS_REG))]
13290   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13291   "@
13292    rol{q}\t{%2, %0|%0, %2}
13293    rol{q}\t{%b2, %0|%0, %b2}"
13294   [(set_attr "type" "rotate")
13295    (set_attr "mode" "DI")])
13296
13297 (define_expand "rotlsi3"
13298   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13299         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13300                    (match_operand:QI 2 "nonmemory_operand" "")))
13301    (clobber (reg:CC FLAGS_REG))]
13302   ""
13303   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13304
13305 (define_insn "*rotlsi3_1_one_bit"
13306   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13307         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13308                    (match_operand:QI 2 "const1_operand" "")))
13309    (clobber (reg:CC FLAGS_REG))]
13310   "(TARGET_SHIFT1 || optimize_size)
13311    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13312   "rol{l}\t%0"
13313   [(set_attr "type" "rotate")
13314    (set (attr "length")
13315      (if_then_else (match_operand:SI 0 "register_operand" "")
13316         (const_string "2")
13317         (const_string "*")))])
13318
13319 (define_insn "*rotlsi3_1_one_bit_zext"
13320   [(set (match_operand:DI 0 "register_operand" "=r")
13321         (zero_extend:DI
13322           (rotate:SI (match_operand:SI 1 "register_operand" "0")
13323                      (match_operand:QI 2 "const1_operand" ""))))
13324    (clobber (reg:CC FLAGS_REG))]
13325   "TARGET_64BIT
13326    && (TARGET_SHIFT1 || optimize_size)
13327    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13328   "rol{l}\t%k0"
13329   [(set_attr "type" "rotate")
13330    (set_attr "length" "2")])
13331
13332 (define_insn "*rotlsi3_1"
13333   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13334         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13335                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13336    (clobber (reg:CC FLAGS_REG))]
13337   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13338   "@
13339    rol{l}\t{%2, %0|%0, %2}
13340    rol{l}\t{%b2, %0|%0, %b2}"
13341   [(set_attr "type" "rotate")
13342    (set_attr "mode" "SI")])
13343
13344 (define_insn "*rotlsi3_1_zext"
13345   [(set (match_operand:DI 0 "register_operand" "=r,r")
13346         (zero_extend:DI
13347           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13348                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13349    (clobber (reg:CC FLAGS_REG))]
13350   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13351   "@
13352    rol{l}\t{%2, %k0|%k0, %2}
13353    rol{l}\t{%b2, %k0|%k0, %b2}"
13354   [(set_attr "type" "rotate")
13355    (set_attr "mode" "SI")])
13356
13357 (define_expand "rotlhi3"
13358   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13359         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13360                    (match_operand:QI 2 "nonmemory_operand" "")))
13361    (clobber (reg:CC FLAGS_REG))]
13362   "TARGET_HIMODE_MATH"
13363   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13364
13365 (define_insn "*rotlhi3_1_one_bit"
13366   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13367         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13368                    (match_operand:QI 2 "const1_operand" "")))
13369    (clobber (reg:CC FLAGS_REG))]
13370   "(TARGET_SHIFT1 || optimize_size)
13371    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13372   "rol{w}\t%0"
13373   [(set_attr "type" "rotate")
13374    (set (attr "length")
13375      (if_then_else (match_operand 0 "register_operand" "")
13376         (const_string "2")
13377         (const_string "*")))])
13378
13379 (define_insn "*rotlhi3_1"
13380   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13381         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13382                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13383    (clobber (reg:CC FLAGS_REG))]
13384   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13385   "@
13386    rol{w}\t{%2, %0|%0, %2}
13387    rol{w}\t{%b2, %0|%0, %b2}"
13388   [(set_attr "type" "rotate")
13389    (set_attr "mode" "HI")])
13390
13391 (define_split
13392  [(set (match_operand:HI 0 "register_operand" "")
13393        (rotate:HI (match_dup 0) (const_int 8)))
13394   (clobber (reg:CC FLAGS_REG))]
13395  "reload_completed"
13396  [(parallel [(set (strict_low_part (match_dup 0))
13397                   (bswap:HI (match_dup 0)))
13398              (clobber (reg:CC FLAGS_REG))])]
13399  "")
13400
13401 (define_expand "rotlqi3"
13402   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13403         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13404                    (match_operand:QI 2 "nonmemory_operand" "")))
13405    (clobber (reg:CC FLAGS_REG))]
13406   "TARGET_QIMODE_MATH"
13407   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13408
13409 (define_insn "*rotlqi3_1_one_bit_slp"
13410   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13411         (rotate:QI (match_dup 0)
13412                    (match_operand:QI 1 "const1_operand" "")))
13413    (clobber (reg:CC FLAGS_REG))]
13414   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13415    && (TARGET_SHIFT1 || optimize_size)"
13416   "rol{b}\t%0"
13417   [(set_attr "type" "rotate1")
13418    (set (attr "length")
13419      (if_then_else (match_operand 0 "register_operand" "")
13420         (const_string "2")
13421         (const_string "*")))])
13422
13423 (define_insn "*rotlqi3_1_one_bit"
13424   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13425         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13426                    (match_operand:QI 2 "const1_operand" "")))
13427    (clobber (reg:CC FLAGS_REG))]
13428   "(TARGET_SHIFT1 || optimize_size)
13429    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13430   "rol{b}\t%0"
13431   [(set_attr "type" "rotate")
13432    (set (attr "length")
13433      (if_then_else (match_operand 0 "register_operand" "")
13434         (const_string "2")
13435         (const_string "*")))])
13436
13437 (define_insn "*rotlqi3_1_slp"
13438   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13439         (rotate:QI (match_dup 0)
13440                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13441    (clobber (reg:CC FLAGS_REG))]
13442   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13443    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13444   "@
13445    rol{b}\t{%1, %0|%0, %1}
13446    rol{b}\t{%b1, %0|%0, %b1}"
13447   [(set_attr "type" "rotate1")
13448    (set_attr "mode" "QI")])
13449
13450 (define_insn "*rotlqi3_1"
13451   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13452         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13453                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13454    (clobber (reg:CC FLAGS_REG))]
13455   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13456   "@
13457    rol{b}\t{%2, %0|%0, %2}
13458    rol{b}\t{%b2, %0|%0, %b2}"
13459   [(set_attr "type" "rotate")
13460    (set_attr "mode" "QI")])
13461
13462 (define_expand "rotrdi3"
13463   [(set (match_operand:DI 0 "shiftdi_operand" "")
13464         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13465                    (match_operand:QI 2 "nonmemory_operand" "")))
13466    (clobber (reg:CC FLAGS_REG))]
13467  ""
13468 {
13469   if (TARGET_64BIT)
13470     {
13471       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13472       DONE;
13473     }
13474   if (!const_1_to_31_operand (operands[2], VOIDmode))
13475     FAIL;
13476   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13477   DONE;
13478 })
13479
13480 ;; Implement rotation using two double-precision shift instructions
13481 ;; and a scratch register.
13482 (define_insn_and_split "ix86_rotrdi3"
13483  [(set (match_operand:DI 0 "register_operand" "=r")
13484        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13485                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13486   (clobber (reg:CC FLAGS_REG))
13487   (clobber (match_scratch:SI 3 "=&r"))]
13488  "!TARGET_64BIT"
13489  ""
13490  "&& reload_completed"
13491  [(set (match_dup 3) (match_dup 4))
13492   (parallel
13493    [(set (match_dup 4)
13494          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13495                  (ashift:SI (match_dup 5)
13496                             (minus:QI (const_int 32) (match_dup 2)))))
13497     (clobber (reg:CC FLAGS_REG))])
13498   (parallel
13499    [(set (match_dup 5)
13500          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13501                  (ashift:SI (match_dup 3)
13502                             (minus:QI (const_int 32) (match_dup 2)))))
13503     (clobber (reg:CC FLAGS_REG))])]
13504  "split_di (operands, 1, operands + 4, operands + 5);")
13505
13506 (define_insn "*rotrdi3_1_one_bit_rex64"
13507   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13508         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13509                      (match_operand:QI 2 "const1_operand" "")))
13510    (clobber (reg:CC FLAGS_REG))]
13511   "TARGET_64BIT
13512    && (TARGET_SHIFT1 || optimize_size)
13513    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13514   "ror{q}\t%0"
13515   [(set_attr "type" "rotate")
13516    (set (attr "length")
13517      (if_then_else (match_operand:DI 0 "register_operand" "")
13518         (const_string "2")
13519         (const_string "*")))])
13520
13521 (define_insn "*rotrdi3_1_rex64"
13522   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13523         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13524                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13525    (clobber (reg:CC FLAGS_REG))]
13526   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13527   "@
13528    ror{q}\t{%2, %0|%0, %2}
13529    ror{q}\t{%b2, %0|%0, %b2}"
13530   [(set_attr "type" "rotate")
13531    (set_attr "mode" "DI")])
13532
13533 (define_expand "rotrsi3"
13534   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13535         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13536                      (match_operand:QI 2 "nonmemory_operand" "")))
13537    (clobber (reg:CC FLAGS_REG))]
13538   ""
13539   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13540
13541 (define_insn "*rotrsi3_1_one_bit"
13542   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13543         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13544                      (match_operand:QI 2 "const1_operand" "")))
13545    (clobber (reg:CC FLAGS_REG))]
13546   "(TARGET_SHIFT1 || optimize_size)
13547    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13548   "ror{l}\t%0"
13549   [(set_attr "type" "rotate")
13550    (set (attr "length")
13551      (if_then_else (match_operand:SI 0 "register_operand" "")
13552         (const_string "2")
13553         (const_string "*")))])
13554
13555 (define_insn "*rotrsi3_1_one_bit_zext"
13556   [(set (match_operand:DI 0 "register_operand" "=r")
13557         (zero_extend:DI
13558           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13559                        (match_operand:QI 2 "const1_operand" ""))))
13560    (clobber (reg:CC FLAGS_REG))]
13561   "TARGET_64BIT
13562    && (TARGET_SHIFT1 || optimize_size)
13563    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13564   "ror{l}\t%k0"
13565   [(set_attr "type" "rotate")
13566    (set (attr "length")
13567      (if_then_else (match_operand:SI 0 "register_operand" "")
13568         (const_string "2")
13569         (const_string "*")))])
13570
13571 (define_insn "*rotrsi3_1"
13572   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13573         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13574                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13575    (clobber (reg:CC FLAGS_REG))]
13576   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13577   "@
13578    ror{l}\t{%2, %0|%0, %2}
13579    ror{l}\t{%b2, %0|%0, %b2}"
13580   [(set_attr "type" "rotate")
13581    (set_attr "mode" "SI")])
13582
13583 (define_insn "*rotrsi3_1_zext"
13584   [(set (match_operand:DI 0 "register_operand" "=r,r")
13585         (zero_extend:DI
13586           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13587                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13588    (clobber (reg:CC FLAGS_REG))]
13589   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13590   "@
13591    ror{l}\t{%2, %k0|%k0, %2}
13592    ror{l}\t{%b2, %k0|%k0, %b2}"
13593   [(set_attr "type" "rotate")
13594    (set_attr "mode" "SI")])
13595
13596 (define_expand "rotrhi3"
13597   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13598         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13599                      (match_operand:QI 2 "nonmemory_operand" "")))
13600    (clobber (reg:CC FLAGS_REG))]
13601   "TARGET_HIMODE_MATH"
13602   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13603
13604 (define_insn "*rotrhi3_one_bit"
13605   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13606         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13607                      (match_operand:QI 2 "const1_operand" "")))
13608    (clobber (reg:CC FLAGS_REG))]
13609   "(TARGET_SHIFT1 || optimize_size)
13610    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13611   "ror{w}\t%0"
13612   [(set_attr "type" "rotate")
13613    (set (attr "length")
13614      (if_then_else (match_operand 0 "register_operand" "")
13615         (const_string "2")
13616         (const_string "*")))])
13617
13618 (define_insn "*rotrhi3_1"
13619   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13620         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13621                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13622    (clobber (reg:CC FLAGS_REG))]
13623   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13624   "@
13625    ror{w}\t{%2, %0|%0, %2}
13626    ror{w}\t{%b2, %0|%0, %b2}"
13627   [(set_attr "type" "rotate")
13628    (set_attr "mode" "HI")])
13629
13630 (define_split
13631  [(set (match_operand:HI 0 "register_operand" "")
13632        (rotatert:HI (match_dup 0) (const_int 8)))
13633   (clobber (reg:CC FLAGS_REG))]
13634  "reload_completed"
13635  [(parallel [(set (strict_low_part (match_dup 0))
13636                   (bswap:HI (match_dup 0)))
13637              (clobber (reg:CC FLAGS_REG))])]
13638  "")
13639
13640 (define_expand "rotrqi3"
13641   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13642         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13643                      (match_operand:QI 2 "nonmemory_operand" "")))
13644    (clobber (reg:CC FLAGS_REG))]
13645   "TARGET_QIMODE_MATH"
13646   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13647
13648 (define_insn "*rotrqi3_1_one_bit"
13649   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13650         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13651                      (match_operand:QI 2 "const1_operand" "")))
13652    (clobber (reg:CC FLAGS_REG))]
13653   "(TARGET_SHIFT1 || optimize_size)
13654    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13655   "ror{b}\t%0"
13656   [(set_attr "type" "rotate")
13657    (set (attr "length")
13658      (if_then_else (match_operand 0 "register_operand" "")
13659         (const_string "2")
13660         (const_string "*")))])
13661
13662 (define_insn "*rotrqi3_1_one_bit_slp"
13663   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13664         (rotatert:QI (match_dup 0)
13665                      (match_operand:QI 1 "const1_operand" "")))
13666    (clobber (reg:CC FLAGS_REG))]
13667   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13668    && (TARGET_SHIFT1 || optimize_size)"
13669   "ror{b}\t%0"
13670   [(set_attr "type" "rotate1")
13671    (set (attr "length")
13672      (if_then_else (match_operand 0 "register_operand" "")
13673         (const_string "2")
13674         (const_string "*")))])
13675
13676 (define_insn "*rotrqi3_1"
13677   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13678         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13679                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13680    (clobber (reg:CC FLAGS_REG))]
13681   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13682   "@
13683    ror{b}\t{%2, %0|%0, %2}
13684    ror{b}\t{%b2, %0|%0, %b2}"
13685   [(set_attr "type" "rotate")
13686    (set_attr "mode" "QI")])
13687
13688 (define_insn "*rotrqi3_1_slp"
13689   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13690         (rotatert:QI (match_dup 0)
13691                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13692    (clobber (reg:CC FLAGS_REG))]
13693   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13694    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13695   "@
13696    ror{b}\t{%1, %0|%0, %1}
13697    ror{b}\t{%b1, %0|%0, %b1}"
13698   [(set_attr "type" "rotate1")
13699    (set_attr "mode" "QI")])
13700 \f
13701 ;; Bit set / bit test instructions
13702
13703 (define_expand "extv"
13704   [(set (match_operand:SI 0 "register_operand" "")
13705         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13706                          (match_operand:SI 2 "const8_operand" "")
13707                          (match_operand:SI 3 "const8_operand" "")))]
13708   ""
13709 {
13710   /* Handle extractions from %ah et al.  */
13711   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13712     FAIL;
13713
13714   /* From mips.md: extract_bit_field doesn't verify that our source
13715      matches the predicate, so check it again here.  */
13716   if (! ext_register_operand (operands[1], VOIDmode))
13717     FAIL;
13718 })
13719
13720 (define_expand "extzv"
13721   [(set (match_operand:SI 0 "register_operand" "")
13722         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13723                          (match_operand:SI 2 "const8_operand" "")
13724                          (match_operand:SI 3 "const8_operand" "")))]
13725   ""
13726 {
13727   /* Handle extractions from %ah et al.  */
13728   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13729     FAIL;
13730
13731   /* From mips.md: extract_bit_field doesn't verify that our source
13732      matches the predicate, so check it again here.  */
13733   if (! ext_register_operand (operands[1], VOIDmode))
13734     FAIL;
13735 })
13736
13737 (define_expand "insv"
13738   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13739                       (match_operand 1 "const8_operand" "")
13740                       (match_operand 2 "const8_operand" ""))
13741         (match_operand 3 "register_operand" ""))]
13742   ""
13743 {
13744   /* Handle insertions to %ah et al.  */
13745   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13746     FAIL;
13747
13748   /* From mips.md: insert_bit_field doesn't verify that our source
13749      matches the predicate, so check it again here.  */
13750   if (! ext_register_operand (operands[0], VOIDmode))
13751     FAIL;
13752
13753   if (TARGET_64BIT)
13754     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13755   else
13756     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13757
13758   DONE;
13759 })
13760
13761 ;; %%% bts, btr, btc, bt.
13762 ;; In general these instructions are *slow* when applied to memory,
13763 ;; since they enforce atomic operation.  When applied to registers,
13764 ;; it depends on the cpu implementation.  They're never faster than
13765 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13766 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13767 ;; within the instruction itself, so operating on bits in the high
13768 ;; 32-bits of a register becomes easier.
13769 ;;
13770 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13771 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13772 ;; negdf respectively, so they can never be disabled entirely.
13773
13774 (define_insn "*btsq"
13775   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13776                          (const_int 1)
13777                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13778         (const_int 1))
13779    (clobber (reg:CC FLAGS_REG))]
13780   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13781   "bts{q} %1,%0"
13782   [(set_attr "type" "alu1")])
13783
13784 (define_insn "*btrq"
13785   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13786                          (const_int 1)
13787                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13788         (const_int 0))
13789    (clobber (reg:CC FLAGS_REG))]
13790   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13791   "btr{q} %1,%0"
13792   [(set_attr "type" "alu1")])
13793
13794 (define_insn "*btcq"
13795   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13796                          (const_int 1)
13797                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13798         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13799    (clobber (reg:CC FLAGS_REG))]
13800   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13801   "btc{q} %1,%0"
13802   [(set_attr "type" "alu1")])
13803
13804 ;; Allow Nocona to avoid these instructions if a register is available.
13805
13806 (define_peephole2
13807   [(match_scratch:DI 2 "r")
13808    (parallel [(set (zero_extract:DI
13809                      (match_operand:DI 0 "register_operand" "")
13810                      (const_int 1)
13811                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13812                    (const_int 1))
13813               (clobber (reg:CC FLAGS_REG))])]
13814   "TARGET_64BIT && !TARGET_USE_BT"
13815   [(const_int 0)]
13816 {
13817   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13818   rtx op1;
13819
13820   if (HOST_BITS_PER_WIDE_INT >= 64)
13821     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13822   else if (i < HOST_BITS_PER_WIDE_INT)
13823     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13824   else
13825     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13826
13827   op1 = immed_double_const (lo, hi, DImode);
13828   if (i >= 31)
13829     {
13830       emit_move_insn (operands[2], op1);
13831       op1 = operands[2];
13832     }
13833
13834   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13835   DONE;
13836 })
13837
13838 (define_peephole2
13839   [(match_scratch:DI 2 "r")
13840    (parallel [(set (zero_extract:DI
13841                      (match_operand:DI 0 "register_operand" "")
13842                      (const_int 1)
13843                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13844                    (const_int 0))
13845               (clobber (reg:CC FLAGS_REG))])]
13846   "TARGET_64BIT && !TARGET_USE_BT"
13847   [(const_int 0)]
13848 {
13849   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13850   rtx op1;
13851
13852   if (HOST_BITS_PER_WIDE_INT >= 64)
13853     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13854   else if (i < HOST_BITS_PER_WIDE_INT)
13855     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13856   else
13857     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13858
13859   op1 = immed_double_const (~lo, ~hi, DImode);
13860   if (i >= 32)
13861     {
13862       emit_move_insn (operands[2], op1);
13863       op1 = operands[2];
13864     }
13865
13866   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13867   DONE;
13868 })
13869
13870 (define_peephole2
13871   [(match_scratch:DI 2 "r")
13872    (parallel [(set (zero_extract:DI
13873                      (match_operand:DI 0 "register_operand" "")
13874                      (const_int 1)
13875                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13876               (not:DI (zero_extract:DI
13877                         (match_dup 0) (const_int 1) (match_dup 1))))
13878               (clobber (reg:CC FLAGS_REG))])]
13879   "TARGET_64BIT && !TARGET_USE_BT"
13880   [(const_int 0)]
13881 {
13882   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13883   rtx op1;
13884
13885   if (HOST_BITS_PER_WIDE_INT >= 64)
13886     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13887   else if (i < HOST_BITS_PER_WIDE_INT)
13888     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13889   else
13890     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13891
13892   op1 = immed_double_const (lo, hi, DImode);
13893   if (i >= 31)
13894     {
13895       emit_move_insn (operands[2], op1);
13896       op1 = operands[2];
13897     }
13898
13899   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13900   DONE;
13901 })
13902 \f
13903 ;; Store-flag instructions.
13904
13905 ;; For all sCOND expanders, also expand the compare or test insn that
13906 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13907
13908 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13909 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13910 ;; way, which can later delete the movzx if only QImode is needed.
13911
13912 (define_expand "s<code>"
13913   [(set (match_operand:QI 0 "register_operand" "")
13914         (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13915   ""
13916   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13917
13918 (define_expand "s<code>"
13919   [(set (match_operand:QI 0 "register_operand" "")
13920         (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13921   "TARGET_80387 || TARGET_SSE"
13922   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13923
13924 (define_insn "*setcc_1"
13925   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13926         (match_operator:QI 1 "ix86_comparison_operator"
13927           [(reg FLAGS_REG) (const_int 0)]))]
13928   ""
13929   "set%C1\t%0"
13930   [(set_attr "type" "setcc")
13931    (set_attr "mode" "QI")])
13932
13933 (define_insn "*setcc_2"
13934   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13935         (match_operator:QI 1 "ix86_comparison_operator"
13936           [(reg FLAGS_REG) (const_int 0)]))]
13937   ""
13938   "set%C1\t%0"
13939   [(set_attr "type" "setcc")
13940    (set_attr "mode" "QI")])
13941
13942 ;; In general it is not safe to assume too much about CCmode registers,
13943 ;; so simplify-rtx stops when it sees a second one.  Under certain
13944 ;; conditions this is safe on x86, so help combine not create
13945 ;;
13946 ;;      seta    %al
13947 ;;      testb   %al, %al
13948 ;;      sete    %al
13949
13950 (define_split
13951   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13952         (ne:QI (match_operator 1 "ix86_comparison_operator"
13953                  [(reg FLAGS_REG) (const_int 0)])
13954             (const_int 0)))]
13955   ""
13956   [(set (match_dup 0) (match_dup 1))]
13957 {
13958   PUT_MODE (operands[1], QImode);
13959 })
13960
13961 (define_split
13962   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13963         (ne:QI (match_operator 1 "ix86_comparison_operator"
13964                  [(reg FLAGS_REG) (const_int 0)])
13965             (const_int 0)))]
13966   ""
13967   [(set (match_dup 0) (match_dup 1))]
13968 {
13969   PUT_MODE (operands[1], QImode);
13970 })
13971
13972 (define_split
13973   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13974         (eq:QI (match_operator 1 "ix86_comparison_operator"
13975                  [(reg FLAGS_REG) (const_int 0)])
13976             (const_int 0)))]
13977   ""
13978   [(set (match_dup 0) (match_dup 1))]
13979 {
13980   rtx new_op1 = copy_rtx (operands[1]);
13981   operands[1] = new_op1;
13982   PUT_MODE (new_op1, QImode);
13983   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13984                                              GET_MODE (XEXP (new_op1, 0))));
13985
13986   /* Make sure that (a) the CCmode we have for the flags is strong
13987      enough for the reversed compare or (b) we have a valid FP compare.  */
13988   if (! ix86_comparison_operator (new_op1, VOIDmode))
13989     FAIL;
13990 })
13991
13992 (define_split
13993   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13994         (eq:QI (match_operator 1 "ix86_comparison_operator"
13995                  [(reg FLAGS_REG) (const_int 0)])
13996             (const_int 0)))]
13997   ""
13998   [(set (match_dup 0) (match_dup 1))]
13999 {
14000   rtx new_op1 = copy_rtx (operands[1]);
14001   operands[1] = new_op1;
14002   PUT_MODE (new_op1, QImode);
14003   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14004                                              GET_MODE (XEXP (new_op1, 0))));
14005
14006   /* Make sure that (a) the CCmode we have for the flags is strong
14007      enough for the reversed compare or (b) we have a valid FP compare.  */
14008   if (! ix86_comparison_operator (new_op1, VOIDmode))
14009     FAIL;
14010 })
14011
14012 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14013 ;; subsequent logical operations are used to imitate conditional moves.
14014 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14015 ;; it directly.
14016
14017 (define_insn "*sse_setcc<mode>"
14018   [(set (match_operand:MODEF 0 "register_operand" "=x")
14019         (match_operator:MODEF 1 "sse_comparison_operator"
14020           [(match_operand:MODEF 2 "register_operand" "0")
14021            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14022   "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
14023   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
14024   [(set_attr "type" "ssecmp")
14025    (set_attr "mode" "<MODE>")])
14026
14027 (define_insn "*sse5_setcc<mode>"
14028   [(set (match_operand:MODEF 0 "register_operand" "=x")
14029         (match_operator:MODEF 1 "sse5_comparison_float_operator"
14030           [(match_operand:MODEF 2 "register_operand" "x")
14031            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14032   "TARGET_SSE5"
14033   "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14034   [(set_attr "type" "sse4arg")
14035    (set_attr "mode" "<MODE>")])
14036
14037 \f
14038 ;; Basic conditional jump instructions.
14039 ;; We ignore the overflow flag for signed branch instructions.
14040
14041 ;; For all bCOND expanders, also expand the compare or test insn that
14042 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
14043
14044 (define_expand "b<code>"
14045   [(set (pc)
14046         (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
14047                                    (const_int 0))
14048                       (label_ref (match_operand 0 ""))
14049                       (pc)))]
14050   ""
14051   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14052
14053 (define_expand "b<code>"
14054   [(set (pc)
14055         (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
14056                                   (const_int 0))
14057                       (label_ref (match_operand 0 ""))
14058                       (pc)))]
14059   "TARGET_80387 || TARGET_SSE_MATH"
14060   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14061
14062 (define_insn "*jcc_1"
14063   [(set (pc)
14064         (if_then_else (match_operator 1 "ix86_comparison_operator"
14065                                       [(reg FLAGS_REG) (const_int 0)])
14066                       (label_ref (match_operand 0 "" ""))
14067                       (pc)))]
14068   ""
14069   "%+j%C1\t%l0"
14070   [(set_attr "type" "ibr")
14071    (set_attr "modrm" "0")
14072    (set (attr "length")
14073            (if_then_else (and (ge (minus (match_dup 0) (pc))
14074                                   (const_int -126))
14075                               (lt (minus (match_dup 0) (pc))
14076                                   (const_int 128)))
14077              (const_int 2)
14078              (const_int 6)))])
14079
14080 (define_insn "*jcc_2"
14081   [(set (pc)
14082         (if_then_else (match_operator 1 "ix86_comparison_operator"
14083                                       [(reg FLAGS_REG) (const_int 0)])
14084                       (pc)
14085                       (label_ref (match_operand 0 "" ""))))]
14086   ""
14087   "%+j%c1\t%l0"
14088   [(set_attr "type" "ibr")
14089    (set_attr "modrm" "0")
14090    (set (attr "length")
14091            (if_then_else (and (ge (minus (match_dup 0) (pc))
14092                                   (const_int -126))
14093                               (lt (minus (match_dup 0) (pc))
14094                                   (const_int 128)))
14095              (const_int 2)
14096              (const_int 6)))])
14097
14098 ;; In general it is not safe to assume too much about CCmode registers,
14099 ;; so simplify-rtx stops when it sees a second one.  Under certain
14100 ;; conditions this is safe on x86, so help combine not create
14101 ;;
14102 ;;      seta    %al
14103 ;;      testb   %al, %al
14104 ;;      je      Lfoo
14105
14106 (define_split
14107   [(set (pc)
14108         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14109                                       [(reg FLAGS_REG) (const_int 0)])
14110                           (const_int 0))
14111                       (label_ref (match_operand 1 "" ""))
14112                       (pc)))]
14113   ""
14114   [(set (pc)
14115         (if_then_else (match_dup 0)
14116                       (label_ref (match_dup 1))
14117                       (pc)))]
14118 {
14119   PUT_MODE (operands[0], VOIDmode);
14120 })
14121
14122 (define_split
14123   [(set (pc)
14124         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14125                                       [(reg FLAGS_REG) (const_int 0)])
14126                           (const_int 0))
14127                       (label_ref (match_operand 1 "" ""))
14128                       (pc)))]
14129   ""
14130   [(set (pc)
14131         (if_then_else (match_dup 0)
14132                       (label_ref (match_dup 1))
14133                       (pc)))]
14134 {
14135   rtx new_op0 = copy_rtx (operands[0]);
14136   operands[0] = new_op0;
14137   PUT_MODE (new_op0, VOIDmode);
14138   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14139                                              GET_MODE (XEXP (new_op0, 0))));
14140
14141   /* Make sure that (a) the CCmode we have for the flags is strong
14142      enough for the reversed compare or (b) we have a valid FP compare.  */
14143   if (! ix86_comparison_operator (new_op0, VOIDmode))
14144     FAIL;
14145 })
14146
14147 ;; Define combination compare-and-branch fp compare instructions to use
14148 ;; during early optimization.  Splitting the operation apart early makes
14149 ;; for bad code when we want to reverse the operation.
14150
14151 (define_insn "*fp_jcc_1_mixed"
14152   [(set (pc)
14153         (if_then_else (match_operator 0 "comparison_operator"
14154                         [(match_operand 1 "register_operand" "f,x")
14155                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14156           (label_ref (match_operand 3 "" ""))
14157           (pc)))
14158    (clobber (reg:CCFP FPSR_REG))
14159    (clobber (reg:CCFP FLAGS_REG))]
14160   "TARGET_MIX_SSE_I387
14161    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14162    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14163    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14164   "#")
14165
14166 (define_insn "*fp_jcc_1_sse"
14167   [(set (pc)
14168         (if_then_else (match_operator 0 "comparison_operator"
14169                         [(match_operand 1 "register_operand" "x")
14170                          (match_operand 2 "nonimmediate_operand" "xm")])
14171           (label_ref (match_operand 3 "" ""))
14172           (pc)))
14173    (clobber (reg:CCFP FPSR_REG))
14174    (clobber (reg:CCFP FLAGS_REG))]
14175   "TARGET_SSE_MATH
14176    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14177    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14178    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14179   "#")
14180
14181 (define_insn "*fp_jcc_1_387"
14182   [(set (pc)
14183         (if_then_else (match_operator 0 "comparison_operator"
14184                         [(match_operand 1 "register_operand" "f")
14185                          (match_operand 2 "register_operand" "f")])
14186           (label_ref (match_operand 3 "" ""))
14187           (pc)))
14188    (clobber (reg:CCFP FPSR_REG))
14189    (clobber (reg:CCFP FLAGS_REG))]
14190   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14191    && TARGET_CMOVE
14192    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14193    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14194   "#")
14195
14196 (define_insn "*fp_jcc_2_mixed"
14197   [(set (pc)
14198         (if_then_else (match_operator 0 "comparison_operator"
14199                         [(match_operand 1 "register_operand" "f,x")
14200                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14201           (pc)
14202           (label_ref (match_operand 3 "" ""))))
14203    (clobber (reg:CCFP FPSR_REG))
14204    (clobber (reg:CCFP FLAGS_REG))]
14205   "TARGET_MIX_SSE_I387
14206    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14207    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14208    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14209   "#")
14210
14211 (define_insn "*fp_jcc_2_sse"
14212   [(set (pc)
14213         (if_then_else (match_operator 0 "comparison_operator"
14214                         [(match_operand 1 "register_operand" "x")
14215                          (match_operand 2 "nonimmediate_operand" "xm")])
14216           (pc)
14217           (label_ref (match_operand 3 "" ""))))
14218    (clobber (reg:CCFP FPSR_REG))
14219    (clobber (reg:CCFP FLAGS_REG))]
14220   "TARGET_SSE_MATH
14221    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14222    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14223    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14224   "#")
14225
14226 (define_insn "*fp_jcc_2_387"
14227   [(set (pc)
14228         (if_then_else (match_operator 0 "comparison_operator"
14229                         [(match_operand 1 "register_operand" "f")
14230                          (match_operand 2 "register_operand" "f")])
14231           (pc)
14232           (label_ref (match_operand 3 "" ""))))
14233    (clobber (reg:CCFP FPSR_REG))
14234    (clobber (reg:CCFP FLAGS_REG))]
14235   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14236    && TARGET_CMOVE
14237    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14238    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14239   "#")
14240
14241 (define_insn "*fp_jcc_3_387"
14242   [(set (pc)
14243         (if_then_else (match_operator 0 "comparison_operator"
14244                         [(match_operand 1 "register_operand" "f")
14245                          (match_operand 2 "nonimmediate_operand" "fm")])
14246           (label_ref (match_operand 3 "" ""))
14247           (pc)))
14248    (clobber (reg:CCFP FPSR_REG))
14249    (clobber (reg:CCFP FLAGS_REG))
14250    (clobber (match_scratch:HI 4 "=a"))]
14251   "TARGET_80387
14252    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14253    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14254    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14255    && SELECT_CC_MODE (GET_CODE (operands[0]),
14256                       operands[1], operands[2]) == CCFPmode
14257    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14258   "#")
14259
14260 (define_insn "*fp_jcc_4_387"
14261   [(set (pc)
14262         (if_then_else (match_operator 0 "comparison_operator"
14263                         [(match_operand 1 "register_operand" "f")
14264                          (match_operand 2 "nonimmediate_operand" "fm")])
14265           (pc)
14266           (label_ref (match_operand 3 "" ""))))
14267    (clobber (reg:CCFP FPSR_REG))
14268    (clobber (reg:CCFP FLAGS_REG))
14269    (clobber (match_scratch:HI 4 "=a"))]
14270   "TARGET_80387
14271    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14272    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14273    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14274    && SELECT_CC_MODE (GET_CODE (operands[0]),
14275                       operands[1], operands[2]) == CCFPmode
14276    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14277   "#")
14278
14279 (define_insn "*fp_jcc_5_387"
14280   [(set (pc)
14281         (if_then_else (match_operator 0 "comparison_operator"
14282                         [(match_operand 1 "register_operand" "f")
14283                          (match_operand 2 "register_operand" "f")])
14284           (label_ref (match_operand 3 "" ""))
14285           (pc)))
14286    (clobber (reg:CCFP FPSR_REG))
14287    (clobber (reg:CCFP FLAGS_REG))
14288    (clobber (match_scratch:HI 4 "=a"))]
14289   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14290    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14291    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14292   "#")
14293
14294 (define_insn "*fp_jcc_6_387"
14295   [(set (pc)
14296         (if_then_else (match_operator 0 "comparison_operator"
14297                         [(match_operand 1 "register_operand" "f")
14298                          (match_operand 2 "register_operand" "f")])
14299           (pc)
14300           (label_ref (match_operand 3 "" ""))))
14301    (clobber (reg:CCFP FPSR_REG))
14302    (clobber (reg:CCFP FLAGS_REG))
14303    (clobber (match_scratch:HI 4 "=a"))]
14304   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14305    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14306    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14307   "#")
14308
14309 (define_insn "*fp_jcc_7_387"
14310   [(set (pc)
14311         (if_then_else (match_operator 0 "comparison_operator"
14312                         [(match_operand 1 "register_operand" "f")
14313                          (match_operand 2 "const0_operand" "X")])
14314           (label_ref (match_operand 3 "" ""))
14315           (pc)))
14316    (clobber (reg:CCFP FPSR_REG))
14317    (clobber (reg:CCFP FLAGS_REG))
14318    (clobber (match_scratch:HI 4 "=a"))]
14319   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14320    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14321    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14322    && SELECT_CC_MODE (GET_CODE (operands[0]),
14323                       operands[1], operands[2]) == CCFPmode
14324    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14325   "#")
14326
14327 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14328 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14329 ;; with a precedence over other operators and is always put in the first
14330 ;; place. Swap condition and operands to match ficom instruction.
14331
14332 (define_insn "*fp_jcc_8<mode>_387"
14333   [(set (pc)
14334         (if_then_else (match_operator 0 "comparison_operator"
14335                         [(match_operator 1 "float_operator"
14336                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14337                            (match_operand 3 "register_operand" "f,f")])
14338           (label_ref (match_operand 4 "" ""))
14339           (pc)))
14340    (clobber (reg:CCFP FPSR_REG))
14341    (clobber (reg:CCFP FLAGS_REG))
14342    (clobber (match_scratch:HI 5 "=a,a"))]
14343   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14344    && TARGET_USE_<MODE>MODE_FIOP
14345    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14346    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14347    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14348    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14349   "#")
14350
14351 (define_split
14352   [(set (pc)
14353         (if_then_else (match_operator 0 "comparison_operator"
14354                         [(match_operand 1 "register_operand" "")
14355                          (match_operand 2 "nonimmediate_operand" "")])
14356           (match_operand 3 "" "")
14357           (match_operand 4 "" "")))
14358    (clobber (reg:CCFP FPSR_REG))
14359    (clobber (reg:CCFP FLAGS_REG))]
14360   "reload_completed"
14361   [(const_int 0)]
14362 {
14363   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14364                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14365   DONE;
14366 })
14367
14368 (define_split
14369   [(set (pc)
14370         (if_then_else (match_operator 0 "comparison_operator"
14371                         [(match_operand 1 "register_operand" "")
14372                          (match_operand 2 "general_operand" "")])
14373           (match_operand 3 "" "")
14374           (match_operand 4 "" "")))
14375    (clobber (reg:CCFP FPSR_REG))
14376    (clobber (reg:CCFP FLAGS_REG))
14377    (clobber (match_scratch:HI 5 "=a"))]
14378   "reload_completed"
14379   [(const_int 0)]
14380 {
14381   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14382                         operands[3], operands[4], operands[5], NULL_RTX);
14383   DONE;
14384 })
14385
14386 (define_split
14387   [(set (pc)
14388         (if_then_else (match_operator 0 "comparison_operator"
14389                         [(match_operator 1 "float_operator"
14390                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14391                            (match_operand 3 "register_operand" "")])
14392           (match_operand 4 "" "")
14393           (match_operand 5 "" "")))
14394    (clobber (reg:CCFP FPSR_REG))
14395    (clobber (reg:CCFP FLAGS_REG))
14396    (clobber (match_scratch:HI 6 "=a"))]
14397   "reload_completed"
14398   [(const_int 0)]
14399 {
14400   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14401   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14402                         operands[3], operands[7],
14403                         operands[4], operands[5], operands[6], NULL_RTX);
14404   DONE;
14405 })
14406
14407 ;; %%% Kill this when reload knows how to do it.
14408 (define_split
14409   [(set (pc)
14410         (if_then_else (match_operator 0 "comparison_operator"
14411                         [(match_operator 1 "float_operator"
14412                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14413                            (match_operand 3 "register_operand" "")])
14414           (match_operand 4 "" "")
14415           (match_operand 5 "" "")))
14416    (clobber (reg:CCFP FPSR_REG))
14417    (clobber (reg:CCFP FLAGS_REG))
14418    (clobber (match_scratch:HI 6 "=a"))]
14419   "reload_completed"
14420   [(const_int 0)]
14421 {
14422   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14423   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14424   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14425                         operands[3], operands[7],
14426                         operands[4], operands[5], operands[6], operands[2]);
14427   DONE;
14428 })
14429 \f
14430 ;; Unconditional and other jump instructions
14431
14432 (define_insn "jump"
14433   [(set (pc)
14434         (label_ref (match_operand 0 "" "")))]
14435   ""
14436   "jmp\t%l0"
14437   [(set_attr "type" "ibr")
14438    (set (attr "length")
14439            (if_then_else (and (ge (minus (match_dup 0) (pc))
14440                                   (const_int -126))
14441                               (lt (minus (match_dup 0) (pc))
14442                                   (const_int 128)))
14443              (const_int 2)
14444              (const_int 5)))
14445    (set_attr "modrm" "0")])
14446
14447 (define_expand "indirect_jump"
14448   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14449   ""
14450   "")
14451
14452 (define_insn "*indirect_jump"
14453   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14454   "!TARGET_64BIT"
14455   "jmp\t%A0"
14456   [(set_attr "type" "ibr")
14457    (set_attr "length_immediate" "0")])
14458
14459 (define_insn "*indirect_jump_rtx64"
14460   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14461   "TARGET_64BIT"
14462   "jmp\t%A0"
14463   [(set_attr "type" "ibr")
14464    (set_attr "length_immediate" "0")])
14465
14466 (define_expand "tablejump"
14467   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14468               (use (label_ref (match_operand 1 "" "")))])]
14469   ""
14470 {
14471   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14472      relative.  Convert the relative address to an absolute address.  */
14473   if (flag_pic)
14474     {
14475       rtx op0, op1;
14476       enum rtx_code code;
14477
14478       /* We can't use @GOTOFF for text labels on VxWorks;
14479          see gotoff_operand.  */
14480       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14481         {
14482           code = PLUS;
14483           op0 = operands[0];
14484           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14485         }
14486       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14487         {
14488           code = PLUS;
14489           op0 = operands[0];
14490           op1 = pic_offset_table_rtx;
14491         }
14492       else
14493         {
14494           code = MINUS;
14495           op0 = pic_offset_table_rtx;
14496           op1 = operands[0];
14497         }
14498
14499       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14500                                          OPTAB_DIRECT);
14501     }
14502 })
14503
14504 (define_insn "*tablejump_1"
14505   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14506    (use (label_ref (match_operand 1 "" "")))]
14507   "!TARGET_64BIT"
14508   "jmp\t%A0"
14509   [(set_attr "type" "ibr")
14510    (set_attr "length_immediate" "0")])
14511
14512 (define_insn "*tablejump_1_rtx64"
14513   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14514    (use (label_ref (match_operand 1 "" "")))]
14515   "TARGET_64BIT"
14516   "jmp\t%A0"
14517   [(set_attr "type" "ibr")
14518    (set_attr "length_immediate" "0")])
14519 \f
14520 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14521
14522 (define_peephole2
14523   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14524    (set (match_operand:QI 1 "register_operand" "")
14525         (match_operator:QI 2 "ix86_comparison_operator"
14526           [(reg FLAGS_REG) (const_int 0)]))
14527    (set (match_operand 3 "q_regs_operand" "")
14528         (zero_extend (match_dup 1)))]
14529   "(peep2_reg_dead_p (3, operands[1])
14530     || operands_match_p (operands[1], operands[3]))
14531    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14532   [(set (match_dup 4) (match_dup 0))
14533    (set (strict_low_part (match_dup 5))
14534         (match_dup 2))]
14535 {
14536   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14537   operands[5] = gen_lowpart (QImode, operands[3]);
14538   ix86_expand_clear (operands[3]);
14539 })
14540
14541 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14542
14543 (define_peephole2
14544   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14545    (set (match_operand:QI 1 "register_operand" "")
14546         (match_operator:QI 2 "ix86_comparison_operator"
14547           [(reg FLAGS_REG) (const_int 0)]))
14548    (parallel [(set (match_operand 3 "q_regs_operand" "")
14549                    (zero_extend (match_dup 1)))
14550               (clobber (reg:CC FLAGS_REG))])]
14551   "(peep2_reg_dead_p (3, operands[1])
14552     || operands_match_p (operands[1], operands[3]))
14553    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14554   [(set (match_dup 4) (match_dup 0))
14555    (set (strict_low_part (match_dup 5))
14556         (match_dup 2))]
14557 {
14558   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14559   operands[5] = gen_lowpart (QImode, operands[3]);
14560   ix86_expand_clear (operands[3]);
14561 })
14562 \f
14563 ;; Call instructions.
14564
14565 ;; The predicates normally associated with named expanders are not properly
14566 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14567 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14568
14569 ;; Call subroutine returning no value.
14570
14571 (define_expand "call_pop"
14572   [(parallel [(call (match_operand:QI 0 "" "")
14573                     (match_operand:SI 1 "" ""))
14574               (set (reg:SI SP_REG)
14575                    (plus:SI (reg:SI SP_REG)
14576                             (match_operand:SI 3 "" "")))])]
14577   "!TARGET_64BIT"
14578 {
14579   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14580   DONE;
14581 })
14582
14583 (define_insn "*call_pop_0"
14584   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14585          (match_operand:SI 1 "" ""))
14586    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14587                             (match_operand:SI 2 "immediate_operand" "")))]
14588   "!TARGET_64BIT"
14589 {
14590   if (SIBLING_CALL_P (insn))
14591     return "jmp\t%P0";
14592   else
14593     return "call\t%P0";
14594 }
14595   [(set_attr "type" "call")])
14596
14597 (define_insn "*call_pop_1"
14598   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14599          (match_operand:SI 1 "" ""))
14600    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14601                             (match_operand:SI 2 "immediate_operand" "i")))]
14602   "!TARGET_64BIT"
14603 {
14604   if (constant_call_address_operand (operands[0], Pmode))
14605     {
14606       if (SIBLING_CALL_P (insn))
14607         return "jmp\t%P0";
14608       else
14609         return "call\t%P0";
14610     }
14611   if (SIBLING_CALL_P (insn))
14612     return "jmp\t%A0";
14613   else
14614     return "call\t%A0";
14615 }
14616   [(set_attr "type" "call")])
14617
14618 (define_expand "call"
14619   [(call (match_operand:QI 0 "" "")
14620          (match_operand 1 "" ""))
14621    (use (match_operand 2 "" ""))]
14622   ""
14623 {
14624   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14625   DONE;
14626 })
14627
14628 (define_expand "sibcall"
14629   [(call (match_operand:QI 0 "" "")
14630          (match_operand 1 "" ""))
14631    (use (match_operand 2 "" ""))]
14632   ""
14633 {
14634   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14635   DONE;
14636 })
14637
14638 (define_insn "*call_0"
14639   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14640          (match_operand 1 "" ""))]
14641   ""
14642 {
14643   if (SIBLING_CALL_P (insn))
14644     return "jmp\t%P0";
14645   else
14646     return "call\t%P0";
14647 }
14648   [(set_attr "type" "call")])
14649
14650 (define_insn "*call_1"
14651   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14652          (match_operand 1 "" ""))]
14653   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14654 {
14655   if (constant_call_address_operand (operands[0], Pmode))
14656     return "call\t%P0";
14657   return "call\t%A0";
14658 }
14659   [(set_attr "type" "call")])
14660
14661 (define_insn "*sibcall_1"
14662   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14663          (match_operand 1 "" ""))]
14664   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14665 {
14666   if (constant_call_address_operand (operands[0], Pmode))
14667     return "jmp\t%P0";
14668   return "jmp\t%A0";
14669 }
14670   [(set_attr "type" "call")])
14671
14672 (define_insn "*call_1_rex64"
14673   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14674          (match_operand 1 "" ""))]
14675   "!SIBLING_CALL_P (insn) && TARGET_64BIT
14676    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14677 {
14678   if (constant_call_address_operand (operands[0], Pmode))
14679     return "call\t%P0";
14680   return "call\t%A0";
14681 }
14682   [(set_attr "type" "call")])
14683
14684 (define_insn "*call_1_rex64_large"
14685   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14686          (match_operand 1 "" ""))]
14687   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14688   "call\t%A0"
14689   [(set_attr "type" "call")])
14690
14691 (define_insn "*sibcall_1_rex64"
14692   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14693          (match_operand 1 "" ""))]
14694   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14695   "jmp\t%P0"
14696   [(set_attr "type" "call")])
14697
14698 (define_insn "*sibcall_1_rex64_v"
14699   [(call (mem:QI (reg:DI R11_REG))
14700          (match_operand 0 "" ""))]
14701   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14702   "jmp\t{*%%}r11"
14703   [(set_attr "type" "call")])
14704
14705
14706 ;; Call subroutine, returning value in operand 0
14707
14708 (define_expand "call_value_pop"
14709   [(parallel [(set (match_operand 0 "" "")
14710                    (call (match_operand:QI 1 "" "")
14711                          (match_operand:SI 2 "" "")))
14712               (set (reg:SI SP_REG)
14713                    (plus:SI (reg:SI SP_REG)
14714                             (match_operand:SI 4 "" "")))])]
14715   "!TARGET_64BIT"
14716 {
14717   ix86_expand_call (operands[0], operands[1], operands[2],
14718                     operands[3], operands[4], 0);
14719   DONE;
14720 })
14721
14722 (define_expand "call_value"
14723   [(set (match_operand 0 "" "")
14724         (call (match_operand:QI 1 "" "")
14725               (match_operand:SI 2 "" "")))
14726    (use (match_operand:SI 3 "" ""))]
14727   ;; Operand 2 not used on the i386.
14728   ""
14729 {
14730   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14731   DONE;
14732 })
14733
14734 (define_expand "sibcall_value"
14735   [(set (match_operand 0 "" "")
14736         (call (match_operand:QI 1 "" "")
14737               (match_operand:SI 2 "" "")))
14738    (use (match_operand:SI 3 "" ""))]
14739   ;; Operand 2 not used on the i386.
14740   ""
14741 {
14742   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14743   DONE;
14744 })
14745
14746 ;; Call subroutine returning any type.
14747
14748 (define_expand "untyped_call"
14749   [(parallel [(call (match_operand 0 "" "")
14750                     (const_int 0))
14751               (match_operand 1 "" "")
14752               (match_operand 2 "" "")])]
14753   ""
14754 {
14755   int i;
14756
14757   /* In order to give reg-stack an easier job in validating two
14758      coprocessor registers as containing a possible return value,
14759      simply pretend the untyped call returns a complex long double
14760      value.  */
14761
14762   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14763                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14764                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14765                     NULL, 0);
14766
14767   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14768     {
14769       rtx set = XVECEXP (operands[2], 0, i);
14770       emit_move_insn (SET_DEST (set), SET_SRC (set));
14771     }
14772
14773   /* The optimizer does not know that the call sets the function value
14774      registers we stored in the result block.  We avoid problems by
14775      claiming that all hard registers are used and clobbered at this
14776      point.  */
14777   emit_insn (gen_blockage ());
14778
14779   DONE;
14780 })
14781 \f
14782 ;; Prologue and epilogue instructions
14783
14784 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14785 ;; all of memory.  This blocks insns from being moved across this point.
14786
14787 (define_insn "blockage"
14788   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14789   ""
14790   ""
14791   [(set_attr "length" "0")])
14792
14793 ;; As USE insns aren't meaningful after reload, this is used instead
14794 ;; to prevent deleting instructions setting registers for PIC code
14795 (define_insn "prologue_use"
14796   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14797   ""
14798   ""
14799   [(set_attr "length" "0")])
14800
14801 ;; Insn emitted into the body of a function to return from a function.
14802 ;; This is only done if the function's epilogue is known to be simple.
14803 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14804
14805 (define_expand "return"
14806   [(return)]
14807   "ix86_can_use_return_insn_p ()"
14808 {
14809   if (current_function_pops_args)
14810     {
14811       rtx popc = GEN_INT (current_function_pops_args);
14812       emit_jump_insn (gen_return_pop_internal (popc));
14813       DONE;
14814     }
14815 })
14816
14817 (define_insn "return_internal"
14818   [(return)]
14819   "reload_completed"
14820   "ret"
14821   [(set_attr "length" "1")
14822    (set_attr "length_immediate" "0")
14823    (set_attr "modrm" "0")])
14824
14825 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14826 ;; instruction Athlon and K8 have.
14827
14828 (define_insn "return_internal_long"
14829   [(return)
14830    (unspec [(const_int 0)] UNSPEC_REP)]
14831   "reload_completed"
14832   "rep\;ret"
14833   [(set_attr "length" "1")
14834    (set_attr "length_immediate" "0")
14835    (set_attr "prefix_rep" "1")
14836    (set_attr "modrm" "0")])
14837
14838 (define_insn "return_pop_internal"
14839   [(return)
14840    (use (match_operand:SI 0 "const_int_operand" ""))]
14841   "reload_completed"
14842   "ret\t%0"
14843   [(set_attr "length" "3")
14844    (set_attr "length_immediate" "2")
14845    (set_attr "modrm" "0")])
14846
14847 (define_insn "return_indirect_internal"
14848   [(return)
14849    (use (match_operand:SI 0 "register_operand" "r"))]
14850   "reload_completed"
14851   "jmp\t%A0"
14852   [(set_attr "type" "ibr")
14853    (set_attr "length_immediate" "0")])
14854
14855 (define_insn "nop"
14856   [(const_int 0)]
14857   ""
14858   "nop"
14859   [(set_attr "length" "1")
14860    (set_attr "length_immediate" "0")
14861    (set_attr "modrm" "0")])
14862
14863 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14864 ;; branch prediction penalty for the third jump in a 16-byte
14865 ;; block on K8.
14866
14867 (define_insn "align"
14868   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14869   ""
14870 {
14871 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14872   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14873 #else
14874   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14875      The align insn is used to avoid 3 jump instructions in the row to improve
14876      branch prediction and the benefits hardly outweigh the cost of extra 8
14877      nops on the average inserted by full alignment pseudo operation.  */
14878 #endif
14879   return "";
14880 }
14881   [(set_attr "length" "16")])
14882
14883 (define_expand "prologue"
14884   [(const_int 0)]
14885   ""
14886   "ix86_expand_prologue (); DONE;")
14887
14888 (define_insn "set_got"
14889   [(set (match_operand:SI 0 "register_operand" "=r")
14890         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14891    (clobber (reg:CC FLAGS_REG))]
14892   "!TARGET_64BIT"
14893   { return output_set_got (operands[0], NULL_RTX); }
14894   [(set_attr "type" "multi")
14895    (set_attr "length" "12")])
14896
14897 (define_insn "set_got_labelled"
14898   [(set (match_operand:SI 0 "register_operand" "=r")
14899         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14900          UNSPEC_SET_GOT))
14901    (clobber (reg:CC FLAGS_REG))]
14902   "!TARGET_64BIT"
14903   { return output_set_got (operands[0], operands[1]); }
14904   [(set_attr "type" "multi")
14905    (set_attr "length" "12")])
14906
14907 (define_insn "set_got_rex64"
14908   [(set (match_operand:DI 0 "register_operand" "=r")
14909         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14910   "TARGET_64BIT"
14911   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14912   [(set_attr "type" "lea")
14913    (set_attr "length" "6")])
14914
14915 (define_insn "set_rip_rex64"
14916   [(set (match_operand:DI 0 "register_operand" "=r")
14917         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14918   "TARGET_64BIT"
14919   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
14920   [(set_attr "type" "lea")
14921    (set_attr "length" "6")])
14922
14923 (define_insn "set_got_offset_rex64"
14924   [(set (match_operand:DI 0 "register_operand" "=r")
14925         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
14926   "TARGET_64BIT"
14927   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
14928   [(set_attr "type" "imov")
14929    (set_attr "length" "11")])
14930
14931 (define_expand "epilogue"
14932   [(const_int 0)]
14933   ""
14934   "ix86_expand_epilogue (1); DONE;")
14935
14936 (define_expand "sibcall_epilogue"
14937   [(const_int 0)]
14938   ""
14939   "ix86_expand_epilogue (0); DONE;")
14940
14941 (define_expand "eh_return"
14942   [(use (match_operand 0 "register_operand" ""))]
14943   ""
14944 {
14945   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14946
14947   /* Tricky bit: we write the address of the handler to which we will
14948      be returning into someone else's stack frame, one word below the
14949      stack address we wish to restore.  */
14950   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14951   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14952   tmp = gen_rtx_MEM (Pmode, tmp);
14953   emit_move_insn (tmp, ra);
14954
14955   if (Pmode == SImode)
14956     emit_jump_insn (gen_eh_return_si (sa));
14957   else
14958     emit_jump_insn (gen_eh_return_di (sa));
14959   emit_barrier ();
14960   DONE;
14961 })
14962
14963 (define_insn_and_split "eh_return_si"
14964   [(set (pc)
14965         (unspec [(match_operand:SI 0 "register_operand" "c")]
14966                  UNSPEC_EH_RETURN))]
14967   "!TARGET_64BIT"
14968   "#"
14969   "reload_completed"
14970   [(const_int 0)]
14971   "ix86_expand_epilogue (2); DONE;")
14972
14973 (define_insn_and_split "eh_return_di"
14974   [(set (pc)
14975         (unspec [(match_operand:DI 0 "register_operand" "c")]
14976                  UNSPEC_EH_RETURN))]
14977   "TARGET_64BIT"
14978   "#"
14979   "reload_completed"
14980   [(const_int 0)]
14981   "ix86_expand_epilogue (2); DONE;")
14982
14983 (define_insn "leave"
14984   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14985    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14986    (clobber (mem:BLK (scratch)))]
14987   "!TARGET_64BIT"
14988   "leave"
14989   [(set_attr "type" "leave")])
14990
14991 (define_insn "leave_rex64"
14992   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14993    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14994    (clobber (mem:BLK (scratch)))]
14995   "TARGET_64BIT"
14996   "leave"
14997   [(set_attr "type" "leave")])
14998 \f
14999 (define_expand "ffssi2"
15000   [(parallel
15001      [(set (match_operand:SI 0 "register_operand" "")
15002            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15003       (clobber (match_scratch:SI 2 ""))
15004       (clobber (reg:CC FLAGS_REG))])]
15005   ""
15006 {
15007   if (TARGET_CMOVE)
15008     {
15009       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15010       DONE;
15011     }
15012 })
15013
15014 (define_expand "ffs_cmove"
15015   [(set (match_dup 2) (const_int -1))
15016    (parallel [(set (reg:CCZ FLAGS_REG)
15017                    (compare:CCZ (match_operand:SI 1 "register_operand" "")
15018                                 (const_int 0)))
15019               (set (match_operand:SI 0 "nonimmediate_operand" "")
15020                    (ctz:SI (match_dup 1)))])
15021    (set (match_dup 0) (if_then_else:SI
15022                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15023                         (match_dup 2)
15024                         (match_dup 0)))
15025    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15026               (clobber (reg:CC FLAGS_REG))])]
15027   "TARGET_CMOVE"
15028   "operands[2] = gen_reg_rtx (SImode);")
15029
15030 (define_insn_and_split "*ffs_no_cmove"
15031   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
15032         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15033    (clobber (match_scratch:SI 2 "=&q"))
15034    (clobber (reg:CC FLAGS_REG))]
15035   "!TARGET_CMOVE"
15036   "#"
15037   "&& reload_completed"
15038   [(parallel [(set (reg:CCZ FLAGS_REG)
15039                    (compare:CCZ (match_dup 1) (const_int 0)))
15040               (set (match_dup 0) (ctz:SI (match_dup 1)))])
15041    (set (strict_low_part (match_dup 3))
15042         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15043    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15044               (clobber (reg:CC FLAGS_REG))])
15045    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15046               (clobber (reg:CC FLAGS_REG))])
15047    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15048               (clobber (reg:CC FLAGS_REG))])]
15049 {
15050   operands[3] = gen_lowpart (QImode, operands[2]);
15051   ix86_expand_clear (operands[2]);
15052 })
15053
15054 (define_insn "*ffssi_1"
15055   [(set (reg:CCZ FLAGS_REG)
15056         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15057                      (const_int 0)))
15058    (set (match_operand:SI 0 "register_operand" "=r")
15059         (ctz:SI (match_dup 1)))]
15060   ""
15061   "bsf{l}\t{%1, %0|%0, %1}"
15062   [(set_attr "prefix_0f" "1")])
15063
15064 (define_expand "ffsdi2"
15065   [(set (match_dup 2) (const_int -1))
15066    (parallel [(set (reg:CCZ FLAGS_REG)
15067                    (compare:CCZ (match_operand:DI 1 "register_operand" "")
15068                                 (const_int 0)))
15069               (set (match_operand:DI 0 "nonimmediate_operand" "")
15070                    (ctz:DI (match_dup 1)))])
15071    (set (match_dup 0) (if_then_else:DI
15072                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15073                         (match_dup 2)
15074                         (match_dup 0)))
15075    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15076               (clobber (reg:CC FLAGS_REG))])]
15077   "TARGET_64BIT"
15078   "operands[2] = gen_reg_rtx (DImode);")
15079
15080 (define_insn "*ffsdi_1"
15081   [(set (reg:CCZ FLAGS_REG)
15082         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15083                      (const_int 0)))
15084    (set (match_operand:DI 0 "register_operand" "=r")
15085         (ctz:DI (match_dup 1)))]
15086   "TARGET_64BIT"
15087   "bsf{q}\t{%1, %0|%0, %1}"
15088   [(set_attr "prefix_0f" "1")])
15089
15090 (define_insn "ctzsi2"
15091   [(set (match_operand:SI 0 "register_operand" "=r")
15092         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15093    (clobber (reg:CC FLAGS_REG))]
15094   ""
15095   "bsf{l}\t{%1, %0|%0, %1}"
15096   [(set_attr "prefix_0f" "1")])
15097
15098 (define_insn "ctzdi2"
15099   [(set (match_operand:DI 0 "register_operand" "=r")
15100         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15101    (clobber (reg:CC FLAGS_REG))]
15102   "TARGET_64BIT"
15103   "bsf{q}\t{%1, %0|%0, %1}"
15104   [(set_attr "prefix_0f" "1")])
15105
15106 (define_expand "clzsi2"
15107   [(parallel
15108      [(set (match_operand:SI 0 "register_operand" "")
15109            (minus:SI (const_int 31)
15110                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15111       (clobber (reg:CC FLAGS_REG))])
15112    (parallel
15113      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15114       (clobber (reg:CC FLAGS_REG))])]
15115   ""
15116 {
15117   if (TARGET_ABM)
15118     {
15119       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15120       DONE;
15121     }
15122 })
15123
15124 (define_insn "clzsi2_abm"
15125   [(set (match_operand:SI 0 "register_operand" "=r")
15126         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15127    (clobber (reg:CC FLAGS_REG))]
15128   "TARGET_ABM"
15129   "lzcnt{l}\t{%1, %0|%0, %1}"
15130   [(set_attr "prefix_rep" "1")
15131    (set_attr "type" "bitmanip")
15132    (set_attr "mode" "SI")])
15133
15134 (define_insn "*bsr"
15135   [(set (match_operand:SI 0 "register_operand" "=r")
15136         (minus:SI (const_int 31)
15137                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15138    (clobber (reg:CC FLAGS_REG))]
15139   ""
15140   "bsr{l}\t{%1, %0|%0, %1}"
15141   [(set_attr "prefix_0f" "1")
15142    (set_attr "mode" "SI")])
15143
15144 (define_insn "popcountsi2"
15145   [(set (match_operand:SI 0 "register_operand" "=r")
15146         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15147    (clobber (reg:CC FLAGS_REG))]
15148   "TARGET_POPCNT"
15149   "popcnt{l}\t{%1, %0|%0, %1}"
15150   [(set_attr "prefix_rep" "1")
15151    (set_attr "type" "bitmanip")
15152    (set_attr "mode" "SI")])
15153
15154 (define_insn "*popcountsi2_cmp"
15155   [(set (reg FLAGS_REG)
15156         (compare
15157           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15158           (const_int 0)))
15159    (set (match_operand:SI 0 "register_operand" "=r")
15160         (popcount:SI (match_dup 1)))]
15161   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15162   "popcnt{l}\t{%1, %0|%0, %1}"
15163   [(set_attr "prefix_rep" "1")
15164    (set_attr "type" "bitmanip")
15165    (set_attr "mode" "SI")])
15166
15167 (define_insn "*popcountsi2_cmp_zext"
15168   [(set (reg FLAGS_REG)
15169         (compare
15170           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15171           (const_int 0)))
15172    (set (match_operand:DI 0 "register_operand" "=r")
15173         (zero_extend:DI(popcount:SI (match_dup 1))))]
15174   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15175   "popcnt{l}\t{%1, %0|%0, %1}"
15176   [(set_attr "prefix_rep" "1")
15177    (set_attr "type" "bitmanip")
15178    (set_attr "mode" "SI")])
15179
15180 (define_expand "bswapsi2"
15181   [(set (match_operand:SI 0 "register_operand" "")
15182         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15183   ""
15184 {
15185   if (!TARGET_BSWAP)
15186     {
15187       rtx x = operands[0];
15188
15189       emit_move_insn (x, operands[1]);
15190       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15191       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15192       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15193       DONE;
15194     }
15195 })
15196
15197 (define_insn "*bswapsi_1"
15198   [(set (match_operand:SI 0 "register_operand" "=r")
15199         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15200   "TARGET_BSWAP"
15201   "bswap\t%0"
15202   [(set_attr "prefix_0f" "1")
15203    (set_attr "length" "2")])
15204
15205 (define_insn "*bswaphi_lowpart_1"
15206   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15207         (bswap:HI (match_dup 0)))
15208    (clobber (reg:CC FLAGS_REG))]
15209   "TARGET_USE_XCHGB || optimize_size"
15210   "@
15211     xchg{b}\t{%h0, %b0|%b0, %h0}
15212     rol{w}\t{$8, %0|%0, 8}"
15213   [(set_attr "length" "2,4")
15214    (set_attr "mode" "QI,HI")])
15215
15216 (define_insn "bswaphi_lowpart"
15217   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15218         (bswap:HI (match_dup 0)))
15219    (clobber (reg:CC FLAGS_REG))]
15220   ""
15221   "rol{w}\t{$8, %0|%0, 8}"
15222   [(set_attr "length" "4")
15223    (set_attr "mode" "HI")])
15224
15225 (define_insn "bswapdi2"
15226   [(set (match_operand:DI 0 "register_operand" "=r")
15227         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15228   "TARGET_64BIT"
15229   "bswap\t%0"
15230   [(set_attr "prefix_0f" "1")
15231    (set_attr "length" "3")])
15232
15233 (define_expand "clzdi2"
15234   [(parallel
15235      [(set (match_operand:DI 0 "register_operand" "")
15236            (minus:DI (const_int 63)
15237                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15238       (clobber (reg:CC FLAGS_REG))])
15239    (parallel
15240      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15241       (clobber (reg:CC FLAGS_REG))])]
15242   "TARGET_64BIT"
15243 {
15244   if (TARGET_ABM)
15245     {
15246       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15247       DONE;
15248     }
15249 })
15250
15251 (define_insn "clzdi2_abm"
15252   [(set (match_operand:DI 0 "register_operand" "=r")
15253         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15254    (clobber (reg:CC FLAGS_REG))]
15255   "TARGET_64BIT && TARGET_ABM"
15256   "lzcnt{q}\t{%1, %0|%0, %1}"
15257   [(set_attr "prefix_rep" "1")
15258    (set_attr "type" "bitmanip")
15259    (set_attr "mode" "DI")])
15260
15261 (define_insn "*bsr_rex64"
15262   [(set (match_operand:DI 0 "register_operand" "=r")
15263         (minus:DI (const_int 63)
15264                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15265    (clobber (reg:CC FLAGS_REG))]
15266   "TARGET_64BIT"
15267   "bsr{q}\t{%1, %0|%0, %1}"
15268   [(set_attr "prefix_0f" "1")
15269    (set_attr "mode" "DI")])
15270
15271 (define_insn "popcountdi2"
15272   [(set (match_operand:DI 0 "register_operand" "=r")
15273         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15274    (clobber (reg:CC FLAGS_REG))]
15275   "TARGET_64BIT && TARGET_POPCNT"
15276   "popcnt{q}\t{%1, %0|%0, %1}"
15277   [(set_attr "prefix_rep" "1")
15278    (set_attr "type" "bitmanip")
15279    (set_attr "mode" "DI")])
15280
15281 (define_insn "*popcountdi2_cmp"
15282   [(set (reg FLAGS_REG)
15283         (compare
15284           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15285           (const_int 0)))
15286    (set (match_operand:DI 0 "register_operand" "=r")
15287         (popcount:DI (match_dup 1)))]
15288   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15289   "popcnt{q}\t{%1, %0|%0, %1}"
15290   [(set_attr "prefix_rep" "1")
15291    (set_attr "type" "bitmanip")
15292    (set_attr "mode" "DI")])
15293
15294 (define_expand "clzhi2"
15295   [(parallel
15296      [(set (match_operand:HI 0 "register_operand" "")
15297            (minus:HI (const_int 15)
15298                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15299       (clobber (reg:CC FLAGS_REG))])
15300    (parallel
15301      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15302       (clobber (reg:CC FLAGS_REG))])]
15303   ""
15304 {
15305   if (TARGET_ABM)
15306     {
15307       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15308       DONE;
15309     }
15310 })
15311
15312 (define_insn "clzhi2_abm"
15313   [(set (match_operand:HI 0 "register_operand" "=r")
15314         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15315    (clobber (reg:CC FLAGS_REG))]
15316   "TARGET_ABM"
15317   "lzcnt{w}\t{%1, %0|%0, %1}"
15318   [(set_attr "prefix_rep" "1")
15319    (set_attr "type" "bitmanip")
15320    (set_attr "mode" "HI")])
15321
15322 (define_insn "*bsrhi"
15323   [(set (match_operand:HI 0 "register_operand" "=r")
15324         (minus:HI (const_int 15)
15325                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15326    (clobber (reg:CC FLAGS_REG))]
15327   ""
15328   "bsr{w}\t{%1, %0|%0, %1}"
15329   [(set_attr "prefix_0f" "1")
15330    (set_attr "mode" "HI")])
15331
15332 (define_insn "popcounthi2"
15333   [(set (match_operand:HI 0 "register_operand" "=r")
15334         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15335    (clobber (reg:CC FLAGS_REG))]
15336   "TARGET_POPCNT"
15337   "popcnt{w}\t{%1, %0|%0, %1}"
15338   [(set_attr "prefix_rep" "1")
15339    (set_attr "type" "bitmanip")
15340    (set_attr "mode" "HI")])
15341
15342 (define_insn "*popcounthi2_cmp"
15343   [(set (reg FLAGS_REG)
15344         (compare
15345           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15346           (const_int 0)))
15347    (set (match_operand:HI 0 "register_operand" "=r")
15348         (popcount:HI (match_dup 1)))]
15349   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15350   "popcnt{w}\t{%1, %0|%0, %1}"
15351   [(set_attr "prefix_rep" "1")
15352    (set_attr "type" "bitmanip")
15353    (set_attr "mode" "HI")])
15354
15355 (define_expand "paritydi2"
15356   [(set (match_operand:DI 0 "register_operand" "")
15357         (parity:DI (match_operand:DI 1 "register_operand" "")))]
15358   "! TARGET_POPCNT"
15359 {
15360   rtx scratch = gen_reg_rtx (QImode);
15361   rtx cond;
15362
15363   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15364                                 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   if (TARGET_64BIT)
15372     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15373   else
15374     {
15375       rtx tmp = gen_reg_rtx (SImode);
15376
15377       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15378       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15379     }
15380   DONE;
15381 })
15382
15383 (define_insn_and_split "paritydi2_cmp"
15384   [(set (reg:CC FLAGS_REG)
15385         (parity:CC (match_operand:DI 3 "register_operand" "0")))
15386    (clobber (match_scratch:DI 0 "=r"))
15387    (clobber (match_scratch:SI 1 "=&r"))
15388    (clobber (match_scratch:HI 2 "=Q"))]
15389   "! TARGET_POPCNT"
15390   "#"
15391   "&& reload_completed"
15392   [(parallel
15393      [(set (match_dup 1)
15394            (xor:SI (match_dup 1) (match_dup 4)))
15395       (clobber (reg:CC FLAGS_REG))])
15396    (parallel
15397      [(set (reg:CC FLAGS_REG)
15398            (parity:CC (match_dup 1)))
15399       (clobber (match_dup 1))
15400       (clobber (match_dup 2))])]
15401 {
15402   operands[4] = gen_lowpart (SImode, operands[3]);
15403
15404   if (TARGET_64BIT)
15405     {
15406       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15407       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15408     }
15409   else
15410     operands[1] = gen_highpart (SImode, operands[3]);
15411 })
15412
15413 (define_expand "paritysi2"
15414   [(set (match_operand:SI 0 "register_operand" "")
15415         (parity:SI (match_operand:SI 1 "register_operand" "")))]
15416   "! TARGET_POPCNT"
15417 {
15418   rtx scratch = gen_reg_rtx (QImode);
15419   rtx cond;
15420
15421   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15422
15423   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15424                          gen_rtx_REG (CCmode, FLAGS_REG),
15425                          const0_rtx);
15426   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15427
15428   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15429   DONE;
15430 })
15431
15432 (define_insn_and_split "paritysi2_cmp"
15433   [(set (reg:CC FLAGS_REG)
15434         (parity:CC (match_operand:SI 2 "register_operand" "0")))
15435    (clobber (match_scratch:SI 0 "=r"))
15436    (clobber (match_scratch:HI 1 "=&Q"))]
15437   "! TARGET_POPCNT"
15438   "#"
15439   "&& reload_completed"
15440   [(parallel
15441      [(set (match_dup 1)
15442            (xor:HI (match_dup 1) (match_dup 3)))
15443       (clobber (reg:CC FLAGS_REG))])
15444    (parallel
15445      [(set (reg:CC FLAGS_REG)
15446            (parity:CC (match_dup 1)))
15447       (clobber (match_dup 1))])]
15448 {
15449   operands[3] = gen_lowpart (HImode, operands[2]);
15450
15451   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15452   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15453 })
15454
15455 (define_insn "*parityhi2_cmp"
15456   [(set (reg:CC FLAGS_REG)
15457         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15458    (clobber (match_scratch:HI 0 "=Q"))]
15459   "! TARGET_POPCNT"
15460   "xor{b}\t{%h0, %b0|%b0, %h0}"
15461   [(set_attr "length" "2")
15462    (set_attr "mode" "HI")])
15463
15464 (define_insn "*parityqi2_cmp"
15465   [(set (reg:CC FLAGS_REG)
15466         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15467   "! TARGET_POPCNT"
15468   "test{b}\t%0, %0"
15469   [(set_attr "length" "2")
15470    (set_attr "mode" "QI")])
15471 \f
15472 ;; Thread-local storage patterns for ELF.
15473 ;;
15474 ;; Note that these code sequences must appear exactly as shown
15475 ;; in order to allow linker relaxation.
15476
15477 (define_insn "*tls_global_dynamic_32_gnu"
15478   [(set (match_operand:SI 0 "register_operand" "=a")
15479         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15480                     (match_operand:SI 2 "tls_symbolic_operand" "")
15481                     (match_operand:SI 3 "call_insn_operand" "")]
15482                     UNSPEC_TLS_GD))
15483    (clobber (match_scratch:SI 4 "=d"))
15484    (clobber (match_scratch:SI 5 "=c"))
15485    (clobber (reg:CC FLAGS_REG))]
15486   "!TARGET_64BIT && TARGET_GNU_TLS"
15487   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15488   [(set_attr "type" "multi")
15489    (set_attr "length" "12")])
15490
15491 (define_insn "*tls_global_dynamic_32_sun"
15492   [(set (match_operand:SI 0 "register_operand" "=a")
15493         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15494                     (match_operand:SI 2 "tls_symbolic_operand" "")
15495                     (match_operand:SI 3 "call_insn_operand" "")]
15496                     UNSPEC_TLS_GD))
15497    (clobber (match_scratch:SI 4 "=d"))
15498    (clobber (match_scratch:SI 5 "=c"))
15499    (clobber (reg:CC FLAGS_REG))]
15500   "!TARGET_64BIT && TARGET_SUN_TLS"
15501   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15502         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15503   [(set_attr "type" "multi")
15504    (set_attr "length" "14")])
15505
15506 (define_expand "tls_global_dynamic_32"
15507   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15508                    (unspec:SI
15509                     [(match_dup 2)
15510                      (match_operand:SI 1 "tls_symbolic_operand" "")
15511                      (match_dup 3)]
15512                     UNSPEC_TLS_GD))
15513               (clobber (match_scratch:SI 4 ""))
15514               (clobber (match_scratch:SI 5 ""))
15515               (clobber (reg:CC FLAGS_REG))])]
15516   ""
15517 {
15518   if (flag_pic)
15519     operands[2] = pic_offset_table_rtx;
15520   else
15521     {
15522       operands[2] = gen_reg_rtx (Pmode);
15523       emit_insn (gen_set_got (operands[2]));
15524     }
15525   if (TARGET_GNU2_TLS)
15526     {
15527        emit_insn (gen_tls_dynamic_gnu2_32
15528                   (operands[0], operands[1], operands[2]));
15529        DONE;
15530     }
15531   operands[3] = ix86_tls_get_addr ();
15532 })
15533
15534 (define_insn "*tls_global_dynamic_64"
15535   [(set (match_operand:DI 0 "register_operand" "=a")
15536         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15537                  (match_operand:DI 3 "" "")))
15538    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15539               UNSPEC_TLS_GD)]
15540   "TARGET_64BIT"
15541   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15542   [(set_attr "type" "multi")
15543    (set_attr "length" "16")])
15544
15545 (define_expand "tls_global_dynamic_64"
15546   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15547                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15548               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15549                          UNSPEC_TLS_GD)])]
15550   ""
15551 {
15552   if (TARGET_GNU2_TLS)
15553     {
15554        emit_insn (gen_tls_dynamic_gnu2_64
15555                   (operands[0], operands[1]));
15556        DONE;
15557     }
15558   operands[2] = ix86_tls_get_addr ();
15559 })
15560
15561 (define_insn "*tls_local_dynamic_base_32_gnu"
15562   [(set (match_operand:SI 0 "register_operand" "=a")
15563         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15564                     (match_operand:SI 2 "call_insn_operand" "")]
15565                    UNSPEC_TLS_LD_BASE))
15566    (clobber (match_scratch:SI 3 "=d"))
15567    (clobber (match_scratch:SI 4 "=c"))
15568    (clobber (reg:CC FLAGS_REG))]
15569   "!TARGET_64BIT && TARGET_GNU_TLS"
15570   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15571   [(set_attr "type" "multi")
15572    (set_attr "length" "11")])
15573
15574 (define_insn "*tls_local_dynamic_base_32_sun"
15575   [(set (match_operand:SI 0 "register_operand" "=a")
15576         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15577                     (match_operand:SI 2 "call_insn_operand" "")]
15578                    UNSPEC_TLS_LD_BASE))
15579    (clobber (match_scratch:SI 3 "=d"))
15580    (clobber (match_scratch:SI 4 "=c"))
15581    (clobber (reg:CC FLAGS_REG))]
15582   "!TARGET_64BIT && TARGET_SUN_TLS"
15583   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15584         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15585   [(set_attr "type" "multi")
15586    (set_attr "length" "13")])
15587
15588 (define_expand "tls_local_dynamic_base_32"
15589   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15590                    (unspec:SI [(match_dup 1) (match_dup 2)]
15591                               UNSPEC_TLS_LD_BASE))
15592               (clobber (match_scratch:SI 3 ""))
15593               (clobber (match_scratch:SI 4 ""))
15594               (clobber (reg:CC FLAGS_REG))])]
15595   ""
15596 {
15597   if (flag_pic)
15598     operands[1] = pic_offset_table_rtx;
15599   else
15600     {
15601       operands[1] = gen_reg_rtx (Pmode);
15602       emit_insn (gen_set_got (operands[1]));
15603     }
15604   if (TARGET_GNU2_TLS)
15605     {
15606        emit_insn (gen_tls_dynamic_gnu2_32
15607                   (operands[0], ix86_tls_module_base (), operands[1]));
15608        DONE;
15609     }
15610   operands[2] = ix86_tls_get_addr ();
15611 })
15612
15613 (define_insn "*tls_local_dynamic_base_64"
15614   [(set (match_operand:DI 0 "register_operand" "=a")
15615         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15616                  (match_operand:DI 2 "" "")))
15617    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15618   "TARGET_64BIT"
15619   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15620   [(set_attr "type" "multi")
15621    (set_attr "length" "12")])
15622
15623 (define_expand "tls_local_dynamic_base_64"
15624   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15625                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15626               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15627   ""
15628 {
15629   if (TARGET_GNU2_TLS)
15630     {
15631        emit_insn (gen_tls_dynamic_gnu2_64
15632                   (operands[0], ix86_tls_module_base ()));
15633        DONE;
15634     }
15635   operands[1] = ix86_tls_get_addr ();
15636 })
15637
15638 ;; Local dynamic of a single variable is a lose.  Show combine how
15639 ;; to convert that back to global dynamic.
15640
15641 (define_insn_and_split "*tls_local_dynamic_32_once"
15642   [(set (match_operand:SI 0 "register_operand" "=a")
15643         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15644                              (match_operand:SI 2 "call_insn_operand" "")]
15645                             UNSPEC_TLS_LD_BASE)
15646                  (const:SI (unspec:SI
15647                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15648                             UNSPEC_DTPOFF))))
15649    (clobber (match_scratch:SI 4 "=d"))
15650    (clobber (match_scratch:SI 5 "=c"))
15651    (clobber (reg:CC FLAGS_REG))]
15652   ""
15653   "#"
15654   ""
15655   [(parallel [(set (match_dup 0)
15656                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15657                               UNSPEC_TLS_GD))
15658               (clobber (match_dup 4))
15659               (clobber (match_dup 5))
15660               (clobber (reg:CC FLAGS_REG))])]
15661   "")
15662
15663 ;; Load and add the thread base pointer from %gs:0.
15664
15665 (define_insn "*load_tp_si"
15666   [(set (match_operand:SI 0 "register_operand" "=r")
15667         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15668   "!TARGET_64BIT"
15669   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15670   [(set_attr "type" "imov")
15671    (set_attr "modrm" "0")
15672    (set_attr "length" "7")
15673    (set_attr "memory" "load")
15674    (set_attr "imm_disp" "false")])
15675
15676 (define_insn "*add_tp_si"
15677   [(set (match_operand:SI 0 "register_operand" "=r")
15678         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15679                  (match_operand:SI 1 "register_operand" "0")))
15680    (clobber (reg:CC FLAGS_REG))]
15681   "!TARGET_64BIT"
15682   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15683   [(set_attr "type" "alu")
15684    (set_attr "modrm" "0")
15685    (set_attr "length" "7")
15686    (set_attr "memory" "load")
15687    (set_attr "imm_disp" "false")])
15688
15689 (define_insn "*load_tp_di"
15690   [(set (match_operand:DI 0 "register_operand" "=r")
15691         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15692   "TARGET_64BIT"
15693   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15694   [(set_attr "type" "imov")
15695    (set_attr "modrm" "0")
15696    (set_attr "length" "7")
15697    (set_attr "memory" "load")
15698    (set_attr "imm_disp" "false")])
15699
15700 (define_insn "*add_tp_di"
15701   [(set (match_operand:DI 0 "register_operand" "=r")
15702         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15703                  (match_operand:DI 1 "register_operand" "0")))
15704    (clobber (reg:CC FLAGS_REG))]
15705   "TARGET_64BIT"
15706   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15707   [(set_attr "type" "alu")
15708    (set_attr "modrm" "0")
15709    (set_attr "length" "7")
15710    (set_attr "memory" "load")
15711    (set_attr "imm_disp" "false")])
15712
15713 ;; GNU2 TLS patterns can be split.
15714
15715 (define_expand "tls_dynamic_gnu2_32"
15716   [(set (match_dup 3)
15717         (plus:SI (match_operand:SI 2 "register_operand" "")
15718                  (const:SI
15719                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15720                              UNSPEC_TLSDESC))))
15721    (parallel
15722     [(set (match_operand:SI 0 "register_operand" "")
15723           (unspec:SI [(match_dup 1) (match_dup 3)
15724                       (match_dup 2) (reg:SI SP_REG)]
15725                       UNSPEC_TLSDESC))
15726      (clobber (reg:CC FLAGS_REG))])]
15727   "!TARGET_64BIT && TARGET_GNU2_TLS"
15728 {
15729   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15730   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15731 })
15732
15733 (define_insn "*tls_dynamic_lea_32"
15734   [(set (match_operand:SI 0 "register_operand" "=r")
15735         (plus:SI (match_operand:SI 1 "register_operand" "b")
15736                  (const:SI
15737                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15738                               UNSPEC_TLSDESC))))]
15739   "!TARGET_64BIT && TARGET_GNU2_TLS"
15740   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15741   [(set_attr "type" "lea")
15742    (set_attr "mode" "SI")
15743    (set_attr "length" "6")
15744    (set_attr "length_address" "4")])
15745
15746 (define_insn "*tls_dynamic_call_32"
15747   [(set (match_operand:SI 0 "register_operand" "=a")
15748         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15749                     (match_operand:SI 2 "register_operand" "0")
15750                     ;; we have to make sure %ebx still points to the GOT
15751                     (match_operand:SI 3 "register_operand" "b")
15752                     (reg:SI SP_REG)]
15753                    UNSPEC_TLSDESC))
15754    (clobber (reg:CC FLAGS_REG))]
15755   "!TARGET_64BIT && TARGET_GNU2_TLS"
15756   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15757   [(set_attr "type" "call")
15758    (set_attr "length" "2")
15759    (set_attr "length_address" "0")])
15760
15761 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15762   [(set (match_operand:SI 0 "register_operand" "=&a")
15763         (plus:SI
15764          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15765                      (match_operand:SI 4 "" "")
15766                      (match_operand:SI 2 "register_operand" "b")
15767                      (reg:SI SP_REG)]
15768                     UNSPEC_TLSDESC)
15769          (const:SI (unspec:SI
15770                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15771                     UNSPEC_DTPOFF))))
15772    (clobber (reg:CC FLAGS_REG))]
15773   "!TARGET_64BIT && TARGET_GNU2_TLS"
15774   "#"
15775   ""
15776   [(set (match_dup 0) (match_dup 5))]
15777 {
15778   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15779   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15780 })
15781
15782 (define_expand "tls_dynamic_gnu2_64"
15783   [(set (match_dup 2)
15784         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15785                    UNSPEC_TLSDESC))
15786    (parallel
15787     [(set (match_operand:DI 0 "register_operand" "")
15788           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15789                      UNSPEC_TLSDESC))
15790      (clobber (reg:CC FLAGS_REG))])]
15791   "TARGET_64BIT && TARGET_GNU2_TLS"
15792 {
15793   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15794   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15795 })
15796
15797 (define_insn "*tls_dynamic_lea_64"
15798   [(set (match_operand:DI 0 "register_operand" "=r")
15799         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15800                    UNSPEC_TLSDESC))]
15801   "TARGET_64BIT && TARGET_GNU2_TLS"
15802   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15803   [(set_attr "type" "lea")
15804    (set_attr "mode" "DI")
15805    (set_attr "length" "7")
15806    (set_attr "length_address" "4")])
15807
15808 (define_insn "*tls_dynamic_call_64"
15809   [(set (match_operand:DI 0 "register_operand" "=a")
15810         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15811                     (match_operand:DI 2 "register_operand" "0")
15812                     (reg:DI SP_REG)]
15813                    UNSPEC_TLSDESC))
15814    (clobber (reg:CC FLAGS_REG))]
15815   "TARGET_64BIT && TARGET_GNU2_TLS"
15816   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15817   [(set_attr "type" "call")
15818    (set_attr "length" "2")
15819    (set_attr "length_address" "0")])
15820
15821 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15822   [(set (match_operand:DI 0 "register_operand" "=&a")
15823         (plus:DI
15824          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15825                      (match_operand:DI 3 "" "")
15826                      (reg:DI SP_REG)]
15827                     UNSPEC_TLSDESC)
15828          (const:DI (unspec:DI
15829                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15830                     UNSPEC_DTPOFF))))
15831    (clobber (reg:CC FLAGS_REG))]
15832   "TARGET_64BIT && TARGET_GNU2_TLS"
15833   "#"
15834   ""
15835   [(set (match_dup 0) (match_dup 4))]
15836 {
15837   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15838   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15839 })
15840
15841 ;;
15842 \f
15843 ;; These patterns match the binary 387 instructions for addM3, subM3,
15844 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15845 ;; SFmode.  The first is the normal insn, the second the same insn but
15846 ;; with one operand a conversion, and the third the same insn but with
15847 ;; the other operand a conversion.  The conversion may be SFmode or
15848 ;; SImode if the target mode DFmode, but only SImode if the target mode
15849 ;; is SFmode.
15850
15851 ;; Gcc is slightly more smart about handling normal two address instructions
15852 ;; so use special patterns for add and mull.
15853
15854 (define_insn "*fop_sf_comm_mixed"
15855   [(set (match_operand:SF 0 "register_operand" "=f,x")
15856         (match_operator:SF 3 "binary_fp_operator"
15857                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15858                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15859   "TARGET_MIX_SSE_I387
15860    && COMMUTATIVE_ARITH_P (operands[3])
15861    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15862   "* return output_387_binary_op (insn, operands);"
15863   [(set (attr "type")
15864         (if_then_else (eq_attr "alternative" "1")
15865            (if_then_else (match_operand:SF 3 "mult_operator" "")
15866               (const_string "ssemul")
15867               (const_string "sseadd"))
15868            (if_then_else (match_operand:SF 3 "mult_operator" "")
15869               (const_string "fmul")
15870               (const_string "fop"))))
15871    (set_attr "mode" "SF")])
15872
15873 (define_insn "*fop_sf_comm_sse"
15874   [(set (match_operand:SF 0 "register_operand" "=x")
15875         (match_operator:SF 3 "binary_fp_operator"
15876                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15877                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15878   "TARGET_SSE_MATH
15879    && COMMUTATIVE_ARITH_P (operands[3])
15880    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15881   "* return output_387_binary_op (insn, operands);"
15882   [(set (attr "type")
15883         (if_then_else (match_operand:SF 3 "mult_operator" "")
15884            (const_string "ssemul")
15885            (const_string "sseadd")))
15886    (set_attr "mode" "SF")])
15887
15888 (define_insn "*fop_sf_comm_i387"
15889   [(set (match_operand:SF 0 "register_operand" "=f")
15890         (match_operator:SF 3 "binary_fp_operator"
15891                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15892                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15893   "TARGET_80387
15894    && COMMUTATIVE_ARITH_P (operands[3])
15895    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15896   "* return output_387_binary_op (insn, operands);"
15897   [(set (attr "type")
15898         (if_then_else (match_operand:SF 3 "mult_operator" "")
15899            (const_string "fmul")
15900            (const_string "fop")))
15901    (set_attr "mode" "SF")])
15902
15903 (define_insn "*fop_sf_1_mixed"
15904   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15905         (match_operator:SF 3 "binary_fp_operator"
15906                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15907                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15908   "TARGET_MIX_SSE_I387
15909    && !COMMUTATIVE_ARITH_P (operands[3])
15910    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15911   "* return output_387_binary_op (insn, operands);"
15912   [(set (attr "type")
15913         (cond [(and (eq_attr "alternative" "2")
15914                     (match_operand:SF 3 "mult_operator" ""))
15915                  (const_string "ssemul")
15916                (and (eq_attr "alternative" "2")
15917                     (match_operand:SF 3 "div_operator" ""))
15918                  (const_string "ssediv")
15919                (eq_attr "alternative" "2")
15920                  (const_string "sseadd")
15921                (match_operand:SF 3 "mult_operator" "")
15922                  (const_string "fmul")
15923                (match_operand:SF 3 "div_operator" "")
15924                  (const_string "fdiv")
15925               ]
15926               (const_string "fop")))
15927    (set_attr "mode" "SF")])
15928
15929 (define_insn "*rcpsf2_sse"
15930   [(set (match_operand:SF 0 "register_operand" "=x")
15931         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15932                    UNSPEC_RCP))]
15933   "TARGET_SSE_MATH"
15934   "rcpss\t{%1, %0|%0, %1}"
15935   [(set_attr "type" "sse")
15936    (set_attr "mode" "SF")])
15937
15938 (define_insn "*fop_sf_1_sse"
15939   [(set (match_operand:SF 0 "register_operand" "=x")
15940         (match_operator:SF 3 "binary_fp_operator"
15941                         [(match_operand:SF 1 "register_operand" "0")
15942                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15943   "TARGET_SSE_MATH
15944    && !COMMUTATIVE_ARITH_P (operands[3])"
15945   "* return output_387_binary_op (insn, operands);"
15946   [(set (attr "type")
15947         (cond [(match_operand:SF 3 "mult_operator" "")
15948                  (const_string "ssemul")
15949                (match_operand:SF 3 "div_operator" "")
15950                  (const_string "ssediv")
15951               ]
15952               (const_string "sseadd")))
15953    (set_attr "mode" "SF")])
15954
15955 ;; This pattern is not fully shadowed by the pattern above.
15956 (define_insn "*fop_sf_1_i387"
15957   [(set (match_operand:SF 0 "register_operand" "=f,f")
15958         (match_operator:SF 3 "binary_fp_operator"
15959                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15960                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15961   "TARGET_80387 && !TARGET_SSE_MATH
15962    && !COMMUTATIVE_ARITH_P (operands[3])
15963    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15964   "* return output_387_binary_op (insn, operands);"
15965   [(set (attr "type")
15966         (cond [(match_operand:SF 3 "mult_operator" "")
15967                  (const_string "fmul")
15968                (match_operand:SF 3 "div_operator" "")
15969                  (const_string "fdiv")
15970               ]
15971               (const_string "fop")))
15972    (set_attr "mode" "SF")])
15973
15974 ;; ??? Add SSE splitters for these!
15975 (define_insn "*fop_sf_2<mode>_i387"
15976   [(set (match_operand:SF 0 "register_operand" "=f,f")
15977         (match_operator:SF 3 "binary_fp_operator"
15978           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15979            (match_operand:SF 2 "register_operand" "0,0")]))]
15980   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15981   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15982   [(set (attr "type")
15983         (cond [(match_operand:SF 3 "mult_operator" "")
15984                  (const_string "fmul")
15985                (match_operand:SF 3 "div_operator" "")
15986                  (const_string "fdiv")
15987               ]
15988               (const_string "fop")))
15989    (set_attr "fp_int_src" "true")
15990    (set_attr "mode" "<MODE>")])
15991
15992 (define_insn "*fop_sf_3<mode>_i387"
15993   [(set (match_operand:SF 0 "register_operand" "=f,f")
15994         (match_operator:SF 3 "binary_fp_operator"
15995           [(match_operand:SF 1 "register_operand" "0,0")
15996            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15997   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15998   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15999   [(set (attr "type")
16000         (cond [(match_operand:SF 3 "mult_operator" "")
16001                  (const_string "fmul")
16002                (match_operand:SF 3 "div_operator" "")
16003                  (const_string "fdiv")
16004               ]
16005               (const_string "fop")))
16006    (set_attr "fp_int_src" "true")
16007    (set_attr "mode" "<MODE>")])
16008
16009 (define_insn "*fop_df_comm_mixed"
16010   [(set (match_operand:DF 0 "register_operand" "=f,x")
16011         (match_operator:DF 3 "binary_fp_operator"
16012           [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
16013            (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
16014   "TARGET_SSE2 && TARGET_MIX_SSE_I387
16015    && COMMUTATIVE_ARITH_P (operands[3])
16016    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16017   "* return output_387_binary_op (insn, operands);"
16018   [(set (attr "type")
16019         (if_then_else (eq_attr "alternative" "1")
16020            (if_then_else (match_operand:DF 3 "mult_operator" "")
16021               (const_string "ssemul")
16022               (const_string "sseadd"))
16023            (if_then_else (match_operand:DF 3 "mult_operator" "")
16024               (const_string "fmul")
16025               (const_string "fop"))))
16026    (set_attr "mode" "DF")])
16027
16028 (define_insn "*fop_df_comm_sse"
16029   [(set (match_operand:DF 0 "register_operand" "=x")
16030         (match_operator:DF 3 "binary_fp_operator"
16031           [(match_operand:DF 1 "nonimmediate_operand" "%0")
16032            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16033   "TARGET_SSE2 && TARGET_SSE_MATH
16034    && COMMUTATIVE_ARITH_P (operands[3])
16035    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16036   "* return output_387_binary_op (insn, operands);"
16037   [(set (attr "type")
16038         (if_then_else (match_operand:DF 3 "mult_operator" "")
16039            (const_string "ssemul")
16040            (const_string "sseadd")))
16041    (set_attr "mode" "DF")])
16042
16043 (define_insn "*fop_df_comm_i387"
16044   [(set (match_operand:DF 0 "register_operand" "=f")
16045         (match_operator:DF 3 "binary_fp_operator"
16046                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
16047                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
16048   "TARGET_80387
16049    && COMMUTATIVE_ARITH_P (operands[3])
16050    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16051   "* return output_387_binary_op (insn, operands);"
16052   [(set (attr "type")
16053         (if_then_else (match_operand:DF 3 "mult_operator" "")
16054            (const_string "fmul")
16055            (const_string "fop")))
16056    (set_attr "mode" "DF")])
16057
16058 (define_insn "*fop_df_1_mixed"
16059   [(set (match_operand:DF 0 "register_operand" "=f,f,x")
16060         (match_operator:DF 3 "binary_fp_operator"
16061           [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
16062            (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
16063   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
16064    && !COMMUTATIVE_ARITH_P (operands[3])
16065    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16066   "* return output_387_binary_op (insn, operands);"
16067   [(set (attr "type")
16068         (cond [(and (eq_attr "alternative" "2")
16069                     (match_operand:DF 3 "mult_operator" ""))
16070                  (const_string "ssemul")
16071                (and (eq_attr "alternative" "2")
16072                     (match_operand:DF 3 "div_operator" ""))
16073                  (const_string "ssediv")
16074                (eq_attr "alternative" "2")
16075                  (const_string "sseadd")
16076                (match_operand:DF 3 "mult_operator" "")
16077                  (const_string "fmul")
16078                (match_operand:DF 3 "div_operator" "")
16079                  (const_string "fdiv")
16080               ]
16081               (const_string "fop")))
16082    (set_attr "mode" "DF")])
16083
16084 (define_insn "*fop_df_1_sse"
16085   [(set (match_operand:DF 0 "register_operand" "=x")
16086         (match_operator:DF 3 "binary_fp_operator"
16087           [(match_operand:DF 1 "register_operand" "0")
16088            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16089   "TARGET_SSE2 && TARGET_SSE_MATH
16090    && !COMMUTATIVE_ARITH_P (operands[3])"
16091   "* return output_387_binary_op (insn, operands);"
16092   [(set_attr "mode" "DF")
16093    (set (attr "type")
16094         (cond [(match_operand:DF 3 "mult_operator" "")
16095                  (const_string "ssemul")
16096                (match_operand:DF 3 "div_operator" "")
16097                  (const_string "ssediv")
16098               ]
16099               (const_string "sseadd")))])
16100
16101 ;; This pattern is not fully shadowed by the pattern above.
16102 (define_insn "*fop_df_1_i387"
16103   [(set (match_operand:DF 0 "register_operand" "=f,f")
16104         (match_operator:DF 3 "binary_fp_operator"
16105                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
16106                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
16107   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16108    && !COMMUTATIVE_ARITH_P (operands[3])
16109    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16110   "* return output_387_binary_op (insn, operands);"
16111   [(set (attr "type")
16112         (cond [(match_operand:DF 3 "mult_operator" "")
16113                  (const_string "fmul")
16114                (match_operand:DF 3 "div_operator" "")
16115                  (const_string "fdiv")
16116               ]
16117               (const_string "fop")))
16118    (set_attr "mode" "DF")])
16119
16120 ;; ??? Add SSE splitters for these!
16121 (define_insn "*fop_df_2<mode>_i387"
16122   [(set (match_operand:DF 0 "register_operand" "=f,f")
16123         (match_operator:DF 3 "binary_fp_operator"
16124            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16125             (match_operand:DF 2 "register_operand" "0,0")]))]
16126   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16127    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16128   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16129   [(set (attr "type")
16130         (cond [(match_operand:DF 3 "mult_operator" "")
16131                  (const_string "fmul")
16132                (match_operand:DF 3 "div_operator" "")
16133                  (const_string "fdiv")
16134               ]
16135               (const_string "fop")))
16136    (set_attr "fp_int_src" "true")
16137    (set_attr "mode" "<MODE>")])
16138
16139 (define_insn "*fop_df_3<mode>_i387"
16140   [(set (match_operand:DF 0 "register_operand" "=f,f")
16141         (match_operator:DF 3 "binary_fp_operator"
16142            [(match_operand:DF 1 "register_operand" "0,0")
16143             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16144   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16145    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16146   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16147   [(set (attr "type")
16148         (cond [(match_operand:DF 3 "mult_operator" "")
16149                  (const_string "fmul")
16150                (match_operand:DF 3 "div_operator" "")
16151                  (const_string "fdiv")
16152               ]
16153               (const_string "fop")))
16154    (set_attr "fp_int_src" "true")
16155    (set_attr "mode" "<MODE>")])
16156
16157 (define_insn "*fop_df_4_i387"
16158   [(set (match_operand:DF 0 "register_operand" "=f,f")
16159         (match_operator:DF 3 "binary_fp_operator"
16160            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16161             (match_operand:DF 2 "register_operand" "0,f")]))]
16162   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16163    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16164   "* return output_387_binary_op (insn, operands);"
16165   [(set (attr "type")
16166         (cond [(match_operand:DF 3 "mult_operator" "")
16167                  (const_string "fmul")
16168                (match_operand:DF 3 "div_operator" "")
16169                  (const_string "fdiv")
16170               ]
16171               (const_string "fop")))
16172    (set_attr "mode" "SF")])
16173
16174 (define_insn "*fop_df_5_i387"
16175   [(set (match_operand:DF 0 "register_operand" "=f,f")
16176         (match_operator:DF 3 "binary_fp_operator"
16177           [(match_operand:DF 1 "register_operand" "0,f")
16178            (float_extend:DF
16179             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16180   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16181   "* return output_387_binary_op (insn, operands);"
16182   [(set (attr "type")
16183         (cond [(match_operand:DF 3 "mult_operator" "")
16184                  (const_string "fmul")
16185                (match_operand:DF 3 "div_operator" "")
16186                  (const_string "fdiv")
16187               ]
16188               (const_string "fop")))
16189    (set_attr "mode" "SF")])
16190
16191 (define_insn "*fop_df_6_i387"
16192   [(set (match_operand:DF 0 "register_operand" "=f,f")
16193         (match_operator:DF 3 "binary_fp_operator"
16194           [(float_extend:DF
16195             (match_operand:SF 1 "register_operand" "0,f"))
16196            (float_extend:DF
16197             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16198   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16199   "* return output_387_binary_op (insn, operands);"
16200   [(set (attr "type")
16201         (cond [(match_operand:DF 3 "mult_operator" "")
16202                  (const_string "fmul")
16203                (match_operand:DF 3 "div_operator" "")
16204                  (const_string "fdiv")
16205               ]
16206               (const_string "fop")))
16207    (set_attr "mode" "SF")])
16208
16209 (define_insn "*fop_xf_comm_i387"
16210   [(set (match_operand:XF 0 "register_operand" "=f")
16211         (match_operator:XF 3 "binary_fp_operator"
16212                         [(match_operand:XF 1 "register_operand" "%0")
16213                          (match_operand:XF 2 "register_operand" "f")]))]
16214   "TARGET_80387
16215    && COMMUTATIVE_ARITH_P (operands[3])"
16216   "* return output_387_binary_op (insn, operands);"
16217   [(set (attr "type")
16218         (if_then_else (match_operand:XF 3 "mult_operator" "")
16219            (const_string "fmul")
16220            (const_string "fop")))
16221    (set_attr "mode" "XF")])
16222
16223 (define_insn "*fop_xf_1_i387"
16224   [(set (match_operand:XF 0 "register_operand" "=f,f")
16225         (match_operator:XF 3 "binary_fp_operator"
16226                         [(match_operand:XF 1 "register_operand" "0,f")
16227                          (match_operand:XF 2 "register_operand" "f,0")]))]
16228   "TARGET_80387
16229    && !COMMUTATIVE_ARITH_P (operands[3])"
16230   "* return output_387_binary_op (insn, operands);"
16231   [(set (attr "type")
16232         (cond [(match_operand:XF 3 "mult_operator" "")
16233                  (const_string "fmul")
16234                (match_operand:XF 3 "div_operator" "")
16235                  (const_string "fdiv")
16236               ]
16237               (const_string "fop")))
16238    (set_attr "mode" "XF")])
16239
16240 (define_insn "*fop_xf_2<mode>_i387"
16241   [(set (match_operand:XF 0 "register_operand" "=f,f")
16242         (match_operator:XF 3 "binary_fp_operator"
16243            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16244             (match_operand:XF 2 "register_operand" "0,0")]))]
16245   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16246   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16247   [(set (attr "type")
16248         (cond [(match_operand:XF 3 "mult_operator" "")
16249                  (const_string "fmul")
16250                (match_operand:XF 3 "div_operator" "")
16251                  (const_string "fdiv")
16252               ]
16253               (const_string "fop")))
16254    (set_attr "fp_int_src" "true")
16255    (set_attr "mode" "<MODE>")])
16256
16257 (define_insn "*fop_xf_3<mode>_i387"
16258   [(set (match_operand:XF 0 "register_operand" "=f,f")
16259         (match_operator:XF 3 "binary_fp_operator"
16260           [(match_operand:XF 1 "register_operand" "0,0")
16261            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16262   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16263   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16264   [(set (attr "type")
16265         (cond [(match_operand:XF 3 "mult_operator" "")
16266                  (const_string "fmul")
16267                (match_operand:XF 3 "div_operator" "")
16268                  (const_string "fdiv")
16269               ]
16270               (const_string "fop")))
16271    (set_attr "fp_int_src" "true")
16272    (set_attr "mode" "<MODE>")])
16273
16274 (define_insn "*fop_xf_4_i387"
16275   [(set (match_operand:XF 0 "register_operand" "=f,f")
16276         (match_operator:XF 3 "binary_fp_operator"
16277            [(float_extend:XF
16278               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16279             (match_operand:XF 2 "register_operand" "0,f")]))]
16280   "TARGET_80387"
16281   "* return output_387_binary_op (insn, operands);"
16282   [(set (attr "type")
16283         (cond [(match_operand:XF 3 "mult_operator" "")
16284                  (const_string "fmul")
16285                (match_operand:XF 3 "div_operator" "")
16286                  (const_string "fdiv")
16287               ]
16288               (const_string "fop")))
16289    (set_attr "mode" "SF")])
16290
16291 (define_insn "*fop_xf_5_i387"
16292   [(set (match_operand:XF 0 "register_operand" "=f,f")
16293         (match_operator:XF 3 "binary_fp_operator"
16294           [(match_operand:XF 1 "register_operand" "0,f")
16295            (float_extend:XF
16296              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16297   "TARGET_80387"
16298   "* return output_387_binary_op (insn, operands);"
16299   [(set (attr "type")
16300         (cond [(match_operand:XF 3 "mult_operator" "")
16301                  (const_string "fmul")
16302                (match_operand:XF 3 "div_operator" "")
16303                  (const_string "fdiv")
16304               ]
16305               (const_string "fop")))
16306    (set_attr "mode" "SF")])
16307
16308 (define_insn "*fop_xf_6_i387"
16309   [(set (match_operand:XF 0 "register_operand" "=f,f")
16310         (match_operator:XF 3 "binary_fp_operator"
16311           [(float_extend:XF
16312              (match_operand:MODEF 1 "register_operand" "0,f"))
16313            (float_extend:XF
16314              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16315   "TARGET_80387"
16316   "* return output_387_binary_op (insn, operands);"
16317   [(set (attr "type")
16318         (cond [(match_operand:XF 3 "mult_operator" "")
16319                  (const_string "fmul")
16320                (match_operand:XF 3 "div_operator" "")
16321                  (const_string "fdiv")
16322               ]
16323               (const_string "fop")))
16324    (set_attr "mode" "SF")])
16325
16326 (define_split
16327   [(set (match_operand 0 "register_operand" "")
16328         (match_operator 3 "binary_fp_operator"
16329            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16330             (match_operand 2 "register_operand" "")]))]
16331   "reload_completed
16332    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16333   [(const_int 0)]
16334 {
16335   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16336   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16337   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16338                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16339                                           GET_MODE (operands[3]),
16340                                           operands[4],
16341                                           operands[2])));
16342   ix86_free_from_memory (GET_MODE (operands[1]));
16343   DONE;
16344 })
16345
16346 (define_split
16347   [(set (match_operand 0 "register_operand" "")
16348         (match_operator 3 "binary_fp_operator"
16349            [(match_operand 1 "register_operand" "")
16350             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16351   "reload_completed
16352    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16353   [(const_int 0)]
16354 {
16355   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16356   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16357   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16358                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16359                                           GET_MODE (operands[3]),
16360                                           operands[1],
16361                                           operands[4])));
16362   ix86_free_from_memory (GET_MODE (operands[2]));
16363   DONE;
16364 })
16365 \f
16366 ;; FPU special functions.
16367
16368 ;; This pattern implements a no-op XFmode truncation for
16369 ;; all fancy i386 XFmode math functions.
16370
16371 (define_insn "truncxf<mode>2_i387_noop_unspec"
16372   [(set (match_operand:MODEF 0 "register_operand" "=f")
16373         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16374         UNSPEC_TRUNC_NOOP))]
16375   "TARGET_USE_FANCY_MATH_387"
16376   "* return output_387_reg_move (insn, operands);"
16377   [(set_attr "type" "fmov")
16378    (set_attr "mode" "<MODE>")])
16379
16380 (define_insn "sqrtxf2"
16381   [(set (match_operand:XF 0 "register_operand" "=f")
16382         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16383   "TARGET_USE_FANCY_MATH_387"
16384   "fsqrt"
16385   [(set_attr "type" "fpspc")
16386    (set_attr "mode" "XF")
16387    (set_attr "athlon_decode" "direct")
16388    (set_attr "amdfam10_decode" "direct")])
16389
16390 (define_insn "sqrt_extend<mode>xf2_i387"
16391   [(set (match_operand:XF 0 "register_operand" "=f")
16392         (sqrt:XF
16393           (float_extend:XF
16394             (match_operand:MODEF 1 "register_operand" "0"))))]
16395   "TARGET_USE_FANCY_MATH_387"
16396   "fsqrt"
16397   [(set_attr "type" "fpspc")
16398    (set_attr "mode" "XF")
16399    (set_attr "athlon_decode" "direct")
16400    (set_attr "amdfam10_decode" "direct")])
16401
16402 (define_insn "*rsqrtsf2_sse"
16403   [(set (match_operand:SF 0 "register_operand" "=x")
16404         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16405                    UNSPEC_RSQRT))]
16406   "TARGET_SSE_MATH"
16407   "rsqrtss\t{%1, %0|%0, %1}"
16408   [(set_attr "type" "sse")
16409    (set_attr "mode" "SF")])
16410
16411 (define_expand "rsqrtsf2"
16412   [(set (match_operand:SF 0 "register_operand" "")
16413         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16414                    UNSPEC_RSQRT))]
16415   "TARGET_SSE_MATH"
16416 {
16417   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16418   DONE;
16419 })
16420
16421 (define_insn "*sqrt<mode>2_sse"
16422   [(set (match_operand:MODEF 0 "register_operand" "=x")
16423         (sqrt:MODEF
16424           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16425   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16426   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16427   [(set_attr "type" "sse")
16428    (set_attr "mode" "<MODE>")
16429    (set_attr "athlon_decode" "*")
16430    (set_attr "amdfam10_decode" "*")])
16431
16432 (define_expand "sqrt<mode>2"
16433   [(set (match_operand:MODEF 0 "register_operand" "")
16434         (sqrt:MODEF
16435           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16436   "TARGET_USE_FANCY_MATH_387
16437    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16438 {
16439   if (<MODE>mode == SFmode
16440       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16441       && flag_finite_math_only && !flag_trapping_math
16442       && flag_unsafe_math_optimizations)
16443     {
16444       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16445       DONE;
16446     }
16447
16448   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16449     {
16450       rtx op0 = gen_reg_rtx (XFmode);
16451       rtx op1 = force_reg (<MODE>mode, operands[1]);
16452
16453       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16454       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16455       DONE;
16456    }
16457 })
16458
16459 (define_insn "fpremxf4_i387"
16460   [(set (match_operand:XF 0 "register_operand" "=f")
16461         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16462                     (match_operand:XF 3 "register_operand" "1")]
16463                    UNSPEC_FPREM_F))
16464    (set (match_operand:XF 1 "register_operand" "=u")
16465         (unspec:XF [(match_dup 2) (match_dup 3)]
16466                    UNSPEC_FPREM_U))
16467    (set (reg:CCFP FPSR_REG)
16468         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16469                      UNSPEC_C2_FLAG))]
16470   "TARGET_USE_FANCY_MATH_387"
16471   "fprem"
16472   [(set_attr "type" "fpspc")
16473    (set_attr "mode" "XF")])
16474
16475 (define_expand "fmodxf3"
16476   [(use (match_operand:XF 0 "register_operand" ""))
16477    (use (match_operand:XF 1 "register_operand" ""))
16478    (use (match_operand:XF 2 "register_operand" ""))]
16479   "TARGET_USE_FANCY_MATH_387"
16480 {
16481   rtx label = gen_label_rtx ();
16482
16483   rtx op2;
16484
16485   if (rtx_equal_p (operands[1], operands[2]))
16486     {
16487       op2 = gen_reg_rtx (XFmode);
16488       emit_move_insn (op2, operands[2]);
16489     }
16490   else
16491     op2 = operands[2];
16492
16493   emit_label (label);
16494   emit_insn (gen_fpremxf4_i387 (operands[1], op2, operands[1], op2));
16495   ix86_emit_fp_unordered_jump (label);
16496   LABEL_NUSES (label) = 1;
16497
16498   emit_move_insn (operands[0], operands[1]);
16499   DONE;
16500 })
16501
16502 (define_expand "fmod<mode>3"
16503   [(use (match_operand:MODEF 0 "register_operand" ""))
16504    (use (match_operand:MODEF 1 "general_operand" ""))
16505    (use (match_operand:MODEF 2 "general_operand" ""))]
16506   "TARGET_USE_FANCY_MATH_387"
16507 {
16508   rtx label = gen_label_rtx ();
16509
16510   rtx op1 = gen_reg_rtx (XFmode);
16511   rtx op2 = gen_reg_rtx (XFmode);
16512
16513   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16514   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16515
16516   emit_label (label);
16517   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16518   ix86_emit_fp_unordered_jump (label);
16519   LABEL_NUSES (label) = 1;
16520
16521   /* Truncate the result properly for strict SSE math.  */
16522   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16523       && !TARGET_MIX_SSE_I387)
16524     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16525   else
16526     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16527
16528   DONE;
16529 })
16530
16531 (define_insn "fprem1xf4_i387"
16532   [(set (match_operand:XF 0 "register_operand" "=f")
16533         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16534                     (match_operand:XF 3 "register_operand" "1")]
16535                    UNSPEC_FPREM1_F))
16536    (set (match_operand:XF 1 "register_operand" "=u")
16537         (unspec:XF [(match_dup 2) (match_dup 3)]
16538                    UNSPEC_FPREM1_U))
16539    (set (reg:CCFP FPSR_REG)
16540         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16541                      UNSPEC_C2_FLAG))]
16542   "TARGET_USE_FANCY_MATH_387"
16543   "fprem1"
16544   [(set_attr "type" "fpspc")
16545    (set_attr "mode" "XF")])
16546
16547 (define_expand "remainderxf3"
16548   [(use (match_operand:XF 0 "register_operand" ""))
16549    (use (match_operand:XF 1 "register_operand" ""))
16550    (use (match_operand:XF 2 "register_operand" ""))]
16551   "TARGET_USE_FANCY_MATH_387"
16552 {
16553   rtx label = gen_label_rtx ();
16554
16555   rtx op2;
16556
16557   if (rtx_equal_p (operands[1], operands[2]))
16558     {
16559       op2 = gen_reg_rtx (XFmode);
16560       emit_move_insn (op2, operands[2]);
16561     }
16562   else
16563     op2 = operands[2];
16564
16565   emit_label (label);
16566   emit_insn (gen_fprem1xf4_i387 (operands[1], op2, operands[1], op2));
16567   ix86_emit_fp_unordered_jump (label);
16568   LABEL_NUSES (label) = 1;
16569
16570   emit_move_insn (operands[0], operands[1]);
16571   DONE;
16572 })
16573
16574 (define_expand "remainder<mode>3"
16575   [(use (match_operand:MODEF 0 "register_operand" ""))
16576    (use (match_operand:MODEF 1 "general_operand" ""))
16577    (use (match_operand:MODEF 2 "general_operand" ""))]
16578   "TARGET_USE_FANCY_MATH_387"
16579 {
16580   rtx label = gen_label_rtx ();
16581
16582   rtx op1 = gen_reg_rtx (XFmode);
16583   rtx op2 = gen_reg_rtx (XFmode);
16584
16585   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16586   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16587
16588   emit_label (label);
16589
16590   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16591   ix86_emit_fp_unordered_jump (label);
16592   LABEL_NUSES (label) = 1;
16593
16594   /* Truncate the result properly for strict SSE math.  */
16595   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16596       && !TARGET_MIX_SSE_I387)
16597     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16598   else
16599     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16600
16601   DONE;
16602 })
16603
16604 (define_insn "*sinxf2_i387"
16605   [(set (match_operand:XF 0 "register_operand" "=f")
16606         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16607   "TARGET_USE_FANCY_MATH_387
16608    && flag_unsafe_math_optimizations"
16609   "fsin"
16610   [(set_attr "type" "fpspc")
16611    (set_attr "mode" "XF")])
16612
16613 (define_insn "*sin_extend<mode>xf2_i387"
16614   [(set (match_operand:XF 0 "register_operand" "=f")
16615         (unspec:XF [(float_extend:XF
16616                       (match_operand:MODEF 1 "register_operand" "0"))]
16617                    UNSPEC_SIN))]
16618   "TARGET_USE_FANCY_MATH_387
16619    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16620        || TARGET_MIX_SSE_I387)
16621    && flag_unsafe_math_optimizations"
16622   "fsin"
16623   [(set_attr "type" "fpspc")
16624    (set_attr "mode" "XF")])
16625
16626 (define_insn "*cosxf2_i387"
16627   [(set (match_operand:XF 0 "register_operand" "=f")
16628         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16629   "TARGET_USE_FANCY_MATH_387
16630    && flag_unsafe_math_optimizations"
16631   "fcos"
16632   [(set_attr "type" "fpspc")
16633    (set_attr "mode" "XF")])
16634
16635 (define_insn "*cos_extend<mode>xf2_i387"
16636   [(set (match_operand:XF 0 "register_operand" "=f")
16637         (unspec:XF [(float_extend:XF
16638                       (match_operand:MODEF 1 "register_operand" "0"))]
16639                    UNSPEC_COS))]
16640   "TARGET_USE_FANCY_MATH_387
16641    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16642        || TARGET_MIX_SSE_I387)
16643    && flag_unsafe_math_optimizations"
16644   "fcos"
16645   [(set_attr "type" "fpspc")
16646    (set_attr "mode" "XF")])
16647
16648 ;; When sincos pattern is defined, sin and cos builtin functions will be
16649 ;; expanded to sincos pattern with one of its outputs left unused.
16650 ;; CSE pass will figure out if two sincos patterns can be combined,
16651 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16652 ;; depending on the unused output.
16653
16654 (define_insn "sincosxf3"
16655   [(set (match_operand:XF 0 "register_operand" "=f")
16656         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16657                    UNSPEC_SINCOS_COS))
16658    (set (match_operand:XF 1 "register_operand" "=u")
16659         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16660   "TARGET_USE_FANCY_MATH_387
16661    && flag_unsafe_math_optimizations"
16662   "fsincos"
16663   [(set_attr "type" "fpspc")
16664    (set_attr "mode" "XF")])
16665
16666 (define_split
16667   [(set (match_operand:XF 0 "register_operand" "")
16668         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16669                    UNSPEC_SINCOS_COS))
16670    (set (match_operand:XF 1 "register_operand" "")
16671         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16672   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16673    && !(reload_completed || reload_in_progress)"
16674   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16675   "")
16676
16677 (define_split
16678   [(set (match_operand:XF 0 "register_operand" "")
16679         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16680                    UNSPEC_SINCOS_COS))
16681    (set (match_operand:XF 1 "register_operand" "")
16682         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16683   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16684    && !(reload_completed || reload_in_progress)"
16685   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16686   "")
16687
16688 (define_insn "sincos_extend<mode>xf3_i387"
16689   [(set (match_operand:XF 0 "register_operand" "=f")
16690         (unspec:XF [(float_extend:XF
16691                       (match_operand:MODEF 2 "register_operand" "0"))]
16692                    UNSPEC_SINCOS_COS))
16693    (set (match_operand:XF 1 "register_operand" "=u")
16694         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16695   "TARGET_USE_FANCY_MATH_387
16696    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16697        || TARGET_MIX_SSE_I387)
16698    && flag_unsafe_math_optimizations"
16699   "fsincos"
16700   [(set_attr "type" "fpspc")
16701    (set_attr "mode" "XF")])
16702
16703 (define_split
16704   [(set (match_operand:XF 0 "register_operand" "")
16705         (unspec:XF [(float_extend:XF
16706                       (match_operand:MODEF 2 "register_operand" ""))]
16707                    UNSPEC_SINCOS_COS))
16708    (set (match_operand:XF 1 "register_operand" "")
16709         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16710   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16711    && !(reload_completed || reload_in_progress)"
16712   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16713   "")
16714
16715 (define_split
16716   [(set (match_operand:XF 0 "register_operand" "")
16717         (unspec:XF [(float_extend:XF
16718                       (match_operand:MODEF 2 "register_operand" ""))]
16719                    UNSPEC_SINCOS_COS))
16720    (set (match_operand:XF 1 "register_operand" "")
16721         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16722   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16723    && !(reload_completed || reload_in_progress)"
16724   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16725   "")
16726
16727 (define_expand "sincos<mode>3"
16728   [(use (match_operand:MODEF 0 "register_operand" ""))
16729    (use (match_operand:MODEF 1 "register_operand" ""))
16730    (use (match_operand:MODEF 2 "register_operand" ""))]
16731   "TARGET_USE_FANCY_MATH_387
16732    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16733        || TARGET_MIX_SSE_I387)
16734    && flag_unsafe_math_optimizations"
16735 {
16736   rtx op0 = gen_reg_rtx (XFmode);
16737   rtx op1 = gen_reg_rtx (XFmode);
16738
16739   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16740   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16741   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16742   DONE;
16743 })
16744
16745 (define_insn "fptanxf4_i387"
16746   [(set (match_operand:XF 0 "register_operand" "=f")
16747         (match_operand:XF 3 "const_double_operand" "F"))
16748    (set (match_operand:XF 1 "register_operand" "=u")
16749         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16750                    UNSPEC_TAN))]
16751   "TARGET_USE_FANCY_MATH_387
16752    && flag_unsafe_math_optimizations
16753    && standard_80387_constant_p (operands[3]) == 2"
16754   "fptan"
16755   [(set_attr "type" "fpspc")
16756    (set_attr "mode" "XF")])
16757
16758 (define_insn "fptan_extend<mode>xf4_i387"
16759   [(set (match_operand:MODEF 0 "register_operand" "=f")
16760         (match_operand:MODEF 3 "const_double_operand" "F"))
16761    (set (match_operand:XF 1 "register_operand" "=u")
16762         (unspec:XF [(float_extend:XF
16763                       (match_operand:MODEF 2 "register_operand" "0"))]
16764                    UNSPEC_TAN))]
16765   "TARGET_USE_FANCY_MATH_387
16766    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16767        || TARGET_MIX_SSE_I387)
16768    && flag_unsafe_math_optimizations
16769    && standard_80387_constant_p (operands[3]) == 2"
16770   "fptan"
16771   [(set_attr "type" "fpspc")
16772    (set_attr "mode" "XF")])
16773
16774 (define_expand "tanxf2"
16775   [(use (match_operand:XF 0 "register_operand" ""))
16776    (use (match_operand:XF 1 "register_operand" ""))]
16777   "TARGET_USE_FANCY_MATH_387
16778    && flag_unsafe_math_optimizations"
16779 {
16780   rtx one = gen_reg_rtx (XFmode);
16781   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16782
16783   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16784   DONE;
16785 })
16786
16787 (define_expand "tan<mode>2"
16788   [(use (match_operand:MODEF 0 "register_operand" ""))
16789    (use (match_operand:MODEF 1 "register_operand" ""))]
16790   "TARGET_USE_FANCY_MATH_387
16791    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16792        || TARGET_MIX_SSE_I387)
16793    && flag_unsafe_math_optimizations"
16794 {
16795   rtx op0 = gen_reg_rtx (XFmode);
16796
16797   rtx one = gen_reg_rtx (<MODE>mode);
16798   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16799
16800   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16801                                              operands[1], op2));
16802   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16803   DONE;
16804 })
16805
16806 (define_insn "*fpatanxf3_i387"
16807   [(set (match_operand:XF 0 "register_operand" "=f")
16808         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16809                     (match_operand:XF 2 "register_operand" "u")]
16810                    UNSPEC_FPATAN))
16811    (clobber (match_scratch:XF 3 "=2"))]
16812   "TARGET_USE_FANCY_MATH_387
16813    && flag_unsafe_math_optimizations"
16814   "fpatan"
16815   [(set_attr "type" "fpspc")
16816    (set_attr "mode" "XF")])
16817
16818 (define_insn "fpatan_extend<mode>xf3_i387"
16819   [(set (match_operand:XF 0 "register_operand" "=f")
16820         (unspec:XF [(float_extend:XF
16821                       (match_operand:MODEF 1 "register_operand" "0"))
16822                     (float_extend:XF
16823                       (match_operand:MODEF 2 "register_operand" "u"))]
16824                    UNSPEC_FPATAN))
16825    (clobber (match_scratch:XF 3 "=2"))]
16826   "TARGET_USE_FANCY_MATH_387
16827    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16828        || TARGET_MIX_SSE_I387)
16829    && flag_unsafe_math_optimizations"
16830   "fpatan"
16831   [(set_attr "type" "fpspc")
16832    (set_attr "mode" "XF")])
16833
16834 (define_expand "atan2xf3"
16835   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16836                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16837                                (match_operand:XF 1 "register_operand" "")]
16838                               UNSPEC_FPATAN))
16839               (clobber (match_scratch:XF 3 ""))])]
16840   "TARGET_USE_FANCY_MATH_387
16841    && flag_unsafe_math_optimizations"
16842   "")
16843
16844 (define_expand "atan2<mode>3"
16845   [(use (match_operand:MODEF 0 "register_operand" ""))
16846    (use (match_operand:MODEF 1 "register_operand" ""))
16847    (use (match_operand:MODEF 2 "register_operand" ""))]
16848   "TARGET_USE_FANCY_MATH_387
16849    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16850        || TARGET_MIX_SSE_I387)
16851    && flag_unsafe_math_optimizations"
16852 {
16853   rtx op0 = gen_reg_rtx (XFmode);
16854
16855   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16856   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16857   DONE;
16858 })
16859
16860 (define_expand "atanxf2"
16861   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16862                    (unspec:XF [(match_dup 2)
16863                                (match_operand:XF 1 "register_operand" "")]
16864                               UNSPEC_FPATAN))
16865               (clobber (match_scratch:XF 3 ""))])]
16866   "TARGET_USE_FANCY_MATH_387
16867    && flag_unsafe_math_optimizations"
16868 {
16869   operands[2] = gen_reg_rtx (XFmode);
16870   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16871 })
16872
16873 (define_expand "atan<mode>2"
16874   [(use (match_operand:MODEF 0 "register_operand" ""))
16875    (use (match_operand:MODEF 1 "register_operand" ""))]
16876   "TARGET_USE_FANCY_MATH_387
16877    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16878        || TARGET_MIX_SSE_I387)
16879    && flag_unsafe_math_optimizations"
16880 {
16881   rtx op0 = gen_reg_rtx (XFmode);
16882
16883   rtx op2 = gen_reg_rtx (<MODE>mode);
16884   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16885
16886   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16887   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16888   DONE;
16889 })
16890
16891 (define_expand "asinxf2"
16892   [(set (match_dup 2)
16893         (mult:XF (match_operand:XF 1 "register_operand" "")
16894                  (match_dup 1)))
16895    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16896    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16897    (parallel [(set (match_operand:XF 0 "register_operand" "")
16898                    (unspec:XF [(match_dup 5) (match_dup 1)]
16899                               UNSPEC_FPATAN))
16900               (clobber (match_scratch:XF 6 ""))])]
16901   "TARGET_USE_FANCY_MATH_387
16902    && flag_unsafe_math_optimizations && !optimize_size"
16903 {
16904   int i;
16905
16906   for (i = 2; i < 6; i++)
16907     operands[i] = gen_reg_rtx (XFmode);
16908
16909   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16910 })
16911
16912 (define_expand "asin<mode>2"
16913   [(use (match_operand:MODEF 0 "register_operand" ""))
16914    (use (match_operand:MODEF 1 "general_operand" ""))]
16915  "TARGET_USE_FANCY_MATH_387
16916    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16917        || TARGET_MIX_SSE_I387)
16918    && flag_unsafe_math_optimizations && !optimize_size"
16919 {
16920   rtx op0 = gen_reg_rtx (XFmode);
16921   rtx op1 = gen_reg_rtx (XFmode);
16922
16923   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16924   emit_insn (gen_asinxf2 (op0, op1));
16925   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16926   DONE;
16927 })
16928
16929 (define_expand "acosxf2"
16930   [(set (match_dup 2)
16931         (mult:XF (match_operand:XF 1 "register_operand" "")
16932                  (match_dup 1)))
16933    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16934    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16935    (parallel [(set (match_operand:XF 0 "register_operand" "")
16936                    (unspec:XF [(match_dup 1) (match_dup 5)]
16937                               UNSPEC_FPATAN))
16938               (clobber (match_scratch:XF 6 ""))])]
16939   "TARGET_USE_FANCY_MATH_387
16940    && flag_unsafe_math_optimizations && !optimize_size"
16941 {
16942   int i;
16943
16944   for (i = 2; i < 6; i++)
16945     operands[i] = gen_reg_rtx (XFmode);
16946
16947   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16948 })
16949
16950 (define_expand "acos<mode>2"
16951   [(use (match_operand:MODEF 0 "register_operand" ""))
16952    (use (match_operand:MODEF 1 "general_operand" ""))]
16953  "TARGET_USE_FANCY_MATH_387
16954    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16955        || TARGET_MIX_SSE_I387)
16956    && flag_unsafe_math_optimizations && !optimize_size"
16957 {
16958   rtx op0 = gen_reg_rtx (XFmode);
16959   rtx op1 = gen_reg_rtx (XFmode);
16960
16961   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16962   emit_insn (gen_acosxf2 (op0, op1));
16963   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16964   DONE;
16965 })
16966
16967 (define_insn "fyl2xxf3_i387"
16968   [(set (match_operand:XF 0 "register_operand" "=f")
16969         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16970                     (match_operand:XF 2 "register_operand" "u")]
16971                    UNSPEC_FYL2X))
16972    (clobber (match_scratch:XF 3 "=2"))]
16973   "TARGET_USE_FANCY_MATH_387
16974    && flag_unsafe_math_optimizations"
16975   "fyl2x"
16976   [(set_attr "type" "fpspc")
16977    (set_attr "mode" "XF")])
16978
16979 (define_insn "fyl2x_extend<mode>xf3_i387"
16980   [(set (match_operand:XF 0 "register_operand" "=f")
16981         (unspec:XF [(float_extend:XF
16982                       (match_operand:MODEF 1 "register_operand" "0"))
16983                     (match_operand:XF 2 "register_operand" "u")]
16984                    UNSPEC_FYL2X))
16985    (clobber (match_scratch:XF 3 "=2"))]
16986   "TARGET_USE_FANCY_MATH_387
16987    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16988        || TARGET_MIX_SSE_I387)
16989    && flag_unsafe_math_optimizations"
16990   "fyl2x"
16991   [(set_attr "type" "fpspc")
16992    (set_attr "mode" "XF")])
16993
16994 (define_expand "logxf2"
16995   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16996                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16997                                (match_dup 2)] UNSPEC_FYL2X))
16998               (clobber (match_scratch:XF 3 ""))])]
16999   "TARGET_USE_FANCY_MATH_387
17000    && flag_unsafe_math_optimizations"
17001 {
17002   operands[2] = gen_reg_rtx (XFmode);
17003   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17004 })
17005
17006 (define_expand "log<mode>2"
17007   [(use (match_operand:MODEF 0 "register_operand" ""))
17008    (use (match_operand:MODEF 1 "register_operand" ""))]
17009   "TARGET_USE_FANCY_MATH_387
17010    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17011        || TARGET_MIX_SSE_I387)
17012    && flag_unsafe_math_optimizations"
17013 {
17014   rtx op0 = gen_reg_rtx (XFmode);
17015
17016   rtx op2 = gen_reg_rtx (XFmode);
17017   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17018
17019   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17020   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17021   DONE;
17022 })
17023
17024 (define_expand "log10xf2"
17025   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17026                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17027                                (match_dup 2)] UNSPEC_FYL2X))
17028               (clobber (match_scratch:XF 3 ""))])]
17029   "TARGET_USE_FANCY_MATH_387
17030    && flag_unsafe_math_optimizations"
17031 {
17032   operands[2] = gen_reg_rtx (XFmode);
17033   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17034 })
17035
17036 (define_expand "log10<mode>2"
17037   [(use (match_operand:MODEF 0 "register_operand" ""))
17038    (use (match_operand:MODEF 1 "register_operand" ""))]
17039   "TARGET_USE_FANCY_MATH_387
17040    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17041        || TARGET_MIX_SSE_I387)
17042    && flag_unsafe_math_optimizations"
17043 {
17044   rtx op0 = gen_reg_rtx (XFmode);
17045
17046   rtx op2 = gen_reg_rtx (XFmode);
17047   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17048
17049   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17050   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17051   DONE;
17052 })
17053
17054 (define_expand "log2xf2"
17055   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17056                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17057                                (match_dup 2)] UNSPEC_FYL2X))
17058               (clobber (match_scratch:XF 3 ""))])]
17059   "TARGET_USE_FANCY_MATH_387
17060    && flag_unsafe_math_optimizations"
17061 {
17062   operands[2] = gen_reg_rtx (XFmode);
17063   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17064 })
17065
17066 (define_expand "log2<mode>2"
17067   [(use (match_operand:MODEF 0 "register_operand" ""))
17068    (use (match_operand:MODEF 1 "register_operand" ""))]
17069   "TARGET_USE_FANCY_MATH_387
17070    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17071        || TARGET_MIX_SSE_I387)
17072    && flag_unsafe_math_optimizations"
17073 {
17074   rtx op0 = gen_reg_rtx (XFmode);
17075
17076   rtx op2 = gen_reg_rtx (XFmode);
17077   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17078
17079   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17080   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17081   DONE;
17082 })
17083
17084 (define_insn "fyl2xp1xf3_i387"
17085   [(set (match_operand:XF 0 "register_operand" "=f")
17086         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17087                     (match_operand:XF 2 "register_operand" "u")]
17088                    UNSPEC_FYL2XP1))
17089    (clobber (match_scratch:XF 3 "=2"))]
17090   "TARGET_USE_FANCY_MATH_387
17091    && flag_unsafe_math_optimizations"
17092   "fyl2xp1"
17093   [(set_attr "type" "fpspc")
17094    (set_attr "mode" "XF")])
17095
17096 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17097   [(set (match_operand:XF 0 "register_operand" "=f")
17098         (unspec:XF [(float_extend:XF
17099                       (match_operand:MODEF 1 "register_operand" "0"))
17100                     (match_operand:XF 2 "register_operand" "u")]
17101                    UNSPEC_FYL2XP1))
17102    (clobber (match_scratch:XF 3 "=2"))]
17103   "TARGET_USE_FANCY_MATH_387
17104    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17105        || TARGET_MIX_SSE_I387)
17106    && flag_unsafe_math_optimizations"
17107   "fyl2xp1"
17108   [(set_attr "type" "fpspc")
17109    (set_attr "mode" "XF")])
17110
17111 (define_expand "log1pxf2"
17112   [(use (match_operand:XF 0 "register_operand" ""))
17113    (use (match_operand:XF 1 "register_operand" ""))]
17114   "TARGET_USE_FANCY_MATH_387
17115    && flag_unsafe_math_optimizations && !optimize_size"
17116 {
17117   ix86_emit_i387_log1p (operands[0], operands[1]);
17118   DONE;
17119 })
17120
17121 (define_expand "log1p<mode>2"
17122   [(use (match_operand:MODEF 0 "register_operand" ""))
17123    (use (match_operand:MODEF 1 "register_operand" ""))]
17124   "TARGET_USE_FANCY_MATH_387
17125    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17126        || TARGET_MIX_SSE_I387)
17127    && flag_unsafe_math_optimizations && !optimize_size"
17128 {
17129   rtx op0 = gen_reg_rtx (XFmode);
17130
17131   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17132
17133   ix86_emit_i387_log1p (op0, operands[1]);
17134   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17135   DONE;
17136 })
17137
17138 (define_insn "fxtractxf3_i387"
17139   [(set (match_operand:XF 0 "register_operand" "=f")
17140         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17141                    UNSPEC_XTRACT_FRACT))
17142    (set (match_operand:XF 1 "register_operand" "=u")
17143         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17144   "TARGET_USE_FANCY_MATH_387
17145    && flag_unsafe_math_optimizations"
17146   "fxtract"
17147   [(set_attr "type" "fpspc")
17148    (set_attr "mode" "XF")])
17149
17150 (define_insn "fxtract_extend<mode>xf3_i387"
17151   [(set (match_operand:XF 0 "register_operand" "=f")
17152         (unspec:XF [(float_extend:XF
17153                       (match_operand:MODEF 2 "register_operand" "0"))]
17154                    UNSPEC_XTRACT_FRACT))
17155    (set (match_operand:XF 1 "register_operand" "=u")
17156         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17157   "TARGET_USE_FANCY_MATH_387
17158    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17159        || TARGET_MIX_SSE_I387)
17160    && flag_unsafe_math_optimizations"
17161   "fxtract"
17162   [(set_attr "type" "fpspc")
17163    (set_attr "mode" "XF")])
17164
17165 (define_expand "logbxf2"
17166   [(parallel [(set (match_dup 2)
17167                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17168                               UNSPEC_XTRACT_FRACT))
17169               (set (match_operand:XF 0 "register_operand" "")
17170                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17171   "TARGET_USE_FANCY_MATH_387
17172    && flag_unsafe_math_optimizations"
17173 {
17174   operands[2] = gen_reg_rtx (XFmode);
17175 })
17176
17177 (define_expand "logb<mode>2"
17178   [(use (match_operand:MODEF 0 "register_operand" ""))
17179    (use (match_operand:MODEF 1 "register_operand" ""))]
17180   "TARGET_USE_FANCY_MATH_387
17181    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17182        || TARGET_MIX_SSE_I387)
17183    && flag_unsafe_math_optimizations"
17184 {
17185   rtx op0 = gen_reg_rtx (XFmode);
17186   rtx op1 = gen_reg_rtx (XFmode);
17187
17188   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17189   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17190   DONE;
17191 })
17192
17193 (define_expand "ilogbxf2"
17194   [(use (match_operand:SI 0 "register_operand" ""))
17195    (use (match_operand:XF 1 "register_operand" ""))]
17196   "TARGET_USE_FANCY_MATH_387
17197    && flag_unsafe_math_optimizations && !optimize_size"
17198 {
17199   rtx op0 = gen_reg_rtx (XFmode);
17200   rtx op1 = gen_reg_rtx (XFmode);
17201
17202   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17203   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17204   DONE;
17205 })
17206
17207 (define_expand "ilogb<mode>2"
17208   [(use (match_operand:SI 0 "register_operand" ""))
17209    (use (match_operand:MODEF 1 "register_operand" ""))]
17210   "TARGET_USE_FANCY_MATH_387
17211    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17212        || TARGET_MIX_SSE_I387)
17213    && flag_unsafe_math_optimizations && !optimize_size"
17214 {
17215   rtx op0 = gen_reg_rtx (XFmode);
17216   rtx op1 = gen_reg_rtx (XFmode);
17217
17218   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17219   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17220   DONE;
17221 })
17222
17223 (define_insn "*f2xm1xf2_i387"
17224   [(set (match_operand:XF 0 "register_operand" "=f")
17225         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17226                    UNSPEC_F2XM1))]
17227   "TARGET_USE_FANCY_MATH_387
17228    && flag_unsafe_math_optimizations"
17229   "f2xm1"
17230   [(set_attr "type" "fpspc")
17231    (set_attr "mode" "XF")])
17232
17233 (define_insn "*fscalexf4_i387"
17234   [(set (match_operand:XF 0 "register_operand" "=f")
17235         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17236                     (match_operand:XF 3 "register_operand" "1")]
17237                    UNSPEC_FSCALE_FRACT))
17238    (set (match_operand:XF 1 "register_operand" "=u")
17239         (unspec:XF [(match_dup 2) (match_dup 3)]
17240                    UNSPEC_FSCALE_EXP))]
17241   "TARGET_USE_FANCY_MATH_387
17242    && flag_unsafe_math_optimizations"
17243   "fscale"
17244   [(set_attr "type" "fpspc")
17245    (set_attr "mode" "XF")])
17246
17247 (define_expand "expNcorexf3"
17248   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17249                                (match_operand:XF 2 "register_operand" "")))
17250    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17251    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17252    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17253    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17254    (parallel [(set (match_operand:XF 0 "register_operand" "")
17255                    (unspec:XF [(match_dup 8) (match_dup 4)]
17256                               UNSPEC_FSCALE_FRACT))
17257               (set (match_dup 9)
17258                    (unspec:XF [(match_dup 8) (match_dup 4)]
17259                               UNSPEC_FSCALE_EXP))])]
17260   "TARGET_USE_FANCY_MATH_387
17261    && flag_unsafe_math_optimizations && !optimize_size"
17262 {
17263   int i;
17264
17265   for (i = 3; i < 10; i++)
17266     operands[i] = gen_reg_rtx (XFmode);
17267
17268   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17269 })
17270
17271 (define_expand "expxf2"
17272   [(use (match_operand:XF 0 "register_operand" ""))
17273    (use (match_operand:XF 1 "register_operand" ""))]
17274   "TARGET_USE_FANCY_MATH_387
17275    && flag_unsafe_math_optimizations && !optimize_size"
17276 {
17277   rtx op2 = gen_reg_rtx (XFmode);
17278   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17279
17280   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17281   DONE;
17282 })
17283
17284 (define_expand "exp<mode>2"
17285   [(use (match_operand:MODEF 0 "register_operand" ""))
17286    (use (match_operand:MODEF 1 "general_operand" ""))]
17287  "TARGET_USE_FANCY_MATH_387
17288    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17289        || TARGET_MIX_SSE_I387)
17290    && flag_unsafe_math_optimizations && !optimize_size"
17291 {
17292   rtx op0 = gen_reg_rtx (XFmode);
17293   rtx op1 = gen_reg_rtx (XFmode);
17294
17295   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17296   emit_insn (gen_expxf2 (op0, op1));
17297   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17298   DONE;
17299 })
17300
17301 (define_expand "exp10xf2"
17302   [(use (match_operand:XF 0 "register_operand" ""))
17303    (use (match_operand:XF 1 "register_operand" ""))]
17304   "TARGET_USE_FANCY_MATH_387
17305    && flag_unsafe_math_optimizations && !optimize_size"
17306 {
17307   rtx op2 = gen_reg_rtx (XFmode);
17308   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17309
17310   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17311   DONE;
17312 })
17313
17314 (define_expand "exp10<mode>2"
17315   [(use (match_operand:MODEF 0 "register_operand" ""))
17316    (use (match_operand:MODEF 1 "general_operand" ""))]
17317  "TARGET_USE_FANCY_MATH_387
17318    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17319        || TARGET_MIX_SSE_I387)
17320    && flag_unsafe_math_optimizations && !optimize_size"
17321 {
17322   rtx op0 = gen_reg_rtx (XFmode);
17323   rtx op1 = gen_reg_rtx (XFmode);
17324
17325   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17326   emit_insn (gen_exp10xf2 (op0, op1));
17327   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17328   DONE;
17329 })
17330
17331 (define_expand "exp2xf2"
17332   [(use (match_operand:XF 0 "register_operand" ""))
17333    (use (match_operand:XF 1 "register_operand" ""))]
17334   "TARGET_USE_FANCY_MATH_387
17335    && flag_unsafe_math_optimizations && !optimize_size"
17336 {
17337   rtx op2 = gen_reg_rtx (XFmode);
17338   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17339
17340   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17341   DONE;
17342 })
17343
17344 (define_expand "exp2<mode>2"
17345   [(use (match_operand:MODEF 0 "register_operand" ""))
17346    (use (match_operand:MODEF 1 "general_operand" ""))]
17347  "TARGET_USE_FANCY_MATH_387
17348    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17349        || TARGET_MIX_SSE_I387)
17350    && flag_unsafe_math_optimizations && !optimize_size"
17351 {
17352   rtx op0 = gen_reg_rtx (XFmode);
17353   rtx op1 = gen_reg_rtx (XFmode);
17354
17355   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17356   emit_insn (gen_exp2xf2 (op0, op1));
17357   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17358   DONE;
17359 })
17360
17361 (define_expand "expm1xf2"
17362   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17363                                (match_dup 2)))
17364    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17365    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17366    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17367    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17368    (parallel [(set (match_dup 7)
17369                    (unspec:XF [(match_dup 6) (match_dup 4)]
17370                               UNSPEC_FSCALE_FRACT))
17371               (set (match_dup 8)
17372                    (unspec:XF [(match_dup 6) (match_dup 4)]
17373                               UNSPEC_FSCALE_EXP))])
17374    (parallel [(set (match_dup 10)
17375                    (unspec:XF [(match_dup 9) (match_dup 8)]
17376                               UNSPEC_FSCALE_FRACT))
17377               (set (match_dup 11)
17378                    (unspec:XF [(match_dup 9) (match_dup 8)]
17379                               UNSPEC_FSCALE_EXP))])
17380    (set (match_dup 12) (minus:XF (match_dup 10)
17381                                  (float_extend:XF (match_dup 13))))
17382    (set (match_operand:XF 0 "register_operand" "")
17383         (plus:XF (match_dup 12) (match_dup 7)))]
17384   "TARGET_USE_FANCY_MATH_387
17385    && flag_unsafe_math_optimizations && !optimize_size"
17386 {
17387   int i;
17388
17389   for (i = 2; i < 13; i++)
17390     operands[i] = gen_reg_rtx (XFmode);
17391
17392   operands[13]
17393     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17394
17395   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17396 })
17397
17398 (define_expand "expm1<mode>2"
17399   [(use (match_operand:MODEF 0 "register_operand" ""))
17400    (use (match_operand:MODEF 1 "general_operand" ""))]
17401  "TARGET_USE_FANCY_MATH_387
17402    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17403        || TARGET_MIX_SSE_I387)
17404    && flag_unsafe_math_optimizations && !optimize_size"
17405 {
17406   rtx op0 = gen_reg_rtx (XFmode);
17407   rtx op1 = gen_reg_rtx (XFmode);
17408
17409   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17410   emit_insn (gen_expm1xf2 (op0, op1));
17411   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17412   DONE;
17413 })
17414
17415 (define_expand "ldexpxf3"
17416   [(set (match_dup 3)
17417         (float:XF (match_operand:SI 2 "register_operand" "")))
17418    (parallel [(set (match_operand:XF 0 " register_operand" "")
17419                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17420                                (match_dup 3)]
17421                               UNSPEC_FSCALE_FRACT))
17422               (set (match_dup 4)
17423                    (unspec:XF [(match_dup 1) (match_dup 3)]
17424                               UNSPEC_FSCALE_EXP))])]
17425   "TARGET_USE_FANCY_MATH_387
17426    && flag_unsafe_math_optimizations && !optimize_size"
17427 {
17428   operands[3] = gen_reg_rtx (XFmode);
17429   operands[4] = gen_reg_rtx (XFmode);
17430 })
17431
17432 (define_expand "ldexp<mode>3"
17433   [(use (match_operand:MODEF 0 "register_operand" ""))
17434    (use (match_operand:MODEF 1 "general_operand" ""))
17435    (use (match_operand:SI 2 "register_operand" ""))]
17436  "TARGET_USE_FANCY_MATH_387
17437    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17438        || TARGET_MIX_SSE_I387)
17439    && flag_unsafe_math_optimizations && !optimize_size"
17440 {
17441   rtx op0 = gen_reg_rtx (XFmode);
17442   rtx op1 = gen_reg_rtx (XFmode);
17443
17444   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17445   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17446   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17447   DONE;
17448 })
17449
17450 (define_expand "scalbxf3"
17451   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17452                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17453                                (match_operand:XF 2 "register_operand" "")]
17454                               UNSPEC_FSCALE_FRACT))
17455               (set (match_dup 3)
17456                    (unspec:XF [(match_dup 1) (match_dup 2)]
17457                               UNSPEC_FSCALE_EXP))])]
17458   "TARGET_USE_FANCY_MATH_387
17459    && flag_unsafe_math_optimizations && !optimize_size"
17460 {
17461   operands[3] = gen_reg_rtx (XFmode);
17462 })
17463
17464 (define_expand "scalb<mode>3"
17465   [(use (match_operand:MODEF 0 "register_operand" ""))
17466    (use (match_operand:MODEF 1 "general_operand" ""))
17467    (use (match_operand:MODEF 2 "register_operand" ""))]
17468  "TARGET_USE_FANCY_MATH_387
17469    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17470        || TARGET_MIX_SSE_I387)
17471    && flag_unsafe_math_optimizations && !optimize_size"
17472 {
17473   rtx op0 = gen_reg_rtx (XFmode);
17474   rtx op1 = gen_reg_rtx (XFmode);
17475   rtx op2 = gen_reg_rtx (XFmode);
17476
17477   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17478   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17479   emit_insn (gen_scalbxf3 (op0, op1, op2));
17480   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17481   DONE;
17482 })
17483 \f
17484
17485 (define_insn "sse4_1_round<mode>2"
17486   [(set (match_operand:MODEF 0 "register_operand" "=x")
17487         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17488                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
17489                       UNSPEC_ROUND))]
17490   "TARGET_ROUND"
17491   "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17492   [(set_attr "type" "ssecvt")
17493    (set_attr "prefix_extra" "1")
17494    (set_attr "mode" "<MODE>")])
17495
17496 (define_insn "rintxf2"
17497   [(set (match_operand:XF 0 "register_operand" "=f")
17498         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17499                    UNSPEC_FRNDINT))]
17500   "TARGET_USE_FANCY_MATH_387
17501    && flag_unsafe_math_optimizations"
17502   "frndint"
17503   [(set_attr "type" "fpspc")
17504    (set_attr "mode" "XF")])
17505
17506 (define_expand "rint<mode>2"
17507   [(use (match_operand:MODEF 0 "register_operand" ""))
17508    (use (match_operand:MODEF 1 "register_operand" ""))]
17509   "(TARGET_USE_FANCY_MATH_387
17510     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17511         || TARGET_MIX_SSE_I387)
17512     && flag_unsafe_math_optimizations)
17513    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17514        && !flag_trapping_math
17515        && (TARGET_ROUND || !optimize_size))"
17516 {
17517   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17518       && !flag_trapping_math
17519       && (TARGET_ROUND || !optimize_size))
17520     {
17521       if (TARGET_ROUND)
17522         emit_insn (gen_sse4_1_round<mode>2
17523                    (operands[0], operands[1], GEN_INT (0x04)));
17524       else
17525         ix86_expand_rint (operand0, operand1);
17526     }
17527   else
17528     {
17529       rtx op0 = gen_reg_rtx (XFmode);
17530       rtx op1 = gen_reg_rtx (XFmode);
17531
17532       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17533       emit_insn (gen_rintxf2 (op0, op1));
17534
17535       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17536     }
17537   DONE;
17538 })
17539
17540 (define_expand "round<mode>2"
17541   [(match_operand:MODEF 0 "register_operand" "")
17542    (match_operand:MODEF 1 "nonimmediate_operand" "")]
17543   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17544    && !flag_trapping_math && !flag_rounding_math
17545    && !optimize_size"
17546 {
17547   if (TARGET_64BIT || (<MODE>mode != DFmode))
17548     ix86_expand_round (operand0, operand1);
17549   else
17550     ix86_expand_rounddf_32 (operand0, operand1);
17551   DONE;
17552 })
17553
17554 (define_insn_and_split "*fistdi2_1"
17555   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17556         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17557                    UNSPEC_FIST))]
17558   "TARGET_USE_FANCY_MATH_387
17559    && !(reload_completed || reload_in_progress)"
17560   "#"
17561   "&& 1"
17562   [(const_int 0)]
17563 {
17564   if (memory_operand (operands[0], VOIDmode))
17565     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17566   else
17567     {
17568       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17569       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17570                                          operands[2]));
17571     }
17572   DONE;
17573 }
17574   [(set_attr "type" "fpspc")
17575    (set_attr "mode" "DI")])
17576
17577 (define_insn "fistdi2"
17578   [(set (match_operand:DI 0 "memory_operand" "=m")
17579         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17580                    UNSPEC_FIST))
17581    (clobber (match_scratch:XF 2 "=&1f"))]
17582   "TARGET_USE_FANCY_MATH_387"
17583   "* return output_fix_trunc (insn, operands, 0);"
17584   [(set_attr "type" "fpspc")
17585    (set_attr "mode" "DI")])
17586
17587 (define_insn "fistdi2_with_temp"
17588   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17589         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17590                    UNSPEC_FIST))
17591    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17592    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17593   "TARGET_USE_FANCY_MATH_387"
17594   "#"
17595   [(set_attr "type" "fpspc")
17596    (set_attr "mode" "DI")])
17597
17598 (define_split
17599   [(set (match_operand:DI 0 "register_operand" "")
17600         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17601                    UNSPEC_FIST))
17602    (clobber (match_operand:DI 2 "memory_operand" ""))
17603    (clobber (match_scratch 3 ""))]
17604   "reload_completed"
17605   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17606               (clobber (match_dup 3))])
17607    (set (match_dup 0) (match_dup 2))]
17608   "")
17609
17610 (define_split
17611   [(set (match_operand:DI 0 "memory_operand" "")
17612         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17613                    UNSPEC_FIST))
17614    (clobber (match_operand:DI 2 "memory_operand" ""))
17615    (clobber (match_scratch 3 ""))]
17616   "reload_completed"
17617   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17618               (clobber (match_dup 3))])]
17619   "")
17620
17621 (define_insn_and_split "*fist<mode>2_1"
17622   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17623         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17624                            UNSPEC_FIST))]
17625   "TARGET_USE_FANCY_MATH_387
17626    && !(reload_completed || reload_in_progress)"
17627   "#"
17628   "&& 1"
17629   [(const_int 0)]
17630 {
17631   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17632   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17633                                         operands[2]));
17634   DONE;
17635 }
17636   [(set_attr "type" "fpspc")
17637    (set_attr "mode" "<MODE>")])
17638
17639 (define_insn "fist<mode>2"
17640   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17641         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17642                            UNSPEC_FIST))]
17643   "TARGET_USE_FANCY_MATH_387"
17644   "* return output_fix_trunc (insn, operands, 0);"
17645   [(set_attr "type" "fpspc")
17646    (set_attr "mode" "<MODE>")])
17647
17648 (define_insn "fist<mode>2_with_temp"
17649   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17650         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17651                            UNSPEC_FIST))
17652    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17653   "TARGET_USE_FANCY_MATH_387"
17654   "#"
17655   [(set_attr "type" "fpspc")
17656    (set_attr "mode" "<MODE>")])
17657
17658 (define_split
17659   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17660         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17661                            UNSPEC_FIST))
17662    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17663   "reload_completed"
17664   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17665    (set (match_dup 0) (match_dup 2))]
17666   "")
17667
17668 (define_split
17669   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17670         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17671                            UNSPEC_FIST))
17672    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17673   "reload_completed"
17674   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17675   "")
17676
17677 (define_expand "lrintxf<mode>2"
17678   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17679      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17680                       UNSPEC_FIST))]
17681   "TARGET_USE_FANCY_MATH_387"
17682   "")
17683
17684 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17685   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17686      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17687                         UNSPEC_FIX_NOTRUNC))]
17688   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17689    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17690   "")
17691
17692 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17693   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17694    (match_operand:MODEF 1 "register_operand" "")]
17695   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17696    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17697    && !flag_trapping_math && !flag_rounding_math
17698    && !optimize_size"
17699 {
17700   ix86_expand_lround (operand0, operand1);
17701   DONE;
17702 })
17703
17704 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17705 (define_insn_and_split "frndintxf2_floor"
17706   [(set (match_operand:XF 0 "register_operand" "")
17707         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17708          UNSPEC_FRNDINT_FLOOR))
17709    (clobber (reg:CC FLAGS_REG))]
17710   "TARGET_USE_FANCY_MATH_387
17711    && flag_unsafe_math_optimizations
17712    && !(reload_completed || reload_in_progress)"
17713   "#"
17714   "&& 1"
17715   [(const_int 0)]
17716 {
17717   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17718
17719   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17720   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17721
17722   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17723                                         operands[2], operands[3]));
17724   DONE;
17725 }
17726   [(set_attr "type" "frndint")
17727    (set_attr "i387_cw" "floor")
17728    (set_attr "mode" "XF")])
17729
17730 (define_insn "frndintxf2_floor_i387"
17731   [(set (match_operand:XF 0 "register_operand" "=f")
17732         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17733          UNSPEC_FRNDINT_FLOOR))
17734    (use (match_operand:HI 2 "memory_operand" "m"))
17735    (use (match_operand:HI 3 "memory_operand" "m"))]
17736   "TARGET_USE_FANCY_MATH_387
17737    && flag_unsafe_math_optimizations"
17738   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17739   [(set_attr "type" "frndint")
17740    (set_attr "i387_cw" "floor")
17741    (set_attr "mode" "XF")])
17742
17743 (define_expand "floorxf2"
17744   [(use (match_operand:XF 0 "register_operand" ""))
17745    (use (match_operand:XF 1 "register_operand" ""))]
17746   "TARGET_USE_FANCY_MATH_387
17747    && flag_unsafe_math_optimizations && !optimize_size"
17748 {
17749   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17750   DONE;
17751 })
17752
17753 (define_expand "floor<mode>2"
17754   [(use (match_operand:MODEF 0 "register_operand" ""))
17755    (use (match_operand:MODEF 1 "register_operand" ""))]
17756   "(TARGET_USE_FANCY_MATH_387
17757     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17758         || TARGET_MIX_SSE_I387)
17759     && flag_unsafe_math_optimizations && !optimize_size)
17760    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17761        && !flag_trapping_math
17762        && (TARGET_ROUND || !optimize_size))"
17763 {
17764   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17765       && !flag_trapping_math
17766       && (TARGET_ROUND || !optimize_size))
17767     {
17768       if (TARGET_ROUND)
17769         emit_insn (gen_sse4_1_round<mode>2
17770                    (operands[0], operands[1], GEN_INT (0x01)));
17771       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17772         ix86_expand_floorceil (operand0, operand1, true);
17773       else
17774         ix86_expand_floorceildf_32 (operand0, operand1, true);
17775     }
17776   else
17777     {
17778       rtx op0 = gen_reg_rtx (XFmode);
17779       rtx op1 = gen_reg_rtx (XFmode);
17780
17781       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17782       emit_insn (gen_frndintxf2_floor (op0, op1));
17783
17784       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17785     }
17786   DONE;
17787 })
17788
17789 (define_insn_and_split "*fist<mode>2_floor_1"
17790   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17791         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17792          UNSPEC_FIST_FLOOR))
17793    (clobber (reg:CC FLAGS_REG))]
17794   "TARGET_USE_FANCY_MATH_387
17795    && flag_unsafe_math_optimizations
17796    && !(reload_completed || reload_in_progress)"
17797   "#"
17798   "&& 1"
17799   [(const_int 0)]
17800 {
17801   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17802
17803   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17804   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17805   if (memory_operand (operands[0], VOIDmode))
17806     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17807                                       operands[2], operands[3]));
17808   else
17809     {
17810       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17811       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17812                                                   operands[2], operands[3],
17813                                                   operands[4]));
17814     }
17815   DONE;
17816 }
17817   [(set_attr "type" "fistp")
17818    (set_attr "i387_cw" "floor")
17819    (set_attr "mode" "<MODE>")])
17820
17821 (define_insn "fistdi2_floor"
17822   [(set (match_operand:DI 0 "memory_operand" "=m")
17823         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17824          UNSPEC_FIST_FLOOR))
17825    (use (match_operand:HI 2 "memory_operand" "m"))
17826    (use (match_operand:HI 3 "memory_operand" "m"))
17827    (clobber (match_scratch:XF 4 "=&1f"))]
17828   "TARGET_USE_FANCY_MATH_387
17829    && flag_unsafe_math_optimizations"
17830   "* return output_fix_trunc (insn, operands, 0);"
17831   [(set_attr "type" "fistp")
17832    (set_attr "i387_cw" "floor")
17833    (set_attr "mode" "DI")])
17834
17835 (define_insn "fistdi2_floor_with_temp"
17836   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17837         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17838          UNSPEC_FIST_FLOOR))
17839    (use (match_operand:HI 2 "memory_operand" "m,m"))
17840    (use (match_operand:HI 3 "memory_operand" "m,m"))
17841    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17842    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17843   "TARGET_USE_FANCY_MATH_387
17844    && flag_unsafe_math_optimizations"
17845   "#"
17846   [(set_attr "type" "fistp")
17847    (set_attr "i387_cw" "floor")
17848    (set_attr "mode" "DI")])
17849
17850 (define_split
17851   [(set (match_operand:DI 0 "register_operand" "")
17852         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17853          UNSPEC_FIST_FLOOR))
17854    (use (match_operand:HI 2 "memory_operand" ""))
17855    (use (match_operand:HI 3 "memory_operand" ""))
17856    (clobber (match_operand:DI 4 "memory_operand" ""))
17857    (clobber (match_scratch 5 ""))]
17858   "reload_completed"
17859   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17860               (use (match_dup 2))
17861               (use (match_dup 3))
17862               (clobber (match_dup 5))])
17863    (set (match_dup 0) (match_dup 4))]
17864   "")
17865
17866 (define_split
17867   [(set (match_operand:DI 0 "memory_operand" "")
17868         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17869          UNSPEC_FIST_FLOOR))
17870    (use (match_operand:HI 2 "memory_operand" ""))
17871    (use (match_operand:HI 3 "memory_operand" ""))
17872    (clobber (match_operand:DI 4 "memory_operand" ""))
17873    (clobber (match_scratch 5 ""))]
17874   "reload_completed"
17875   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17876               (use (match_dup 2))
17877               (use (match_dup 3))
17878               (clobber (match_dup 5))])]
17879   "")
17880
17881 (define_insn "fist<mode>2_floor"
17882   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17883         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17884          UNSPEC_FIST_FLOOR))
17885    (use (match_operand:HI 2 "memory_operand" "m"))
17886    (use (match_operand:HI 3 "memory_operand" "m"))]
17887   "TARGET_USE_FANCY_MATH_387
17888    && flag_unsafe_math_optimizations"
17889   "* return output_fix_trunc (insn, operands, 0);"
17890   [(set_attr "type" "fistp")
17891    (set_attr "i387_cw" "floor")
17892    (set_attr "mode" "<MODE>")])
17893
17894 (define_insn "fist<mode>2_floor_with_temp"
17895   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17896         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17897          UNSPEC_FIST_FLOOR))
17898    (use (match_operand:HI 2 "memory_operand" "m,m"))
17899    (use (match_operand:HI 3 "memory_operand" "m,m"))
17900    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17901   "TARGET_USE_FANCY_MATH_387
17902    && flag_unsafe_math_optimizations"
17903   "#"
17904   [(set_attr "type" "fistp")
17905    (set_attr "i387_cw" "floor")
17906    (set_attr "mode" "<MODE>")])
17907
17908 (define_split
17909   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17910         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17911          UNSPEC_FIST_FLOOR))
17912    (use (match_operand:HI 2 "memory_operand" ""))
17913    (use (match_operand:HI 3 "memory_operand" ""))
17914    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17915   "reload_completed"
17916   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17917                                   UNSPEC_FIST_FLOOR))
17918               (use (match_dup 2))
17919               (use (match_dup 3))])
17920    (set (match_dup 0) (match_dup 4))]
17921   "")
17922
17923 (define_split
17924   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17925         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17926          UNSPEC_FIST_FLOOR))
17927    (use (match_operand:HI 2 "memory_operand" ""))
17928    (use (match_operand:HI 3 "memory_operand" ""))
17929    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17930   "reload_completed"
17931   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17932                                   UNSPEC_FIST_FLOOR))
17933               (use (match_dup 2))
17934               (use (match_dup 3))])]
17935   "")
17936
17937 (define_expand "lfloorxf<mode>2"
17938   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17939                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17940                     UNSPEC_FIST_FLOOR))
17941               (clobber (reg:CC FLAGS_REG))])]
17942   "TARGET_USE_FANCY_MATH_387
17943    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17944    && flag_unsafe_math_optimizations"
17945   "")
17946
17947 (define_expand "lfloor<mode>di2"
17948   [(match_operand:DI 0 "nonimmediate_operand" "")
17949    (match_operand:MODEF 1 "register_operand" "")]
17950   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17951    && !flag_trapping_math
17952    && !optimize_size"
17953 {
17954   ix86_expand_lfloorceil (operand0, operand1, true);
17955   DONE;
17956 })
17957
17958 (define_expand "lfloor<mode>si2"
17959   [(match_operand:SI 0 "nonimmediate_operand" "")
17960    (match_operand:MODEF 1 "register_operand" "")]
17961   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17962    && !flag_trapping_math
17963    && (!optimize_size || !TARGET_64BIT)"
17964 {
17965   ix86_expand_lfloorceil (operand0, operand1, true);
17966   DONE;
17967 })
17968
17969 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17970 (define_insn_and_split "frndintxf2_ceil"
17971   [(set (match_operand:XF 0 "register_operand" "")
17972         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17973          UNSPEC_FRNDINT_CEIL))
17974    (clobber (reg:CC FLAGS_REG))]
17975   "TARGET_USE_FANCY_MATH_387
17976    && flag_unsafe_math_optimizations
17977    && !(reload_completed || reload_in_progress)"
17978   "#"
17979   "&& 1"
17980   [(const_int 0)]
17981 {
17982   ix86_optimize_mode_switching[I387_CEIL] = 1;
17983
17984   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17985   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17986
17987   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17988                                        operands[2], operands[3]));
17989   DONE;
17990 }
17991   [(set_attr "type" "frndint")
17992    (set_attr "i387_cw" "ceil")
17993    (set_attr "mode" "XF")])
17994
17995 (define_insn "frndintxf2_ceil_i387"
17996   [(set (match_operand:XF 0 "register_operand" "=f")
17997         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17998          UNSPEC_FRNDINT_CEIL))
17999    (use (match_operand:HI 2 "memory_operand" "m"))
18000    (use (match_operand:HI 3 "memory_operand" "m"))]
18001   "TARGET_USE_FANCY_MATH_387
18002    && flag_unsafe_math_optimizations"
18003   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18004   [(set_attr "type" "frndint")
18005    (set_attr "i387_cw" "ceil")
18006    (set_attr "mode" "XF")])
18007
18008 (define_expand "ceilxf2"
18009   [(use (match_operand:XF 0 "register_operand" ""))
18010    (use (match_operand:XF 1 "register_operand" ""))]
18011   "TARGET_USE_FANCY_MATH_387
18012    && flag_unsafe_math_optimizations && !optimize_size"
18013 {
18014   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18015   DONE;
18016 })
18017
18018 (define_expand "ceil<mode>2"
18019   [(use (match_operand:MODEF 0 "register_operand" ""))
18020    (use (match_operand:MODEF 1 "register_operand" ""))]
18021   "(TARGET_USE_FANCY_MATH_387
18022     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18023         || TARGET_MIX_SSE_I387)
18024     && flag_unsafe_math_optimizations && !optimize_size)
18025    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18026        && !flag_trapping_math
18027        && (TARGET_ROUND || !optimize_size))"
18028 {
18029   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18030       && !flag_trapping_math
18031       && (TARGET_ROUND || !optimize_size))
18032     {
18033       if (TARGET_ROUND)
18034         emit_insn (gen_sse4_1_round<mode>2
18035                    (operands[0], operands[1], GEN_INT (0x02)));
18036       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18037         ix86_expand_floorceil (operand0, operand1, false);
18038       else
18039         ix86_expand_floorceildf_32 (operand0, operand1, false);
18040     }
18041   else
18042     {
18043       rtx op0 = gen_reg_rtx (XFmode);
18044       rtx op1 = gen_reg_rtx (XFmode);
18045
18046       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18047       emit_insn (gen_frndintxf2_ceil (op0, op1));
18048
18049       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18050     }
18051   DONE;
18052 })
18053
18054 (define_insn_and_split "*fist<mode>2_ceil_1"
18055   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18056         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18057          UNSPEC_FIST_CEIL))
18058    (clobber (reg:CC FLAGS_REG))]
18059   "TARGET_USE_FANCY_MATH_387
18060    && flag_unsafe_math_optimizations
18061    && !(reload_completed || reload_in_progress)"
18062   "#"
18063   "&& 1"
18064   [(const_int 0)]
18065 {
18066   ix86_optimize_mode_switching[I387_CEIL] = 1;
18067
18068   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18069   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18070   if (memory_operand (operands[0], VOIDmode))
18071     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18072                                      operands[2], operands[3]));
18073   else
18074     {
18075       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18076       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18077                                                  operands[2], operands[3],
18078                                                  operands[4]));
18079     }
18080   DONE;
18081 }
18082   [(set_attr "type" "fistp")
18083    (set_attr "i387_cw" "ceil")
18084    (set_attr "mode" "<MODE>")])
18085
18086 (define_insn "fistdi2_ceil"
18087   [(set (match_operand:DI 0 "memory_operand" "=m")
18088         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18089          UNSPEC_FIST_CEIL))
18090    (use (match_operand:HI 2 "memory_operand" "m"))
18091    (use (match_operand:HI 3 "memory_operand" "m"))
18092    (clobber (match_scratch:XF 4 "=&1f"))]
18093   "TARGET_USE_FANCY_MATH_387
18094    && flag_unsafe_math_optimizations"
18095   "* return output_fix_trunc (insn, operands, 0);"
18096   [(set_attr "type" "fistp")
18097    (set_attr "i387_cw" "ceil")
18098    (set_attr "mode" "DI")])
18099
18100 (define_insn "fistdi2_ceil_with_temp"
18101   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18102         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18103          UNSPEC_FIST_CEIL))
18104    (use (match_operand:HI 2 "memory_operand" "m,m"))
18105    (use (match_operand:HI 3 "memory_operand" "m,m"))
18106    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
18107    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18108   "TARGET_USE_FANCY_MATH_387
18109    && flag_unsafe_math_optimizations"
18110   "#"
18111   [(set_attr "type" "fistp")
18112    (set_attr "i387_cw" "ceil")
18113    (set_attr "mode" "DI")])
18114
18115 (define_split
18116   [(set (match_operand:DI 0 "register_operand" "")
18117         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18118          UNSPEC_FIST_CEIL))
18119    (use (match_operand:HI 2 "memory_operand" ""))
18120    (use (match_operand:HI 3 "memory_operand" ""))
18121    (clobber (match_operand:DI 4 "memory_operand" ""))
18122    (clobber (match_scratch 5 ""))]
18123   "reload_completed"
18124   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18125               (use (match_dup 2))
18126               (use (match_dup 3))
18127               (clobber (match_dup 5))])
18128    (set (match_dup 0) (match_dup 4))]
18129   "")
18130
18131 (define_split
18132   [(set (match_operand:DI 0 "memory_operand" "")
18133         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18134          UNSPEC_FIST_CEIL))
18135    (use (match_operand:HI 2 "memory_operand" ""))
18136    (use (match_operand:HI 3 "memory_operand" ""))
18137    (clobber (match_operand:DI 4 "memory_operand" ""))
18138    (clobber (match_scratch 5 ""))]
18139   "reload_completed"
18140   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18141               (use (match_dup 2))
18142               (use (match_dup 3))
18143               (clobber (match_dup 5))])]
18144   "")
18145
18146 (define_insn "fist<mode>2_ceil"
18147   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18148         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18149          UNSPEC_FIST_CEIL))
18150    (use (match_operand:HI 2 "memory_operand" "m"))
18151    (use (match_operand:HI 3 "memory_operand" "m"))]
18152   "TARGET_USE_FANCY_MATH_387
18153    && flag_unsafe_math_optimizations"
18154   "* return output_fix_trunc (insn, operands, 0);"
18155   [(set_attr "type" "fistp")
18156    (set_attr "i387_cw" "ceil")
18157    (set_attr "mode" "<MODE>")])
18158
18159 (define_insn "fist<mode>2_ceil_with_temp"
18160   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18161         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18162          UNSPEC_FIST_CEIL))
18163    (use (match_operand:HI 2 "memory_operand" "m,m"))
18164    (use (match_operand:HI 3 "memory_operand" "m,m"))
18165    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18166   "TARGET_USE_FANCY_MATH_387
18167    && flag_unsafe_math_optimizations"
18168   "#"
18169   [(set_attr "type" "fistp")
18170    (set_attr "i387_cw" "ceil")
18171    (set_attr "mode" "<MODE>")])
18172
18173 (define_split
18174   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18175         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18176          UNSPEC_FIST_CEIL))
18177    (use (match_operand:HI 2 "memory_operand" ""))
18178    (use (match_operand:HI 3 "memory_operand" ""))
18179    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18180   "reload_completed"
18181   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18182                                   UNSPEC_FIST_CEIL))
18183               (use (match_dup 2))
18184               (use (match_dup 3))])
18185    (set (match_dup 0) (match_dup 4))]
18186   "")
18187
18188 (define_split
18189   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18190         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18191          UNSPEC_FIST_CEIL))
18192    (use (match_operand:HI 2 "memory_operand" ""))
18193    (use (match_operand:HI 3 "memory_operand" ""))
18194    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18195   "reload_completed"
18196   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18197                                   UNSPEC_FIST_CEIL))
18198               (use (match_dup 2))
18199               (use (match_dup 3))])]
18200   "")
18201
18202 (define_expand "lceilxf<mode>2"
18203   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18204                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18205                     UNSPEC_FIST_CEIL))
18206               (clobber (reg:CC FLAGS_REG))])]
18207   "TARGET_USE_FANCY_MATH_387
18208    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18209    && flag_unsafe_math_optimizations"
18210   "")
18211
18212 (define_expand "lceil<mode>di2"
18213   [(match_operand:DI 0 "nonimmediate_operand" "")
18214    (match_operand:MODEF 1 "register_operand" "")]
18215   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18216    && !flag_trapping_math"
18217 {
18218   ix86_expand_lfloorceil (operand0, operand1, false);
18219   DONE;
18220 })
18221
18222 (define_expand "lceil<mode>si2"
18223   [(match_operand:SI 0 "nonimmediate_operand" "")
18224    (match_operand:MODEF 1 "register_operand" "")]
18225   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18226    && !flag_trapping_math"
18227 {
18228   ix86_expand_lfloorceil (operand0, operand1, false);
18229   DONE;
18230 })
18231
18232 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18233 (define_insn_and_split "frndintxf2_trunc"
18234   [(set (match_operand:XF 0 "register_operand" "")
18235         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18236          UNSPEC_FRNDINT_TRUNC))
18237    (clobber (reg:CC FLAGS_REG))]
18238   "TARGET_USE_FANCY_MATH_387
18239    && flag_unsafe_math_optimizations
18240    && !(reload_completed || reload_in_progress)"
18241   "#"
18242   "&& 1"
18243   [(const_int 0)]
18244 {
18245   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18246
18247   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18248   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18249
18250   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18251                                         operands[2], operands[3]));
18252   DONE;
18253 }
18254   [(set_attr "type" "frndint")
18255    (set_attr "i387_cw" "trunc")
18256    (set_attr "mode" "XF")])
18257
18258 (define_insn "frndintxf2_trunc_i387"
18259   [(set (match_operand:XF 0 "register_operand" "=f")
18260         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18261          UNSPEC_FRNDINT_TRUNC))
18262    (use (match_operand:HI 2 "memory_operand" "m"))
18263    (use (match_operand:HI 3 "memory_operand" "m"))]
18264   "TARGET_USE_FANCY_MATH_387
18265    && flag_unsafe_math_optimizations"
18266   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18267   [(set_attr "type" "frndint")
18268    (set_attr "i387_cw" "trunc")
18269    (set_attr "mode" "XF")])
18270
18271 (define_expand "btruncxf2"
18272   [(use (match_operand:XF 0 "register_operand" ""))
18273    (use (match_operand:XF 1 "register_operand" ""))]
18274   "TARGET_USE_FANCY_MATH_387
18275    && flag_unsafe_math_optimizations && !optimize_size"
18276 {
18277   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18278   DONE;
18279 })
18280
18281 (define_expand "btrunc<mode>2"
18282   [(use (match_operand:MODEF 0 "register_operand" ""))
18283    (use (match_operand:MODEF 1 "register_operand" ""))]
18284   "(TARGET_USE_FANCY_MATH_387
18285     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18286         || TARGET_MIX_SSE_I387)
18287     && flag_unsafe_math_optimizations && !optimize_size)
18288    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18289        && !flag_trapping_math
18290        && (TARGET_ROUND || !optimize_size))"
18291 {
18292   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18293       && !flag_trapping_math
18294       && (TARGET_ROUND || !optimize_size))
18295     {
18296       if (TARGET_ROUND)
18297         emit_insn (gen_sse4_1_round<mode>2
18298                    (operands[0], operands[1], GEN_INT (0x03)));
18299       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18300         ix86_expand_trunc (operand0, operand1);
18301       else
18302         ix86_expand_truncdf_32 (operand0, operand1);
18303     }
18304   else
18305     {
18306       rtx op0 = gen_reg_rtx (XFmode);
18307       rtx op1 = gen_reg_rtx (XFmode);
18308
18309       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18310       emit_insn (gen_frndintxf2_trunc (op0, op1));
18311
18312       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18313     }
18314   DONE;
18315 })
18316
18317 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18318 (define_insn_and_split "frndintxf2_mask_pm"
18319   [(set (match_operand:XF 0 "register_operand" "")
18320         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18321          UNSPEC_FRNDINT_MASK_PM))
18322    (clobber (reg:CC FLAGS_REG))]
18323   "TARGET_USE_FANCY_MATH_387
18324    && flag_unsafe_math_optimizations
18325    && !(reload_completed || reload_in_progress)"
18326   "#"
18327   "&& 1"
18328   [(const_int 0)]
18329 {
18330   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18331
18332   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18333   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18334
18335   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18336                                           operands[2], operands[3]));
18337   DONE;
18338 }
18339   [(set_attr "type" "frndint")
18340    (set_attr "i387_cw" "mask_pm")
18341    (set_attr "mode" "XF")])
18342
18343 (define_insn "frndintxf2_mask_pm_i387"
18344   [(set (match_operand:XF 0 "register_operand" "=f")
18345         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18346          UNSPEC_FRNDINT_MASK_PM))
18347    (use (match_operand:HI 2 "memory_operand" "m"))
18348    (use (match_operand:HI 3 "memory_operand" "m"))]
18349   "TARGET_USE_FANCY_MATH_387
18350    && flag_unsafe_math_optimizations"
18351   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18352   [(set_attr "type" "frndint")
18353    (set_attr "i387_cw" "mask_pm")
18354    (set_attr "mode" "XF")])
18355
18356 (define_expand "nearbyintxf2"
18357   [(use (match_operand:XF 0 "register_operand" ""))
18358    (use (match_operand:XF 1 "register_operand" ""))]
18359   "TARGET_USE_FANCY_MATH_387
18360    && flag_unsafe_math_optimizations"
18361 {
18362   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18363
18364   DONE;
18365 })
18366
18367 (define_expand "nearbyint<mode>2"
18368   [(use (match_operand:MODEF 0 "register_operand" ""))
18369    (use (match_operand:MODEF 1 "register_operand" ""))]
18370   "TARGET_USE_FANCY_MATH_387
18371    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18372        || TARGET_MIX_SSE_I387)
18373    && flag_unsafe_math_optimizations"
18374 {
18375   rtx op0 = gen_reg_rtx (XFmode);
18376   rtx op1 = gen_reg_rtx (XFmode);
18377
18378   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18379   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18380
18381   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18382   DONE;
18383 })
18384
18385 (define_insn "fxam<mode>2_i387"
18386   [(set (match_operand:HI 0 "register_operand" "=a")
18387         (unspec:HI
18388           [(match_operand:X87MODEF 1 "register_operand" "f")]
18389           UNSPEC_FXAM))]
18390   "TARGET_USE_FANCY_MATH_387"
18391   "fxam\n\tfnstsw\t%0"
18392   [(set_attr "type" "multi")
18393    (set_attr "unit" "i387")
18394    (set_attr "mode" "<MODE>")])
18395
18396 (define_expand "isinf<mode>2"
18397   [(use (match_operand:SI 0 "register_operand" ""))
18398    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18399   "TARGET_USE_FANCY_MATH_387
18400    && TARGET_C99_FUNCTIONS
18401    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18402 {
18403   rtx mask = GEN_INT (0x45);
18404   rtx val = GEN_INT (0x05);
18405
18406   rtx cond;
18407
18408   rtx scratch = gen_reg_rtx (HImode);
18409   rtx res = gen_reg_rtx (QImode);
18410
18411   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18412   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18413   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18414   cond = gen_rtx_fmt_ee (EQ, QImode,
18415                          gen_rtx_REG (CCmode, FLAGS_REG),
18416                          const0_rtx);
18417   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18418   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18419   DONE;
18420 })
18421
18422 (define_expand "signbit<mode>2"
18423   [(use (match_operand:SI 0 "register_operand" ""))
18424    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18425   "TARGET_USE_FANCY_MATH_387
18426    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18427 {
18428   rtx mask = GEN_INT (0x0200);
18429
18430   rtx scratch = gen_reg_rtx (HImode);
18431
18432   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18433   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18434   DONE;
18435 })
18436 \f
18437 ;; Block operation instructions
18438
18439 (define_expand "movmemsi"
18440   [(use (match_operand:BLK 0 "memory_operand" ""))
18441    (use (match_operand:BLK 1 "memory_operand" ""))
18442    (use (match_operand:SI 2 "nonmemory_operand" ""))
18443    (use (match_operand:SI 3 "const_int_operand" ""))
18444    (use (match_operand:SI 4 "const_int_operand" ""))
18445    (use (match_operand:SI 5 "const_int_operand" ""))]
18446   ""
18447 {
18448  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18449                          operands[4], operands[5]))
18450    DONE;
18451  else
18452    FAIL;
18453 })
18454
18455 (define_expand "movmemdi"
18456   [(use (match_operand:BLK 0 "memory_operand" ""))
18457    (use (match_operand:BLK 1 "memory_operand" ""))
18458    (use (match_operand:DI 2 "nonmemory_operand" ""))
18459    (use (match_operand:DI 3 "const_int_operand" ""))
18460    (use (match_operand:SI 4 "const_int_operand" ""))
18461    (use (match_operand:SI 5 "const_int_operand" ""))]
18462   "TARGET_64BIT"
18463 {
18464  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18465                          operands[4], operands[5]))
18466    DONE;
18467  else
18468    FAIL;
18469 })
18470
18471 ;; Most CPUs don't like single string operations
18472 ;; Handle this case here to simplify previous expander.
18473
18474 (define_expand "strmov"
18475   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18476    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18477    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18478               (clobber (reg:CC FLAGS_REG))])
18479    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18480               (clobber (reg:CC FLAGS_REG))])]
18481   ""
18482 {
18483   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18484
18485   /* If .md ever supports :P for Pmode, these can be directly
18486      in the pattern above.  */
18487   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18488   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18489
18490   /* Can't use this if the user has appropriated esi or edi.  */
18491   if ((TARGET_SINGLE_STRINGOP || optimize_size)
18492       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18493     {
18494       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18495                                       operands[2], operands[3],
18496                                       operands[5], operands[6]));
18497       DONE;
18498     }
18499
18500   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18501 })
18502
18503 (define_expand "strmov_singleop"
18504   [(parallel [(set (match_operand 1 "memory_operand" "")
18505                    (match_operand 3 "memory_operand" ""))
18506               (set (match_operand 0 "register_operand" "")
18507                    (match_operand 4 "" ""))
18508               (set (match_operand 2 "register_operand" "")
18509                    (match_operand 5 "" ""))])]
18510   "TARGET_SINGLE_STRINGOP || optimize_size"
18511   "")
18512
18513 (define_insn "*strmovdi_rex_1"
18514   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18515         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18516    (set (match_operand:DI 0 "register_operand" "=D")
18517         (plus:DI (match_dup 2)
18518                  (const_int 8)))
18519    (set (match_operand:DI 1 "register_operand" "=S")
18520         (plus:DI (match_dup 3)
18521                  (const_int 8)))]
18522   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18523   "movsq"
18524   [(set_attr "type" "str")
18525    (set_attr "mode" "DI")
18526    (set_attr "memory" "both")])
18527
18528 (define_insn "*strmovsi_1"
18529   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18530         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18531    (set (match_operand:SI 0 "register_operand" "=D")
18532         (plus:SI (match_dup 2)
18533                  (const_int 4)))
18534    (set (match_operand:SI 1 "register_operand" "=S")
18535         (plus:SI (match_dup 3)
18536                  (const_int 4)))]
18537   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18538   "{movsl|movsd}"
18539   [(set_attr "type" "str")
18540    (set_attr "mode" "SI")
18541    (set_attr "memory" "both")])
18542
18543 (define_insn "*strmovsi_rex_1"
18544   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18545         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18546    (set (match_operand:DI 0 "register_operand" "=D")
18547         (plus:DI (match_dup 2)
18548                  (const_int 4)))
18549    (set (match_operand:DI 1 "register_operand" "=S")
18550         (plus:DI (match_dup 3)
18551                  (const_int 4)))]
18552   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18553   "{movsl|movsd}"
18554   [(set_attr "type" "str")
18555    (set_attr "mode" "SI")
18556    (set_attr "memory" "both")])
18557
18558 (define_insn "*strmovhi_1"
18559   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18560         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18561    (set (match_operand:SI 0 "register_operand" "=D")
18562         (plus:SI (match_dup 2)
18563                  (const_int 2)))
18564    (set (match_operand:SI 1 "register_operand" "=S")
18565         (plus:SI (match_dup 3)
18566                  (const_int 2)))]
18567   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18568   "movsw"
18569   [(set_attr "type" "str")
18570    (set_attr "memory" "both")
18571    (set_attr "mode" "HI")])
18572
18573 (define_insn "*strmovhi_rex_1"
18574   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18575         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18576    (set (match_operand:DI 0 "register_operand" "=D")
18577         (plus:DI (match_dup 2)
18578                  (const_int 2)))
18579    (set (match_operand:DI 1 "register_operand" "=S")
18580         (plus:DI (match_dup 3)
18581                  (const_int 2)))]
18582   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18583   "movsw"
18584   [(set_attr "type" "str")
18585    (set_attr "memory" "both")
18586    (set_attr "mode" "HI")])
18587
18588 (define_insn "*strmovqi_1"
18589   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18590         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18591    (set (match_operand:SI 0 "register_operand" "=D")
18592         (plus:SI (match_dup 2)
18593                  (const_int 1)))
18594    (set (match_operand:SI 1 "register_operand" "=S")
18595         (plus:SI (match_dup 3)
18596                  (const_int 1)))]
18597   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18598   "movsb"
18599   [(set_attr "type" "str")
18600    (set_attr "memory" "both")
18601    (set_attr "mode" "QI")])
18602
18603 (define_insn "*strmovqi_rex_1"
18604   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18605         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18606    (set (match_operand:DI 0 "register_operand" "=D")
18607         (plus:DI (match_dup 2)
18608                  (const_int 1)))
18609    (set (match_operand:DI 1 "register_operand" "=S")
18610         (plus:DI (match_dup 3)
18611                  (const_int 1)))]
18612   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18613   "movsb"
18614   [(set_attr "type" "str")
18615    (set_attr "memory" "both")
18616    (set_attr "mode" "QI")])
18617
18618 (define_expand "rep_mov"
18619   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18620               (set (match_operand 0 "register_operand" "")
18621                    (match_operand 5 "" ""))
18622               (set (match_operand 2 "register_operand" "")
18623                    (match_operand 6 "" ""))
18624               (set (match_operand 1 "memory_operand" "")
18625                    (match_operand 3 "memory_operand" ""))
18626               (use (match_dup 4))])]
18627   ""
18628   "")
18629
18630 (define_insn "*rep_movdi_rex64"
18631   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18632    (set (match_operand:DI 0 "register_operand" "=D")
18633         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18634                             (const_int 3))
18635                  (match_operand:DI 3 "register_operand" "0")))
18636    (set (match_operand:DI 1 "register_operand" "=S")
18637         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18638                  (match_operand:DI 4 "register_operand" "1")))
18639    (set (mem:BLK (match_dup 3))
18640         (mem:BLK (match_dup 4)))
18641    (use (match_dup 5))]
18642   "TARGET_64BIT"
18643   "rep movsq"
18644   [(set_attr "type" "str")
18645    (set_attr "prefix_rep" "1")
18646    (set_attr "memory" "both")
18647    (set_attr "mode" "DI")])
18648
18649 (define_insn "*rep_movsi"
18650   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18651    (set (match_operand:SI 0 "register_operand" "=D")
18652         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18653                             (const_int 2))
18654                  (match_operand:SI 3 "register_operand" "0")))
18655    (set (match_operand:SI 1 "register_operand" "=S")
18656         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18657                  (match_operand:SI 4 "register_operand" "1")))
18658    (set (mem:BLK (match_dup 3))
18659         (mem:BLK (match_dup 4)))
18660    (use (match_dup 5))]
18661   "!TARGET_64BIT"
18662   "rep movs{l|d}"
18663   [(set_attr "type" "str")
18664    (set_attr "prefix_rep" "1")
18665    (set_attr "memory" "both")
18666    (set_attr "mode" "SI")])
18667
18668 (define_insn "*rep_movsi_rex64"
18669   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18670    (set (match_operand:DI 0 "register_operand" "=D")
18671         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18672                             (const_int 2))
18673                  (match_operand:DI 3 "register_operand" "0")))
18674    (set (match_operand:DI 1 "register_operand" "=S")
18675         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18676                  (match_operand:DI 4 "register_operand" "1")))
18677    (set (mem:BLK (match_dup 3))
18678         (mem:BLK (match_dup 4)))
18679    (use (match_dup 5))]
18680   "TARGET_64BIT"
18681   "rep movs{l|d}"
18682   [(set_attr "type" "str")
18683    (set_attr "prefix_rep" "1")
18684    (set_attr "memory" "both")
18685    (set_attr "mode" "SI")])
18686
18687 (define_insn "*rep_movqi"
18688   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18689    (set (match_operand:SI 0 "register_operand" "=D")
18690         (plus:SI (match_operand:SI 3 "register_operand" "0")
18691                  (match_operand:SI 5 "register_operand" "2")))
18692    (set (match_operand:SI 1 "register_operand" "=S")
18693         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18694    (set (mem:BLK (match_dup 3))
18695         (mem:BLK (match_dup 4)))
18696    (use (match_dup 5))]
18697   "!TARGET_64BIT"
18698   "rep movsb"
18699   [(set_attr "type" "str")
18700    (set_attr "prefix_rep" "1")
18701    (set_attr "memory" "both")
18702    (set_attr "mode" "SI")])
18703
18704 (define_insn "*rep_movqi_rex64"
18705   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18706    (set (match_operand:DI 0 "register_operand" "=D")
18707         (plus:DI (match_operand:DI 3 "register_operand" "0")
18708                  (match_operand:DI 5 "register_operand" "2")))
18709    (set (match_operand:DI 1 "register_operand" "=S")
18710         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18711    (set (mem:BLK (match_dup 3))
18712         (mem:BLK (match_dup 4)))
18713    (use (match_dup 5))]
18714   "TARGET_64BIT"
18715   "rep movsb"
18716   [(set_attr "type" "str")
18717    (set_attr "prefix_rep" "1")
18718    (set_attr "memory" "both")
18719    (set_attr "mode" "SI")])
18720
18721 (define_expand "setmemsi"
18722    [(use (match_operand:BLK 0 "memory_operand" ""))
18723     (use (match_operand:SI 1 "nonmemory_operand" ""))
18724     (use (match_operand 2 "const_int_operand" ""))
18725     (use (match_operand 3 "const_int_operand" ""))
18726     (use (match_operand:SI 4 "const_int_operand" ""))
18727     (use (match_operand:SI 5 "const_int_operand" ""))]
18728   ""
18729 {
18730  if (ix86_expand_setmem (operands[0], operands[1],
18731                          operands[2], operands[3],
18732                          operands[4], operands[5]))
18733    DONE;
18734  else
18735    FAIL;
18736 })
18737
18738 (define_expand "setmemdi"
18739    [(use (match_operand:BLK 0 "memory_operand" ""))
18740     (use (match_operand:DI 1 "nonmemory_operand" ""))
18741     (use (match_operand 2 "const_int_operand" ""))
18742     (use (match_operand 3 "const_int_operand" ""))
18743     (use (match_operand 4 "const_int_operand" ""))
18744     (use (match_operand 5 "const_int_operand" ""))]
18745   "TARGET_64BIT"
18746 {
18747  if (ix86_expand_setmem (operands[0], operands[1],
18748                          operands[2], operands[3],
18749                          operands[4], operands[5]))
18750    DONE;
18751  else
18752    FAIL;
18753 })
18754
18755 ;; Most CPUs don't like single string operations
18756 ;; Handle this case here to simplify previous expander.
18757
18758 (define_expand "strset"
18759   [(set (match_operand 1 "memory_operand" "")
18760         (match_operand 2 "register_operand" ""))
18761    (parallel [(set (match_operand 0 "register_operand" "")
18762                    (match_dup 3))
18763               (clobber (reg:CC FLAGS_REG))])]
18764   ""
18765 {
18766   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18767     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18768
18769   /* If .md ever supports :P for Pmode, this can be directly
18770      in the pattern above.  */
18771   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18772                               GEN_INT (GET_MODE_SIZE (GET_MODE
18773                                                       (operands[2]))));
18774   if (TARGET_SINGLE_STRINGOP || optimize_size)
18775     {
18776       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18777                                       operands[3]));
18778       DONE;
18779     }
18780 })
18781
18782 (define_expand "strset_singleop"
18783   [(parallel [(set (match_operand 1 "memory_operand" "")
18784                    (match_operand 2 "register_operand" ""))
18785               (set (match_operand 0 "register_operand" "")
18786                    (match_operand 3 "" ""))])]
18787   "TARGET_SINGLE_STRINGOP || optimize_size"
18788   "")
18789
18790 (define_insn "*strsetdi_rex_1"
18791   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18792         (match_operand:DI 2 "register_operand" "a"))
18793    (set (match_operand:DI 0 "register_operand" "=D")
18794         (plus:DI (match_dup 1)
18795                  (const_int 8)))]
18796   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18797   "stosq"
18798   [(set_attr "type" "str")
18799    (set_attr "memory" "store")
18800    (set_attr "mode" "DI")])
18801
18802 (define_insn "*strsetsi_1"
18803   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18804         (match_operand:SI 2 "register_operand" "a"))
18805    (set (match_operand:SI 0 "register_operand" "=D")
18806         (plus:SI (match_dup 1)
18807                  (const_int 4)))]
18808   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18809   "{stosl|stosd}"
18810   [(set_attr "type" "str")
18811    (set_attr "memory" "store")
18812    (set_attr "mode" "SI")])
18813
18814 (define_insn "*strsetsi_rex_1"
18815   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18816         (match_operand:SI 2 "register_operand" "a"))
18817    (set (match_operand:DI 0 "register_operand" "=D")
18818         (plus:DI (match_dup 1)
18819                  (const_int 4)))]
18820   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18821   "{stosl|stosd}"
18822   [(set_attr "type" "str")
18823    (set_attr "memory" "store")
18824    (set_attr "mode" "SI")])
18825
18826 (define_insn "*strsethi_1"
18827   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18828         (match_operand:HI 2 "register_operand" "a"))
18829    (set (match_operand:SI 0 "register_operand" "=D")
18830         (plus:SI (match_dup 1)
18831                  (const_int 2)))]
18832   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18833   "stosw"
18834   [(set_attr "type" "str")
18835    (set_attr "memory" "store")
18836    (set_attr "mode" "HI")])
18837
18838 (define_insn "*strsethi_rex_1"
18839   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18840         (match_operand:HI 2 "register_operand" "a"))
18841    (set (match_operand:DI 0 "register_operand" "=D")
18842         (plus:DI (match_dup 1)
18843                  (const_int 2)))]
18844   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18845   "stosw"
18846   [(set_attr "type" "str")
18847    (set_attr "memory" "store")
18848    (set_attr "mode" "HI")])
18849
18850 (define_insn "*strsetqi_1"
18851   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18852         (match_operand:QI 2 "register_operand" "a"))
18853    (set (match_operand:SI 0 "register_operand" "=D")
18854         (plus:SI (match_dup 1)
18855                  (const_int 1)))]
18856   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18857   "stosb"
18858   [(set_attr "type" "str")
18859    (set_attr "memory" "store")
18860    (set_attr "mode" "QI")])
18861
18862 (define_insn "*strsetqi_rex_1"
18863   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18864         (match_operand:QI 2 "register_operand" "a"))
18865    (set (match_operand:DI 0 "register_operand" "=D")
18866         (plus:DI (match_dup 1)
18867                  (const_int 1)))]
18868   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18869   "stosb"
18870   [(set_attr "type" "str")
18871    (set_attr "memory" "store")
18872    (set_attr "mode" "QI")])
18873
18874 (define_expand "rep_stos"
18875   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18876               (set (match_operand 0 "register_operand" "")
18877                    (match_operand 4 "" ""))
18878               (set (match_operand 2 "memory_operand" "") (const_int 0))
18879               (use (match_operand 3 "register_operand" ""))
18880               (use (match_dup 1))])]
18881   ""
18882   "")
18883
18884 (define_insn "*rep_stosdi_rex64"
18885   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18886    (set (match_operand:DI 0 "register_operand" "=D")
18887         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18888                             (const_int 3))
18889                  (match_operand:DI 3 "register_operand" "0")))
18890    (set (mem:BLK (match_dup 3))
18891         (const_int 0))
18892    (use (match_operand:DI 2 "register_operand" "a"))
18893    (use (match_dup 4))]
18894   "TARGET_64BIT"
18895   "rep stosq"
18896   [(set_attr "type" "str")
18897    (set_attr "prefix_rep" "1")
18898    (set_attr "memory" "store")
18899    (set_attr "mode" "DI")])
18900
18901 (define_insn "*rep_stossi"
18902   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18903    (set (match_operand:SI 0 "register_operand" "=D")
18904         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18905                             (const_int 2))
18906                  (match_operand:SI 3 "register_operand" "0")))
18907    (set (mem:BLK (match_dup 3))
18908         (const_int 0))
18909    (use (match_operand:SI 2 "register_operand" "a"))
18910    (use (match_dup 4))]
18911   "!TARGET_64BIT"
18912   "rep stos{l|d}"
18913   [(set_attr "type" "str")
18914    (set_attr "prefix_rep" "1")
18915    (set_attr "memory" "store")
18916    (set_attr "mode" "SI")])
18917
18918 (define_insn "*rep_stossi_rex64"
18919   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18920    (set (match_operand:DI 0 "register_operand" "=D")
18921         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18922                             (const_int 2))
18923                  (match_operand:DI 3 "register_operand" "0")))
18924    (set (mem:BLK (match_dup 3))
18925         (const_int 0))
18926    (use (match_operand:SI 2 "register_operand" "a"))
18927    (use (match_dup 4))]
18928   "TARGET_64BIT"
18929   "rep stos{l|d}"
18930   [(set_attr "type" "str")
18931    (set_attr "prefix_rep" "1")
18932    (set_attr "memory" "store")
18933    (set_attr "mode" "SI")])
18934
18935 (define_insn "*rep_stosqi"
18936   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18937    (set (match_operand:SI 0 "register_operand" "=D")
18938         (plus:SI (match_operand:SI 3 "register_operand" "0")
18939                  (match_operand:SI 4 "register_operand" "1")))
18940    (set (mem:BLK (match_dup 3))
18941         (const_int 0))
18942    (use (match_operand:QI 2 "register_operand" "a"))
18943    (use (match_dup 4))]
18944   "!TARGET_64BIT"
18945   "rep stosb"
18946   [(set_attr "type" "str")
18947    (set_attr "prefix_rep" "1")
18948    (set_attr "memory" "store")
18949    (set_attr "mode" "QI")])
18950
18951 (define_insn "*rep_stosqi_rex64"
18952   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18953    (set (match_operand:DI 0 "register_operand" "=D")
18954         (plus:DI (match_operand:DI 3 "register_operand" "0")
18955                  (match_operand:DI 4 "register_operand" "1")))
18956    (set (mem:BLK (match_dup 3))
18957         (const_int 0))
18958    (use (match_operand:QI 2 "register_operand" "a"))
18959    (use (match_dup 4))]
18960   "TARGET_64BIT"
18961   "rep stosb"
18962   [(set_attr "type" "str")
18963    (set_attr "prefix_rep" "1")
18964    (set_attr "memory" "store")
18965    (set_attr "mode" "QI")])
18966
18967 (define_expand "cmpstrnsi"
18968   [(set (match_operand:SI 0 "register_operand" "")
18969         (compare:SI (match_operand:BLK 1 "general_operand" "")
18970                     (match_operand:BLK 2 "general_operand" "")))
18971    (use (match_operand 3 "general_operand" ""))
18972    (use (match_operand 4 "immediate_operand" ""))]
18973   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18974 {
18975   rtx addr1, addr2, out, outlow, count, countreg, align;
18976
18977   /* Can't use this if the user has appropriated esi or edi.  */
18978   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18979     FAIL;
18980
18981   out = operands[0];
18982   if (!REG_P (out))
18983     out = gen_reg_rtx (SImode);
18984
18985   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18986   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18987   if (addr1 != XEXP (operands[1], 0))
18988     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18989   if (addr2 != XEXP (operands[2], 0))
18990     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18991
18992   count = operands[3];
18993   countreg = ix86_zero_extend_to_Pmode (count);
18994
18995   /* %%% Iff we are testing strict equality, we can use known alignment
18996      to good advantage.  This may be possible with combine, particularly
18997      once cc0 is dead.  */
18998   align = operands[4];
18999
19000   if (CONST_INT_P (count))
19001     {
19002       if (INTVAL (count) == 0)
19003         {
19004           emit_move_insn (operands[0], const0_rtx);
19005           DONE;
19006         }
19007       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19008                                      operands[1], operands[2]));
19009     }
19010   else
19011     {
19012       if (TARGET_64BIT)
19013         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19014       else
19015         emit_insn (gen_cmpsi_1 (countreg, countreg));
19016       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19017                                   operands[1], operands[2]));
19018     }
19019
19020   outlow = gen_lowpart (QImode, out);
19021   emit_insn (gen_cmpintqi (outlow));
19022   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19023
19024   if (operands[0] != out)
19025     emit_move_insn (operands[0], out);
19026
19027   DONE;
19028 })
19029
19030 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19031
19032 (define_expand "cmpintqi"
19033   [(set (match_dup 1)
19034         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19035    (set (match_dup 2)
19036         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19037    (parallel [(set (match_operand:QI 0 "register_operand" "")
19038                    (minus:QI (match_dup 1)
19039                              (match_dup 2)))
19040               (clobber (reg:CC FLAGS_REG))])]
19041   ""
19042   "operands[1] = gen_reg_rtx (QImode);
19043    operands[2] = gen_reg_rtx (QImode);")
19044
19045 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
19046 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
19047
19048 (define_expand "cmpstrnqi_nz_1"
19049   [(parallel [(set (reg:CC FLAGS_REG)
19050                    (compare:CC (match_operand 4 "memory_operand" "")
19051                                (match_operand 5 "memory_operand" "")))
19052               (use (match_operand 2 "register_operand" ""))
19053               (use (match_operand:SI 3 "immediate_operand" ""))
19054               (clobber (match_operand 0 "register_operand" ""))
19055               (clobber (match_operand 1 "register_operand" ""))
19056               (clobber (match_dup 2))])]
19057   ""
19058   "")
19059
19060 (define_insn "*cmpstrnqi_nz_1"
19061   [(set (reg:CC FLAGS_REG)
19062         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19063                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19064    (use (match_operand:SI 6 "register_operand" "2"))
19065    (use (match_operand:SI 3 "immediate_operand" "i"))
19066    (clobber (match_operand:SI 0 "register_operand" "=S"))
19067    (clobber (match_operand:SI 1 "register_operand" "=D"))
19068    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19069   "!TARGET_64BIT"
19070   "repz cmpsb"
19071   [(set_attr "type" "str")
19072    (set_attr "mode" "QI")
19073    (set_attr "prefix_rep" "1")])
19074
19075 (define_insn "*cmpstrnqi_nz_rex_1"
19076   [(set (reg:CC FLAGS_REG)
19077         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19078                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19079    (use (match_operand:DI 6 "register_operand" "2"))
19080    (use (match_operand:SI 3 "immediate_operand" "i"))
19081    (clobber (match_operand:DI 0 "register_operand" "=S"))
19082    (clobber (match_operand:DI 1 "register_operand" "=D"))
19083    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19084   "TARGET_64BIT"
19085   "repz cmpsb"
19086   [(set_attr "type" "str")
19087    (set_attr "mode" "QI")
19088    (set_attr "prefix_rep" "1")])
19089
19090 ;; The same, but the count is not known to not be zero.
19091
19092 (define_expand "cmpstrnqi_1"
19093   [(parallel [(set (reg:CC FLAGS_REG)
19094                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19095                                      (const_int 0))
19096                   (compare:CC (match_operand 4 "memory_operand" "")
19097                               (match_operand 5 "memory_operand" ""))
19098                   (const_int 0)))
19099               (use (match_operand:SI 3 "immediate_operand" ""))
19100               (use (reg:CC FLAGS_REG))
19101               (clobber (match_operand 0 "register_operand" ""))
19102               (clobber (match_operand 1 "register_operand" ""))
19103               (clobber (match_dup 2))])]
19104   ""
19105   "")
19106
19107 (define_insn "*cmpstrnqi_1"
19108   [(set (reg:CC FLAGS_REG)
19109         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19110                              (const_int 0))
19111           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19112                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19113           (const_int 0)))
19114    (use (match_operand:SI 3 "immediate_operand" "i"))
19115    (use (reg:CC FLAGS_REG))
19116    (clobber (match_operand:SI 0 "register_operand" "=S"))
19117    (clobber (match_operand:SI 1 "register_operand" "=D"))
19118    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19119   "!TARGET_64BIT"
19120   "repz cmpsb"
19121   [(set_attr "type" "str")
19122    (set_attr "mode" "QI")
19123    (set_attr "prefix_rep" "1")])
19124
19125 (define_insn "*cmpstrnqi_rex_1"
19126   [(set (reg:CC FLAGS_REG)
19127         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19128                              (const_int 0))
19129           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19130                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19131           (const_int 0)))
19132    (use (match_operand:SI 3 "immediate_operand" "i"))
19133    (use (reg:CC FLAGS_REG))
19134    (clobber (match_operand:DI 0 "register_operand" "=S"))
19135    (clobber (match_operand:DI 1 "register_operand" "=D"))
19136    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19137   "TARGET_64BIT"
19138   "repz cmpsb"
19139   [(set_attr "type" "str")
19140    (set_attr "mode" "QI")
19141    (set_attr "prefix_rep" "1")])
19142
19143 (define_expand "strlensi"
19144   [(set (match_operand:SI 0 "register_operand" "")
19145         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19146                     (match_operand:QI 2 "immediate_operand" "")
19147                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19148   ""
19149 {
19150  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19151    DONE;
19152  else
19153    FAIL;
19154 })
19155
19156 (define_expand "strlendi"
19157   [(set (match_operand:DI 0 "register_operand" "")
19158         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19159                     (match_operand:QI 2 "immediate_operand" "")
19160                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19161   ""
19162 {
19163  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19164    DONE;
19165  else
19166    FAIL;
19167 })
19168
19169 (define_expand "strlenqi_1"
19170   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19171               (clobber (match_operand 1 "register_operand" ""))
19172               (clobber (reg:CC FLAGS_REG))])]
19173   ""
19174   "")
19175
19176 (define_insn "*strlenqi_1"
19177   [(set (match_operand:SI 0 "register_operand" "=&c")
19178         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19179                     (match_operand:QI 2 "register_operand" "a")
19180                     (match_operand:SI 3 "immediate_operand" "i")
19181                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19182    (clobber (match_operand:SI 1 "register_operand" "=D"))
19183    (clobber (reg:CC FLAGS_REG))]
19184   "!TARGET_64BIT"
19185   "repnz scasb"
19186   [(set_attr "type" "str")
19187    (set_attr "mode" "QI")
19188    (set_attr "prefix_rep" "1")])
19189
19190 (define_insn "*strlenqi_rex_1"
19191   [(set (match_operand:DI 0 "register_operand" "=&c")
19192         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19193                     (match_operand:QI 2 "register_operand" "a")
19194                     (match_operand:DI 3 "immediate_operand" "i")
19195                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19196    (clobber (match_operand:DI 1 "register_operand" "=D"))
19197    (clobber (reg:CC FLAGS_REG))]
19198   "TARGET_64BIT"
19199   "repnz scasb"
19200   [(set_attr "type" "str")
19201    (set_attr "mode" "QI")
19202    (set_attr "prefix_rep" "1")])
19203
19204 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19205 ;; handled in combine, but it is not currently up to the task.
19206 ;; When used for their truth value, the cmpstrn* expanders generate
19207 ;; code like this:
19208 ;;
19209 ;;   repz cmpsb
19210 ;;   seta       %al
19211 ;;   setb       %dl
19212 ;;   cmpb       %al, %dl
19213 ;;   jcc        label
19214 ;;
19215 ;; The intermediate three instructions are unnecessary.
19216
19217 ;; This one handles cmpstrn*_nz_1...
19218 (define_peephole2
19219   [(parallel[
19220      (set (reg:CC FLAGS_REG)
19221           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19222                       (mem:BLK (match_operand 5 "register_operand" ""))))
19223      (use (match_operand 6 "register_operand" ""))
19224      (use (match_operand:SI 3 "immediate_operand" ""))
19225      (clobber (match_operand 0 "register_operand" ""))
19226      (clobber (match_operand 1 "register_operand" ""))
19227      (clobber (match_operand 2 "register_operand" ""))])
19228    (set (match_operand:QI 7 "register_operand" "")
19229         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19230    (set (match_operand:QI 8 "register_operand" "")
19231         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19232    (set (reg FLAGS_REG)
19233         (compare (match_dup 7) (match_dup 8)))
19234   ]
19235   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19236   [(parallel[
19237      (set (reg:CC FLAGS_REG)
19238           (compare:CC (mem:BLK (match_dup 4))
19239                       (mem:BLK (match_dup 5))))
19240      (use (match_dup 6))
19241      (use (match_dup 3))
19242      (clobber (match_dup 0))
19243      (clobber (match_dup 1))
19244      (clobber (match_dup 2))])]
19245   "")
19246
19247 ;; ...and this one handles cmpstrn*_1.
19248 (define_peephole2
19249   [(parallel[
19250      (set (reg:CC FLAGS_REG)
19251           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19252                                (const_int 0))
19253             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19254                         (mem:BLK (match_operand 5 "register_operand" "")))
19255             (const_int 0)))
19256      (use (match_operand:SI 3 "immediate_operand" ""))
19257      (use (reg:CC FLAGS_REG))
19258      (clobber (match_operand 0 "register_operand" ""))
19259      (clobber (match_operand 1 "register_operand" ""))
19260      (clobber (match_operand 2 "register_operand" ""))])
19261    (set (match_operand:QI 7 "register_operand" "")
19262         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19263    (set (match_operand:QI 8 "register_operand" "")
19264         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19265    (set (reg FLAGS_REG)
19266         (compare (match_dup 7) (match_dup 8)))
19267   ]
19268   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19269   [(parallel[
19270      (set (reg:CC FLAGS_REG)
19271           (if_then_else:CC (ne (match_dup 6)
19272                                (const_int 0))
19273             (compare:CC (mem:BLK (match_dup 4))
19274                         (mem:BLK (match_dup 5)))
19275             (const_int 0)))
19276      (use (match_dup 3))
19277      (use (reg:CC FLAGS_REG))
19278      (clobber (match_dup 0))
19279      (clobber (match_dup 1))
19280      (clobber (match_dup 2))])]
19281   "")
19282
19283
19284 \f
19285 ;; Conditional move instructions.
19286
19287 (define_expand "movdicc"
19288   [(set (match_operand:DI 0 "register_operand" "")
19289         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19290                          (match_operand:DI 2 "general_operand" "")
19291                          (match_operand:DI 3 "general_operand" "")))]
19292   "TARGET_64BIT"
19293   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19294
19295 (define_insn "x86_movdicc_0_m1_rex64"
19296   [(set (match_operand:DI 0 "register_operand" "=r")
19297         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19298           (const_int -1)
19299           (const_int 0)))
19300    (clobber (reg:CC FLAGS_REG))]
19301   "TARGET_64BIT"
19302   "sbb{q}\t%0, %0"
19303   ; Since we don't have the proper number of operands for an alu insn,
19304   ; fill in all the blanks.
19305   [(set_attr "type" "alu")
19306    (set_attr "pent_pair" "pu")
19307    (set_attr "memory" "none")
19308    (set_attr "imm_disp" "false")
19309    (set_attr "mode" "DI")
19310    (set_attr "length_immediate" "0")])
19311
19312 (define_insn "*x86_movdicc_0_m1_se"
19313   [(set (match_operand:DI 0 "register_operand" "=r")
19314         (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19315                          (const_int 1)
19316                          (const_int 0)))
19317    (clobber (reg:CC FLAGS_REG))]
19318   ""
19319   "sbb{q}\t%0, %0"
19320   [(set_attr "type" "alu")
19321    (set_attr "pent_pair" "pu")
19322    (set_attr "memory" "none")
19323    (set_attr "imm_disp" "false")
19324    (set_attr "mode" "DI")
19325    (set_attr "length_immediate" "0")])
19326
19327 (define_insn "*movdicc_c_rex64"
19328   [(set (match_operand:DI 0 "register_operand" "=r,r")
19329         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19330                                 [(reg FLAGS_REG) (const_int 0)])
19331                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19332                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19333   "TARGET_64BIT && TARGET_CMOVE
19334    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19335   "@
19336    cmov%O2%C1\t{%2, %0|%0, %2}
19337    cmov%O2%c1\t{%3, %0|%0, %3}"
19338   [(set_attr "type" "icmov")
19339    (set_attr "mode" "DI")])
19340
19341 (define_expand "movsicc"
19342   [(set (match_operand:SI 0 "register_operand" "")
19343         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19344                          (match_operand:SI 2 "general_operand" "")
19345                          (match_operand:SI 3 "general_operand" "")))]
19346   ""
19347   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19348
19349 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19350 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19351 ;; So just document what we're doing explicitly.
19352
19353 (define_insn "x86_movsicc_0_m1"
19354   [(set (match_operand:SI 0 "register_operand" "=r")
19355         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19356           (const_int -1)
19357           (const_int 0)))
19358    (clobber (reg:CC FLAGS_REG))]
19359   ""
19360   "sbb{l}\t%0, %0"
19361   ; Since we don't have the proper number of operands for an alu insn,
19362   ; fill in all the blanks.
19363   [(set_attr "type" "alu")
19364    (set_attr "pent_pair" "pu")
19365    (set_attr "memory" "none")
19366    (set_attr "imm_disp" "false")
19367    (set_attr "mode" "SI")
19368    (set_attr "length_immediate" "0")])
19369
19370 (define_insn "*x86_movsicc_0_m1_se"
19371   [(set (match_operand:SI 0 "register_operand" "=r")
19372         (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19373                          (const_int 1)
19374                          (const_int 0)))
19375    (clobber (reg:CC FLAGS_REG))]
19376   ""
19377   "sbb{l}\t%0, %0"
19378   [(set_attr "type" "alu")
19379    (set_attr "pent_pair" "pu")
19380    (set_attr "memory" "none")
19381    (set_attr "imm_disp" "false")
19382    (set_attr "mode" "SI")
19383    (set_attr "length_immediate" "0")])
19384
19385 (define_insn "*movsicc_noc"
19386   [(set (match_operand:SI 0 "register_operand" "=r,r")
19387         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19388                                 [(reg FLAGS_REG) (const_int 0)])
19389                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19390                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19391   "TARGET_CMOVE
19392    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19393   "@
19394    cmov%O2%C1\t{%2, %0|%0, %2}
19395    cmov%O2%c1\t{%3, %0|%0, %3}"
19396   [(set_attr "type" "icmov")
19397    (set_attr "mode" "SI")])
19398
19399 (define_expand "movhicc"
19400   [(set (match_operand:HI 0 "register_operand" "")
19401         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19402                          (match_operand:HI 2 "general_operand" "")
19403                          (match_operand:HI 3 "general_operand" "")))]
19404   "TARGET_HIMODE_MATH"
19405   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19406
19407 (define_insn "*movhicc_noc"
19408   [(set (match_operand:HI 0 "register_operand" "=r,r")
19409         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19410                                 [(reg FLAGS_REG) (const_int 0)])
19411                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19412                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19413   "TARGET_CMOVE
19414    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19415   "@
19416    cmov%O2%C1\t{%2, %0|%0, %2}
19417    cmov%O2%c1\t{%3, %0|%0, %3}"
19418   [(set_attr "type" "icmov")
19419    (set_attr "mode" "HI")])
19420
19421 (define_expand "movqicc"
19422   [(set (match_operand:QI 0 "register_operand" "")
19423         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19424                          (match_operand:QI 2 "general_operand" "")
19425                          (match_operand:QI 3 "general_operand" "")))]
19426   "TARGET_QIMODE_MATH"
19427   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19428
19429 (define_insn_and_split "*movqicc_noc"
19430   [(set (match_operand:QI 0 "register_operand" "=r,r")
19431         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19432                                 [(match_operand 4 "flags_reg_operand" "")
19433                                  (const_int 0)])
19434                       (match_operand:QI 2 "register_operand" "r,0")
19435                       (match_operand:QI 3 "register_operand" "0,r")))]
19436   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19437   "#"
19438   "&& reload_completed"
19439   [(set (match_dup 0)
19440         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19441                       (match_dup 2)
19442                       (match_dup 3)))]
19443   "operands[0] = gen_lowpart (SImode, operands[0]);
19444    operands[2] = gen_lowpart (SImode, operands[2]);
19445    operands[3] = gen_lowpart (SImode, operands[3]);"
19446   [(set_attr "type" "icmov")
19447    (set_attr "mode" "SI")])
19448
19449 (define_expand "mov<mode>cc"
19450   [(set (match_operand:X87MODEF 0 "register_operand" "")
19451         (if_then_else:X87MODEF
19452           (match_operand 1 "comparison_operator" "")
19453           (match_operand:X87MODEF 2 "register_operand" "")
19454           (match_operand:X87MODEF 3 "register_operand" "")))]
19455   "(TARGET_80387 && TARGET_CMOVE)
19456    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19457   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19458
19459 (define_insn "*movsfcc_1_387"
19460   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19461         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19462                                 [(reg FLAGS_REG) (const_int 0)])
19463                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19464                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19465   "TARGET_80387 && TARGET_CMOVE
19466    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19467   "@
19468    fcmov%F1\t{%2, %0|%0, %2}
19469    fcmov%f1\t{%3, %0|%0, %3}
19470    cmov%O2%C1\t{%2, %0|%0, %2}
19471    cmov%O2%c1\t{%3, %0|%0, %3}"
19472   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19473    (set_attr "mode" "SF,SF,SI,SI")])
19474
19475 (define_insn "*movdfcc_1"
19476   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19477         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19478                                 [(reg FLAGS_REG) (const_int 0)])
19479                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19480                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19481   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19482    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19483   "@
19484    fcmov%F1\t{%2, %0|%0, %2}
19485    fcmov%f1\t{%3, %0|%0, %3}
19486    #
19487    #"
19488   [(set_attr "type" "fcmov,fcmov,multi,multi")
19489    (set_attr "mode" "DF")])
19490
19491 (define_insn "*movdfcc_1_rex64"
19492   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19493         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19494                                 [(reg FLAGS_REG) (const_int 0)])
19495                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19496                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19497   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19498    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19499   "@
19500    fcmov%F1\t{%2, %0|%0, %2}
19501    fcmov%f1\t{%3, %0|%0, %3}
19502    cmov%O2%C1\t{%2, %0|%0, %2}
19503    cmov%O2%c1\t{%3, %0|%0, %3}"
19504   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19505    (set_attr "mode" "DF")])
19506
19507 (define_split
19508   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19509         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19510                                 [(match_operand 4 "flags_reg_operand" "")
19511                                  (const_int 0)])
19512                       (match_operand:DF 2 "nonimmediate_operand" "")
19513                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19514   "!TARGET_64BIT && reload_completed"
19515   [(set (match_dup 2)
19516         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19517                       (match_dup 5)
19518                       (match_dup 7)))
19519    (set (match_dup 3)
19520         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19521                       (match_dup 6)
19522                       (match_dup 8)))]
19523   "split_di (operands+2, 1, operands+5, operands+6);
19524    split_di (operands+3, 1, operands+7, operands+8);
19525    split_di (operands, 1, operands+2, operands+3);")
19526
19527 (define_insn "*movxfcc_1"
19528   [(set (match_operand:XF 0 "register_operand" "=f,f")
19529         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19530                                 [(reg FLAGS_REG) (const_int 0)])
19531                       (match_operand:XF 2 "register_operand" "f,0")
19532                       (match_operand:XF 3 "register_operand" "0,f")))]
19533   "TARGET_80387 && TARGET_CMOVE"
19534   "@
19535    fcmov%F1\t{%2, %0|%0, %2}
19536    fcmov%f1\t{%3, %0|%0, %3}"
19537   [(set_attr "type" "fcmov")
19538    (set_attr "mode" "XF")])
19539
19540 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19541 ;; the scalar versions to have only XMM registers as operands.
19542
19543 ;; SSE5 conditional move
19544 (define_insn "*sse5_pcmov_<mode>"
19545   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19546         (if_then_else:MODEF
19547           (match_operand:MODEF 1 "register_operand" "x,0")
19548           (match_operand:MODEF 2 "register_operand" "0,x")
19549           (match_operand:MODEF 3 "register_operand" "x,x")))]
19550   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19551   "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19552   [(set_attr "type" "sse4arg")])
19553
19554 ;; These versions of the min/max patterns are intentionally ignorant of
19555 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19556 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19557 ;; are undefined in this condition, we're certain this is correct.
19558
19559 (define_insn "<code><mode>3"
19560   [(set (match_operand:MODEF 0 "register_operand" "=x")
19561         (smaxmin:MODEF
19562           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19563           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19564   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19565   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19566   [(set_attr "type" "sseadd")
19567    (set_attr "mode" "<MODE>")])
19568
19569 ;; These versions of the min/max patterns implement exactly the operations
19570 ;;   min = (op1 < op2 ? op1 : op2)
19571 ;;   max = (!(op1 < op2) ? op1 : op2)
19572 ;; Their operands are not commutative, and thus they may be used in the
19573 ;; presence of -0.0 and NaN.
19574
19575 (define_insn "*ieee_smin<mode>3"
19576   [(set (match_operand:MODEF 0 "register_operand" "=x")
19577         (unspec:MODEF
19578           [(match_operand:MODEF 1 "register_operand" "0")
19579            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19580          UNSPEC_IEEE_MIN))]
19581   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19582   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19583   [(set_attr "type" "sseadd")
19584    (set_attr "mode" "<MODE>")])
19585
19586 (define_insn "*ieee_smax<mode>3"
19587   [(set (match_operand:MODEF 0 "register_operand" "=x")
19588         (unspec:MODEF
19589           [(match_operand:MODEF 1 "register_operand" "0")
19590            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19591          UNSPEC_IEEE_MAX))]
19592   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19593   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19594   [(set_attr "type" "sseadd")
19595    (set_attr "mode" "<MODE>")])
19596
19597 ;; Make two stack loads independent:
19598 ;;   fld aa              fld aa
19599 ;;   fld %st(0)     ->   fld bb
19600 ;;   fmul bb             fmul %st(1), %st
19601 ;;
19602 ;; Actually we only match the last two instructions for simplicity.
19603 (define_peephole2
19604   [(set (match_operand 0 "fp_register_operand" "")
19605         (match_operand 1 "fp_register_operand" ""))
19606    (set (match_dup 0)
19607         (match_operator 2 "binary_fp_operator"
19608            [(match_dup 0)
19609             (match_operand 3 "memory_operand" "")]))]
19610   "REGNO (operands[0]) != REGNO (operands[1])"
19611   [(set (match_dup 0) (match_dup 3))
19612    (set (match_dup 0) (match_dup 4))]
19613
19614   ;; The % modifier is not operational anymore in peephole2's, so we have to
19615   ;; swap the operands manually in the case of addition and multiplication.
19616   "if (COMMUTATIVE_ARITH_P (operands[2]))
19617      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19618                                  operands[0], operands[1]);
19619    else
19620      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19621                                  operands[1], operands[0]);")
19622
19623 ;; Conditional addition patterns
19624 (define_expand "addqicc"
19625   [(match_operand:QI 0 "register_operand" "")
19626    (match_operand 1 "comparison_operator" "")
19627    (match_operand:QI 2 "register_operand" "")
19628    (match_operand:QI 3 "const_int_operand" "")]
19629   ""
19630   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19631
19632 (define_expand "addhicc"
19633   [(match_operand:HI 0 "register_operand" "")
19634    (match_operand 1 "comparison_operator" "")
19635    (match_operand:HI 2 "register_operand" "")
19636    (match_operand:HI 3 "const_int_operand" "")]
19637   ""
19638   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19639
19640 (define_expand "addsicc"
19641   [(match_operand:SI 0 "register_operand" "")
19642    (match_operand 1 "comparison_operator" "")
19643    (match_operand:SI 2 "register_operand" "")
19644    (match_operand:SI 3 "const_int_operand" "")]
19645   ""
19646   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19647
19648 (define_expand "adddicc"
19649   [(match_operand:DI 0 "register_operand" "")
19650    (match_operand 1 "comparison_operator" "")
19651    (match_operand:DI 2 "register_operand" "")
19652    (match_operand:DI 3 "const_int_operand" "")]
19653   "TARGET_64BIT"
19654   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19655
19656 \f
19657 ;; Misc patterns (?)
19658
19659 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19660 ;; Otherwise there will be nothing to keep
19661 ;;
19662 ;; [(set (reg ebp) (reg esp))]
19663 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19664 ;;  (clobber (eflags)]
19665 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19666 ;;
19667 ;; in proper program order.
19668 (define_insn "pro_epilogue_adjust_stack_1"
19669   [(set (match_operand:SI 0 "register_operand" "=r,r")
19670         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19671                  (match_operand:SI 2 "immediate_operand" "i,i")))
19672    (clobber (reg:CC FLAGS_REG))
19673    (clobber (mem:BLK (scratch)))]
19674   "!TARGET_64BIT"
19675 {
19676   switch (get_attr_type (insn))
19677     {
19678     case TYPE_IMOV:
19679       return "mov{l}\t{%1, %0|%0, %1}";
19680
19681     case TYPE_ALU:
19682       if (CONST_INT_P (operands[2])
19683           && (INTVAL (operands[2]) == 128
19684               || (INTVAL (operands[2]) < 0
19685                   && INTVAL (operands[2]) != -128)))
19686         {
19687           operands[2] = GEN_INT (-INTVAL (operands[2]));
19688           return "sub{l}\t{%2, %0|%0, %2}";
19689         }
19690       return "add{l}\t{%2, %0|%0, %2}";
19691
19692     case TYPE_LEA:
19693       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19694       return "lea{l}\t{%a2, %0|%0, %a2}";
19695
19696     default:
19697       gcc_unreachable ();
19698     }
19699 }
19700   [(set (attr "type")
19701         (cond [(eq_attr "alternative" "0")
19702                  (const_string "alu")
19703                (match_operand:SI 2 "const0_operand" "")
19704                  (const_string "imov")
19705               ]
19706               (const_string "lea")))
19707    (set_attr "mode" "SI")])
19708
19709 (define_insn "pro_epilogue_adjust_stack_rex64"
19710   [(set (match_operand:DI 0 "register_operand" "=r,r")
19711         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19712                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19713    (clobber (reg:CC FLAGS_REG))
19714    (clobber (mem:BLK (scratch)))]
19715   "TARGET_64BIT"
19716 {
19717   switch (get_attr_type (insn))
19718     {
19719     case TYPE_IMOV:
19720       return "mov{q}\t{%1, %0|%0, %1}";
19721
19722     case TYPE_ALU:
19723       if (CONST_INT_P (operands[2])
19724           /* Avoid overflows.  */
19725           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19726           && (INTVAL (operands[2]) == 128
19727               || (INTVAL (operands[2]) < 0
19728                   && INTVAL (operands[2]) != -128)))
19729         {
19730           operands[2] = GEN_INT (-INTVAL (operands[2]));
19731           return "sub{q}\t{%2, %0|%0, %2}";
19732         }
19733       return "add{q}\t{%2, %0|%0, %2}";
19734
19735     case TYPE_LEA:
19736       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19737       return "lea{q}\t{%a2, %0|%0, %a2}";
19738
19739     default:
19740       gcc_unreachable ();
19741     }
19742 }
19743   [(set (attr "type")
19744         (cond [(eq_attr "alternative" "0")
19745                  (const_string "alu")
19746                (match_operand:DI 2 "const0_operand" "")
19747                  (const_string "imov")
19748               ]
19749               (const_string "lea")))
19750    (set_attr "mode" "DI")])
19751
19752 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19753   [(set (match_operand:DI 0 "register_operand" "=r,r")
19754         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19755                  (match_operand:DI 3 "immediate_operand" "i,i")))
19756    (use (match_operand:DI 2 "register_operand" "r,r"))
19757    (clobber (reg:CC FLAGS_REG))
19758    (clobber (mem:BLK (scratch)))]
19759   "TARGET_64BIT"
19760 {
19761   switch (get_attr_type (insn))
19762     {
19763     case TYPE_ALU:
19764       return "add{q}\t{%2, %0|%0, %2}";
19765
19766     case TYPE_LEA:
19767       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19768       return "lea{q}\t{%a2, %0|%0, %a2}";
19769
19770     default:
19771       gcc_unreachable ();
19772     }
19773 }
19774   [(set_attr "type" "alu,lea")
19775    (set_attr "mode" "DI")])
19776
19777 (define_insn "allocate_stack_worker_32"
19778   [(set (match_operand:SI 0 "register_operand" "+a")
19779         (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19780    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19781    (clobber (reg:CC FLAGS_REG))]
19782   "!TARGET_64BIT && TARGET_STACK_PROBE"
19783   "call\t___chkstk"
19784   [(set_attr "type" "multi")
19785    (set_attr "length" "5")])
19786
19787 (define_insn "allocate_stack_worker_64"
19788   [(set (match_operand:DI 0 "register_operand" "=a")
19789         (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19790    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19791    (clobber (reg:DI R10_REG))
19792    (clobber (reg:DI R11_REG))
19793    (clobber (reg:CC FLAGS_REG))]
19794   "TARGET_64BIT && TARGET_STACK_PROBE"
19795   "call\t___chkstk"
19796   [(set_attr "type" "multi")
19797    (set_attr "length" "5")])
19798
19799 (define_expand "allocate_stack"
19800   [(match_operand 0 "register_operand" "")
19801    (match_operand 1 "general_operand" "")]
19802   "TARGET_STACK_PROBE"
19803 {
19804   rtx x;
19805
19806 #ifndef CHECK_STACK_LIMIT
19807 #define CHECK_STACK_LIMIT 0
19808 #endif
19809
19810   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19811       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19812     {
19813       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19814                                stack_pointer_rtx, 0, OPTAB_DIRECT);
19815       if (x != stack_pointer_rtx)
19816         emit_move_insn (stack_pointer_rtx, x);
19817     }
19818   else
19819     {
19820       x = copy_to_mode_reg (Pmode, operands[1]);
19821       if (TARGET_64BIT)
19822         x = gen_allocate_stack_worker_64 (x);
19823       else
19824         x = gen_allocate_stack_worker_32 (x);
19825       emit_insn (x);
19826     }
19827
19828   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19829   DONE;
19830 })
19831
19832 (define_expand "builtin_setjmp_receiver"
19833   [(label_ref (match_operand 0 "" ""))]
19834   "!TARGET_64BIT && flag_pic"
19835 {
19836   if (TARGET_MACHO)
19837     {
19838       rtx xops[3];
19839       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19840       rtx label_rtx = gen_label_rtx ();
19841       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19842       xops[0] = xops[1] = picreg;
19843       xops[2] = gen_rtx_CONST (SImode,
19844                   gen_rtx_MINUS (SImode,
19845                     gen_rtx_LABEL_REF (SImode, label_rtx),
19846                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19847       ix86_expand_binary_operator (MINUS, SImode, xops);
19848     }
19849   else
19850     emit_insn (gen_set_got (pic_offset_table_rtx));
19851   DONE;
19852 })
19853 \f
19854 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19855
19856 (define_split
19857   [(set (match_operand 0 "register_operand" "")
19858         (match_operator 3 "promotable_binary_operator"
19859            [(match_operand 1 "register_operand" "")
19860             (match_operand 2 "aligned_operand" "")]))
19861    (clobber (reg:CC FLAGS_REG))]
19862   "! TARGET_PARTIAL_REG_STALL && reload_completed
19863    && ((GET_MODE (operands[0]) == HImode
19864         && ((!optimize_size && !TARGET_FAST_PREFIX)
19865             /* ??? next two lines just !satisfies_constraint_K (...) */
19866             || !CONST_INT_P (operands[2])
19867             || satisfies_constraint_K (operands[2])))
19868        || (GET_MODE (operands[0]) == QImode
19869            && (TARGET_PROMOTE_QImode || optimize_size)))"
19870   [(parallel [(set (match_dup 0)
19871                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19872               (clobber (reg:CC FLAGS_REG))])]
19873   "operands[0] = gen_lowpart (SImode, operands[0]);
19874    operands[1] = gen_lowpart (SImode, operands[1]);
19875    if (GET_CODE (operands[3]) != ASHIFT)
19876      operands[2] = gen_lowpart (SImode, operands[2]);
19877    PUT_MODE (operands[3], SImode);")
19878
19879 ; Promote the QImode tests, as i386 has encoding of the AND
19880 ; instruction with 32-bit sign-extended immediate and thus the
19881 ; instruction size is unchanged, except in the %eax case for
19882 ; which it is increased by one byte, hence the ! optimize_size.
19883 (define_split
19884   [(set (match_operand 0 "flags_reg_operand" "")
19885         (match_operator 2 "compare_operator"
19886           [(and (match_operand 3 "aligned_operand" "")
19887                 (match_operand 4 "const_int_operand" ""))
19888            (const_int 0)]))
19889    (set (match_operand 1 "register_operand" "")
19890         (and (match_dup 3) (match_dup 4)))]
19891   "! TARGET_PARTIAL_REG_STALL && reload_completed
19892    && ! optimize_size
19893    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19894        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19895    /* Ensure that the operand will remain sign-extended immediate.  */
19896    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19897   [(parallel [(set (match_dup 0)
19898                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19899                                     (const_int 0)]))
19900               (set (match_dup 1)
19901                    (and:SI (match_dup 3) (match_dup 4)))])]
19902 {
19903   operands[4]
19904     = gen_int_mode (INTVAL (operands[4])
19905                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19906   operands[1] = gen_lowpart (SImode, operands[1]);
19907   operands[3] = gen_lowpart (SImode, operands[3]);
19908 })
19909
19910 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19911 ; the TEST instruction with 32-bit sign-extended immediate and thus
19912 ; the instruction size would at least double, which is not what we
19913 ; want even with ! optimize_size.
19914 (define_split
19915   [(set (match_operand 0 "flags_reg_operand" "")
19916         (match_operator 1 "compare_operator"
19917           [(and (match_operand:HI 2 "aligned_operand" "")
19918                 (match_operand:HI 3 "const_int_operand" ""))
19919            (const_int 0)]))]
19920   "! TARGET_PARTIAL_REG_STALL && reload_completed
19921    && ! TARGET_FAST_PREFIX
19922    && ! optimize_size
19923    /* Ensure that the operand will remain sign-extended immediate.  */
19924    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19925   [(set (match_dup 0)
19926         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19927                          (const_int 0)]))]
19928 {
19929   operands[3]
19930     = gen_int_mode (INTVAL (operands[3])
19931                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19932   operands[2] = gen_lowpart (SImode, operands[2]);
19933 })
19934
19935 (define_split
19936   [(set (match_operand 0 "register_operand" "")
19937         (neg (match_operand 1 "register_operand" "")))
19938    (clobber (reg:CC FLAGS_REG))]
19939   "! TARGET_PARTIAL_REG_STALL && reload_completed
19940    && (GET_MODE (operands[0]) == HImode
19941        || (GET_MODE (operands[0]) == QImode
19942            && (TARGET_PROMOTE_QImode || optimize_size)))"
19943   [(parallel [(set (match_dup 0)
19944                    (neg:SI (match_dup 1)))
19945               (clobber (reg:CC FLAGS_REG))])]
19946   "operands[0] = gen_lowpart (SImode, operands[0]);
19947    operands[1] = gen_lowpart (SImode, operands[1]);")
19948
19949 (define_split
19950   [(set (match_operand 0 "register_operand" "")
19951         (not (match_operand 1 "register_operand" "")))]
19952   "! TARGET_PARTIAL_REG_STALL && reload_completed
19953    && (GET_MODE (operands[0]) == HImode
19954        || (GET_MODE (operands[0]) == QImode
19955            && (TARGET_PROMOTE_QImode || optimize_size)))"
19956   [(set (match_dup 0)
19957         (not:SI (match_dup 1)))]
19958   "operands[0] = gen_lowpart (SImode, operands[0]);
19959    operands[1] = gen_lowpart (SImode, operands[1]);")
19960
19961 (define_split
19962   [(set (match_operand 0 "register_operand" "")
19963         (if_then_else (match_operator 1 "comparison_operator"
19964                                 [(reg FLAGS_REG) (const_int 0)])
19965                       (match_operand 2 "register_operand" "")
19966                       (match_operand 3 "register_operand" "")))]
19967   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19968    && (GET_MODE (operands[0]) == HImode
19969        || (GET_MODE (operands[0]) == QImode
19970            && (TARGET_PROMOTE_QImode || optimize_size)))"
19971   [(set (match_dup 0)
19972         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19973   "operands[0] = gen_lowpart (SImode, operands[0]);
19974    operands[2] = gen_lowpart (SImode, operands[2]);
19975    operands[3] = gen_lowpart (SImode, operands[3]);")
19976
19977 \f
19978 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19979 ;; transform a complex memory operation into two memory to register operations.
19980
19981 ;; Don't push memory operands
19982 (define_peephole2
19983   [(set (match_operand:SI 0 "push_operand" "")
19984         (match_operand:SI 1 "memory_operand" ""))
19985    (match_scratch:SI 2 "r")]
19986   "!optimize_size && !TARGET_PUSH_MEMORY
19987    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19988   [(set (match_dup 2) (match_dup 1))
19989    (set (match_dup 0) (match_dup 2))]
19990   "")
19991
19992 (define_peephole2
19993   [(set (match_operand:DI 0 "push_operand" "")
19994         (match_operand:DI 1 "memory_operand" ""))
19995    (match_scratch:DI 2 "r")]
19996   "!optimize_size && !TARGET_PUSH_MEMORY
19997    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19998   [(set (match_dup 2) (match_dup 1))
19999    (set (match_dup 0) (match_dup 2))]
20000   "")
20001
20002 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20003 ;; SImode pushes.
20004 (define_peephole2
20005   [(set (match_operand:SF 0 "push_operand" "")
20006         (match_operand:SF 1 "memory_operand" ""))
20007    (match_scratch:SF 2 "r")]
20008   "!optimize_size && !TARGET_PUSH_MEMORY
20009    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20010   [(set (match_dup 2) (match_dup 1))
20011    (set (match_dup 0) (match_dup 2))]
20012   "")
20013
20014 (define_peephole2
20015   [(set (match_operand:HI 0 "push_operand" "")
20016         (match_operand:HI 1 "memory_operand" ""))
20017    (match_scratch:HI 2 "r")]
20018   "!optimize_size && !TARGET_PUSH_MEMORY
20019    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20020   [(set (match_dup 2) (match_dup 1))
20021    (set (match_dup 0) (match_dup 2))]
20022   "")
20023
20024 (define_peephole2
20025   [(set (match_operand:QI 0 "push_operand" "")
20026         (match_operand:QI 1 "memory_operand" ""))
20027    (match_scratch:QI 2 "q")]
20028   "!optimize_size && !TARGET_PUSH_MEMORY
20029    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20030   [(set (match_dup 2) (match_dup 1))
20031    (set (match_dup 0) (match_dup 2))]
20032   "")
20033
20034 ;; Don't move an immediate directly to memory when the instruction
20035 ;; gets too big.
20036 (define_peephole2
20037   [(match_scratch:SI 1 "r")
20038    (set (match_operand:SI 0 "memory_operand" "")
20039         (const_int 0))]
20040   "! optimize_size
20041    && ! TARGET_USE_MOV0
20042    && TARGET_SPLIT_LONG_MOVES
20043    && get_attr_length (insn) >= ix86_cost->large_insn
20044    && peep2_regno_dead_p (0, FLAGS_REG)"
20045   [(parallel [(set (match_dup 1) (const_int 0))
20046               (clobber (reg:CC FLAGS_REG))])
20047    (set (match_dup 0) (match_dup 1))]
20048   "")
20049
20050 (define_peephole2
20051   [(match_scratch:HI 1 "r")
20052    (set (match_operand:HI 0 "memory_operand" "")
20053         (const_int 0))]
20054   "! optimize_size
20055    && ! TARGET_USE_MOV0
20056    && TARGET_SPLIT_LONG_MOVES
20057    && get_attr_length (insn) >= ix86_cost->large_insn
20058    && peep2_regno_dead_p (0, FLAGS_REG)"
20059   [(parallel [(set (match_dup 2) (const_int 0))
20060               (clobber (reg:CC FLAGS_REG))])
20061    (set (match_dup 0) (match_dup 1))]
20062   "operands[2] = gen_lowpart (SImode, operands[1]);")
20063
20064 (define_peephole2
20065   [(match_scratch:QI 1 "q")
20066    (set (match_operand:QI 0 "memory_operand" "")
20067         (const_int 0))]
20068   "! optimize_size
20069    && ! TARGET_USE_MOV0
20070    && TARGET_SPLIT_LONG_MOVES
20071    && get_attr_length (insn) >= ix86_cost->large_insn
20072    && peep2_regno_dead_p (0, FLAGS_REG)"
20073   [(parallel [(set (match_dup 2) (const_int 0))
20074               (clobber (reg:CC FLAGS_REG))])
20075    (set (match_dup 0) (match_dup 1))]
20076   "operands[2] = gen_lowpart (SImode, operands[1]);")
20077
20078 (define_peephole2
20079   [(match_scratch:SI 2 "r")
20080    (set (match_operand:SI 0 "memory_operand" "")
20081         (match_operand:SI 1 "immediate_operand" ""))]
20082   "! optimize_size
20083    && TARGET_SPLIT_LONG_MOVES
20084    && get_attr_length (insn) >= ix86_cost->large_insn"
20085   [(set (match_dup 2) (match_dup 1))
20086    (set (match_dup 0) (match_dup 2))]
20087   "")
20088
20089 (define_peephole2
20090   [(match_scratch:HI 2 "r")
20091    (set (match_operand:HI 0 "memory_operand" "")
20092         (match_operand:HI 1 "immediate_operand" ""))]
20093   "! optimize_size
20094    && TARGET_SPLIT_LONG_MOVES
20095    && get_attr_length (insn) >= ix86_cost->large_insn"
20096   [(set (match_dup 2) (match_dup 1))
20097    (set (match_dup 0) (match_dup 2))]
20098   "")
20099
20100 (define_peephole2
20101   [(match_scratch:QI 2 "q")
20102    (set (match_operand:QI 0 "memory_operand" "")
20103         (match_operand:QI 1 "immediate_operand" ""))]
20104   "! optimize_size
20105    && TARGET_SPLIT_LONG_MOVES
20106    && get_attr_length (insn) >= ix86_cost->large_insn"
20107   [(set (match_dup 2) (match_dup 1))
20108    (set (match_dup 0) (match_dup 2))]
20109   "")
20110
20111 ;; Don't compare memory with zero, load and use a test instead.
20112 (define_peephole2
20113   [(set (match_operand 0 "flags_reg_operand" "")
20114         (match_operator 1 "compare_operator"
20115           [(match_operand:SI 2 "memory_operand" "")
20116            (const_int 0)]))
20117    (match_scratch:SI 3 "r")]
20118   " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20119   [(set (match_dup 3) (match_dup 2))
20120    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20121   "")
20122
20123 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20124 ;; Don't split NOTs with a displacement operand, because resulting XOR
20125 ;; will not be pairable anyway.
20126 ;;
20127 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20128 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20129 ;; so this split helps here as well.
20130 ;;
20131 ;; Note: Can't do this as a regular split because we can't get proper
20132 ;; lifetime information then.
20133
20134 (define_peephole2
20135   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20136         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20137   "!optimize_size
20138    && ((TARGET_NOT_UNPAIRABLE
20139         && (!MEM_P (operands[0])
20140             || !memory_displacement_operand (operands[0], SImode)))
20141        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20142    && peep2_regno_dead_p (0, FLAGS_REG)"
20143   [(parallel [(set (match_dup 0)
20144                    (xor:SI (match_dup 1) (const_int -1)))
20145               (clobber (reg:CC FLAGS_REG))])]
20146   "")
20147
20148 (define_peephole2
20149   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20150         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20151   "!optimize_size
20152    && ((TARGET_NOT_UNPAIRABLE
20153         && (!MEM_P (operands[0])
20154             || !memory_displacement_operand (operands[0], HImode)))
20155        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20156    && peep2_regno_dead_p (0, FLAGS_REG)"
20157   [(parallel [(set (match_dup 0)
20158                    (xor:HI (match_dup 1) (const_int -1)))
20159               (clobber (reg:CC FLAGS_REG))])]
20160   "")
20161
20162 (define_peephole2
20163   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20164         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20165   "!optimize_size
20166    && ((TARGET_NOT_UNPAIRABLE
20167         && (!MEM_P (operands[0])
20168             || !memory_displacement_operand (operands[0], QImode)))
20169        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20170    && peep2_regno_dead_p (0, FLAGS_REG)"
20171   [(parallel [(set (match_dup 0)
20172                    (xor:QI (match_dup 1) (const_int -1)))
20173               (clobber (reg:CC FLAGS_REG))])]
20174   "")
20175
20176 ;; Non pairable "test imm, reg" instructions can be translated to
20177 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20178 ;; byte opcode instead of two, have a short form for byte operands),
20179 ;; so do it for other CPUs as well.  Given that the value was dead,
20180 ;; this should not create any new dependencies.  Pass on the sub-word
20181 ;; versions if we're concerned about partial register stalls.
20182
20183 (define_peephole2
20184   [(set (match_operand 0 "flags_reg_operand" "")
20185         (match_operator 1 "compare_operator"
20186           [(and:SI (match_operand:SI 2 "register_operand" "")
20187                    (match_operand:SI 3 "immediate_operand" ""))
20188            (const_int 0)]))]
20189   "ix86_match_ccmode (insn, CCNOmode)
20190    && (true_regnum (operands[2]) != AX_REG
20191        || satisfies_constraint_K (operands[3]))
20192    && peep2_reg_dead_p (1, operands[2])"
20193   [(parallel
20194      [(set (match_dup 0)
20195            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20196                             (const_int 0)]))
20197       (set (match_dup 2)
20198            (and:SI (match_dup 2) (match_dup 3)))])]
20199   "")
20200
20201 ;; We don't need to handle HImode case, because it will be promoted to SImode
20202 ;; on ! TARGET_PARTIAL_REG_STALL
20203
20204 (define_peephole2
20205   [(set (match_operand 0 "flags_reg_operand" "")
20206         (match_operator 1 "compare_operator"
20207           [(and:QI (match_operand:QI 2 "register_operand" "")
20208                    (match_operand:QI 3 "immediate_operand" ""))
20209            (const_int 0)]))]
20210   "! TARGET_PARTIAL_REG_STALL
20211    && ix86_match_ccmode (insn, CCNOmode)
20212    && true_regnum (operands[2]) != AX_REG
20213    && peep2_reg_dead_p (1, operands[2])"
20214   [(parallel
20215      [(set (match_dup 0)
20216            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20217                             (const_int 0)]))
20218       (set (match_dup 2)
20219            (and:QI (match_dup 2) (match_dup 3)))])]
20220   "")
20221
20222 (define_peephole2
20223   [(set (match_operand 0 "flags_reg_operand" "")
20224         (match_operator 1 "compare_operator"
20225           [(and:SI
20226              (zero_extract:SI
20227                (match_operand 2 "ext_register_operand" "")
20228                (const_int 8)
20229                (const_int 8))
20230              (match_operand 3 "const_int_operand" ""))
20231            (const_int 0)]))]
20232   "! TARGET_PARTIAL_REG_STALL
20233    && ix86_match_ccmode (insn, CCNOmode)
20234    && true_regnum (operands[2]) != AX_REG
20235    && peep2_reg_dead_p (1, operands[2])"
20236   [(parallel [(set (match_dup 0)
20237                    (match_op_dup 1
20238                      [(and:SI
20239                         (zero_extract:SI
20240                           (match_dup 2)
20241                           (const_int 8)
20242                           (const_int 8))
20243                         (match_dup 3))
20244                       (const_int 0)]))
20245               (set (zero_extract:SI (match_dup 2)
20246                                     (const_int 8)
20247                                     (const_int 8))
20248                    (and:SI
20249                      (zero_extract:SI
20250                        (match_dup 2)
20251                        (const_int 8)
20252                        (const_int 8))
20253                      (match_dup 3)))])]
20254   "")
20255
20256 ;; Don't do logical operations with memory inputs.
20257 (define_peephole2
20258   [(match_scratch:SI 2 "r")
20259    (parallel [(set (match_operand:SI 0 "register_operand" "")
20260                    (match_operator:SI 3 "arith_or_logical_operator"
20261                      [(match_dup 0)
20262                       (match_operand:SI 1 "memory_operand" "")]))
20263               (clobber (reg:CC FLAGS_REG))])]
20264   "! optimize_size && ! TARGET_READ_MODIFY"
20265   [(set (match_dup 2) (match_dup 1))
20266    (parallel [(set (match_dup 0)
20267                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20268               (clobber (reg:CC FLAGS_REG))])]
20269   "")
20270
20271 (define_peephole2
20272   [(match_scratch:SI 2 "r")
20273    (parallel [(set (match_operand:SI 0 "register_operand" "")
20274                    (match_operator:SI 3 "arith_or_logical_operator"
20275                      [(match_operand:SI 1 "memory_operand" "")
20276                       (match_dup 0)]))
20277               (clobber (reg:CC FLAGS_REG))])]
20278   "! optimize_size && ! TARGET_READ_MODIFY"
20279   [(set (match_dup 2) (match_dup 1))
20280    (parallel [(set (match_dup 0)
20281                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20282               (clobber (reg:CC FLAGS_REG))])]
20283   "")
20284
20285 ; Don't do logical operations with memory outputs
20286 ;
20287 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20288 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20289 ; the same decoder scheduling characteristics as the original.
20290
20291 (define_peephole2
20292   [(match_scratch:SI 2 "r")
20293    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20294                    (match_operator:SI 3 "arith_or_logical_operator"
20295                      [(match_dup 0)
20296                       (match_operand:SI 1 "nonmemory_operand" "")]))
20297               (clobber (reg:CC FLAGS_REG))])]
20298   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20299   [(set (match_dup 2) (match_dup 0))
20300    (parallel [(set (match_dup 2)
20301                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20302               (clobber (reg:CC FLAGS_REG))])
20303    (set (match_dup 0) (match_dup 2))]
20304   "")
20305
20306 (define_peephole2
20307   [(match_scratch:SI 2 "r")
20308    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20309                    (match_operator:SI 3 "arith_or_logical_operator"
20310                      [(match_operand:SI 1 "nonmemory_operand" "")
20311                       (match_dup 0)]))
20312               (clobber (reg:CC FLAGS_REG))])]
20313   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20314   [(set (match_dup 2) (match_dup 0))
20315    (parallel [(set (match_dup 2)
20316                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20317               (clobber (reg:CC FLAGS_REG))])
20318    (set (match_dup 0) (match_dup 2))]
20319   "")
20320
20321 ;; Attempt to always use XOR for zeroing registers.
20322 (define_peephole2
20323   [(set (match_operand 0 "register_operand" "")
20324         (match_operand 1 "const0_operand" ""))]
20325   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20326    && (! TARGET_USE_MOV0 || optimize_size)
20327    && GENERAL_REG_P (operands[0])
20328    && peep2_regno_dead_p (0, FLAGS_REG)"
20329   [(parallel [(set (match_dup 0) (const_int 0))
20330               (clobber (reg:CC FLAGS_REG))])]
20331 {
20332   operands[0] = gen_lowpart (word_mode, operands[0]);
20333 })
20334
20335 (define_peephole2
20336   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20337         (const_int 0))]
20338   "(GET_MODE (operands[0]) == QImode
20339     || GET_MODE (operands[0]) == HImode)
20340    && (! TARGET_USE_MOV0 || optimize_size)
20341    && peep2_regno_dead_p (0, FLAGS_REG)"
20342   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20343               (clobber (reg:CC FLAGS_REG))])])
20344
20345 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20346 (define_peephole2
20347   [(set (match_operand 0 "register_operand" "")
20348         (const_int -1))]
20349   "(GET_MODE (operands[0]) == HImode
20350     || GET_MODE (operands[0]) == SImode
20351     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20352    && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20353    && peep2_regno_dead_p (0, FLAGS_REG)"
20354   [(parallel [(set (match_dup 0) (const_int -1))
20355               (clobber (reg:CC FLAGS_REG))])]
20356   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20357                               operands[0]);")
20358
20359 ;; Attempt to convert simple leas to adds. These can be created by
20360 ;; move expanders.
20361 (define_peephole2
20362   [(set (match_operand:SI 0 "register_operand" "")
20363         (plus:SI (match_dup 0)
20364                  (match_operand:SI 1 "nonmemory_operand" "")))]
20365   "peep2_regno_dead_p (0, FLAGS_REG)"
20366   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20367               (clobber (reg:CC FLAGS_REG))])]
20368   "")
20369
20370 (define_peephole2
20371   [(set (match_operand:SI 0 "register_operand" "")
20372         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20373                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20374   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20375   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20376               (clobber (reg:CC FLAGS_REG))])]
20377   "operands[2] = gen_lowpart (SImode, operands[2]);")
20378
20379 (define_peephole2
20380   [(set (match_operand:DI 0 "register_operand" "")
20381         (plus:DI (match_dup 0)
20382                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20383   "peep2_regno_dead_p (0, FLAGS_REG)"
20384   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20385               (clobber (reg:CC FLAGS_REG))])]
20386   "")
20387
20388 (define_peephole2
20389   [(set (match_operand:SI 0 "register_operand" "")
20390         (mult:SI (match_dup 0)
20391                  (match_operand:SI 1 "const_int_operand" "")))]
20392   "exact_log2 (INTVAL (operands[1])) >= 0
20393    && peep2_regno_dead_p (0, FLAGS_REG)"
20394   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20395               (clobber (reg:CC FLAGS_REG))])]
20396   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20397
20398 (define_peephole2
20399   [(set (match_operand:DI 0 "register_operand" "")
20400         (mult:DI (match_dup 0)
20401                  (match_operand:DI 1 "const_int_operand" "")))]
20402   "exact_log2 (INTVAL (operands[1])) >= 0
20403    && peep2_regno_dead_p (0, FLAGS_REG)"
20404   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20405               (clobber (reg:CC FLAGS_REG))])]
20406   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20407
20408 (define_peephole2
20409   [(set (match_operand:SI 0 "register_operand" "")
20410         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20411                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20412   "exact_log2 (INTVAL (operands[2])) >= 0
20413    && REGNO (operands[0]) == REGNO (operands[1])
20414    && peep2_regno_dead_p (0, FLAGS_REG)"
20415   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20416               (clobber (reg:CC FLAGS_REG))])]
20417   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20418
20419 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20420 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20421 ;; many CPUs it is also faster, since special hardware to avoid esp
20422 ;; dependencies is present.
20423
20424 ;; While some of these conversions may be done using splitters, we use peepholes
20425 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20426
20427 ;; Convert prologue esp subtractions to push.
20428 ;; We need register to push.  In order to keep verify_flow_info happy we have
20429 ;; two choices
20430 ;; - use scratch and clobber it in order to avoid dependencies
20431 ;; - use already live register
20432 ;; We can't use the second way right now, since there is no reliable way how to
20433 ;; verify that given register is live.  First choice will also most likely in
20434 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20435 ;; call clobbered registers are dead.  We may want to use base pointer as an
20436 ;; alternative when no register is available later.
20437
20438 (define_peephole2
20439   [(match_scratch:SI 0 "r")
20440    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20441               (clobber (reg:CC FLAGS_REG))
20442               (clobber (mem:BLK (scratch)))])]
20443   "optimize_size || !TARGET_SUB_ESP_4"
20444   [(clobber (match_dup 0))
20445    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20446               (clobber (mem:BLK (scratch)))])])
20447
20448 (define_peephole2
20449   [(match_scratch:SI 0 "r")
20450    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20451               (clobber (reg:CC FLAGS_REG))
20452               (clobber (mem:BLK (scratch)))])]
20453   "optimize_size || !TARGET_SUB_ESP_8"
20454   [(clobber (match_dup 0))
20455    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20456    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20457               (clobber (mem:BLK (scratch)))])])
20458
20459 ;; Convert esp subtractions to push.
20460 (define_peephole2
20461   [(match_scratch:SI 0 "r")
20462    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20463               (clobber (reg:CC FLAGS_REG))])]
20464   "optimize_size || !TARGET_SUB_ESP_4"
20465   [(clobber (match_dup 0))
20466    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20467
20468 (define_peephole2
20469   [(match_scratch:SI 0 "r")
20470    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20471               (clobber (reg:CC FLAGS_REG))])]
20472   "optimize_size || !TARGET_SUB_ESP_8"
20473   [(clobber (match_dup 0))
20474    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20475    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20476
20477 ;; Convert epilogue deallocator to pop.
20478 (define_peephole2
20479   [(match_scratch:SI 0 "r")
20480    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20481               (clobber (reg:CC FLAGS_REG))
20482               (clobber (mem:BLK (scratch)))])]
20483   "optimize_size || !TARGET_ADD_ESP_4"
20484   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20485               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20486               (clobber (mem:BLK (scratch)))])]
20487   "")
20488
20489 ;; Two pops case is tricky, since pop causes dependency on destination register.
20490 ;; We use two registers if available.
20491 (define_peephole2
20492   [(match_scratch:SI 0 "r")
20493    (match_scratch:SI 1 "r")
20494    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20495               (clobber (reg:CC FLAGS_REG))
20496               (clobber (mem:BLK (scratch)))])]
20497   "optimize_size || !TARGET_ADD_ESP_8"
20498   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20499               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20500               (clobber (mem:BLK (scratch)))])
20501    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20502               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20503   "")
20504
20505 (define_peephole2
20506   [(match_scratch:SI 0 "r")
20507    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20508               (clobber (reg:CC FLAGS_REG))
20509               (clobber (mem:BLK (scratch)))])]
20510   "optimize_size"
20511   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20512               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20513               (clobber (mem:BLK (scratch)))])
20514    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20515               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20516   "")
20517
20518 ;; Convert esp additions to pop.
20519 (define_peephole2
20520   [(match_scratch:SI 0 "r")
20521    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20522               (clobber (reg:CC FLAGS_REG))])]
20523   ""
20524   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20525               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20526   "")
20527
20528 ;; Two pops case is tricky, since pop causes dependency on destination register.
20529 ;; We use two registers if available.
20530 (define_peephole2
20531   [(match_scratch:SI 0 "r")
20532    (match_scratch:SI 1 "r")
20533    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20534               (clobber (reg:CC FLAGS_REG))])]
20535   ""
20536   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20537               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20538    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20539               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20540   "")
20541
20542 (define_peephole2
20543   [(match_scratch:SI 0 "r")
20544    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20545               (clobber (reg:CC FLAGS_REG))])]
20546   "optimize_size"
20547   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20548               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20549    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20550               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20551   "")
20552 \f
20553 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20554 ;; required and register dies.  Similarly for 128 to plus -128.
20555 (define_peephole2
20556   [(set (match_operand 0 "flags_reg_operand" "")
20557         (match_operator 1 "compare_operator"
20558           [(match_operand 2 "register_operand" "")
20559            (match_operand 3 "const_int_operand" "")]))]
20560   "(INTVAL (operands[3]) == -1
20561     || INTVAL (operands[3]) == 1
20562     || INTVAL (operands[3]) == 128)
20563    && ix86_match_ccmode (insn, CCGCmode)
20564    && peep2_reg_dead_p (1, operands[2])"
20565   [(parallel [(set (match_dup 0)
20566                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20567               (clobber (match_dup 2))])]
20568   "")
20569 \f
20570 (define_peephole2
20571   [(match_scratch:DI 0 "r")
20572    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20573               (clobber (reg:CC FLAGS_REG))
20574               (clobber (mem:BLK (scratch)))])]
20575   "optimize_size || !TARGET_SUB_ESP_4"
20576   [(clobber (match_dup 0))
20577    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20578               (clobber (mem:BLK (scratch)))])])
20579
20580 (define_peephole2
20581   [(match_scratch:DI 0 "r")
20582    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20583               (clobber (reg:CC FLAGS_REG))
20584               (clobber (mem:BLK (scratch)))])]
20585   "optimize_size || !TARGET_SUB_ESP_8"
20586   [(clobber (match_dup 0))
20587    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20588    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20589               (clobber (mem:BLK (scratch)))])])
20590
20591 ;; Convert esp subtractions to push.
20592 (define_peephole2
20593   [(match_scratch:DI 0 "r")
20594    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20595               (clobber (reg:CC FLAGS_REG))])]
20596   "optimize_size || !TARGET_SUB_ESP_4"
20597   [(clobber (match_dup 0))
20598    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20599
20600 (define_peephole2
20601   [(match_scratch:DI 0 "r")
20602    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20603               (clobber (reg:CC FLAGS_REG))])]
20604   "optimize_size || !TARGET_SUB_ESP_8"
20605   [(clobber (match_dup 0))
20606    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20607    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20608
20609 ;; Convert epilogue deallocator to pop.
20610 (define_peephole2
20611   [(match_scratch:DI 0 "r")
20612    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20613               (clobber (reg:CC FLAGS_REG))
20614               (clobber (mem:BLK (scratch)))])]
20615   "optimize_size || !TARGET_ADD_ESP_4"
20616   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20617               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20618               (clobber (mem:BLK (scratch)))])]
20619   "")
20620
20621 ;; Two pops case is tricky, since pop causes dependency on destination register.
20622 ;; We use two registers if available.
20623 (define_peephole2
20624   [(match_scratch:DI 0 "r")
20625    (match_scratch:DI 1 "r")
20626    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20627               (clobber (reg:CC FLAGS_REG))
20628               (clobber (mem:BLK (scratch)))])]
20629   "optimize_size || !TARGET_ADD_ESP_8"
20630   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20631               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20632               (clobber (mem:BLK (scratch)))])
20633    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20634               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20635   "")
20636
20637 (define_peephole2
20638   [(match_scratch:DI 0 "r")
20639    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20640               (clobber (reg:CC FLAGS_REG))
20641               (clobber (mem:BLK (scratch)))])]
20642   "optimize_size"
20643   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20644               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20645               (clobber (mem:BLK (scratch)))])
20646    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20647               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20648   "")
20649
20650 ;; Convert esp additions to pop.
20651 (define_peephole2
20652   [(match_scratch:DI 0 "r")
20653    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20654               (clobber (reg:CC FLAGS_REG))])]
20655   ""
20656   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20657               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20658   "")
20659
20660 ;; Two pops case is tricky, since pop causes dependency on destination register.
20661 ;; We use two registers if available.
20662 (define_peephole2
20663   [(match_scratch:DI 0 "r")
20664    (match_scratch:DI 1 "r")
20665    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20666               (clobber (reg:CC FLAGS_REG))])]
20667   ""
20668   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20669               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20670    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20671               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20672   "")
20673
20674 (define_peephole2
20675   [(match_scratch:DI 0 "r")
20676    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20677               (clobber (reg:CC FLAGS_REG))])]
20678   "optimize_size"
20679   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20680               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20681    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20682               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20683   "")
20684 \f
20685 ;; Convert imul by three, five and nine into lea
20686 (define_peephole2
20687   [(parallel
20688     [(set (match_operand:SI 0 "register_operand" "")
20689           (mult:SI (match_operand:SI 1 "register_operand" "")
20690                    (match_operand:SI 2 "const_int_operand" "")))
20691      (clobber (reg:CC FLAGS_REG))])]
20692   "INTVAL (operands[2]) == 3
20693    || INTVAL (operands[2]) == 5
20694    || INTVAL (operands[2]) == 9"
20695   [(set (match_dup 0)
20696         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20697                  (match_dup 1)))]
20698   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20699
20700 (define_peephole2
20701   [(parallel
20702     [(set (match_operand:SI 0 "register_operand" "")
20703           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20704                    (match_operand:SI 2 "const_int_operand" "")))
20705      (clobber (reg:CC FLAGS_REG))])]
20706   "!optimize_size
20707    && (INTVAL (operands[2]) == 3
20708        || INTVAL (operands[2]) == 5
20709        || INTVAL (operands[2]) == 9)"
20710   [(set (match_dup 0) (match_dup 1))
20711    (set (match_dup 0)
20712         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20713                  (match_dup 0)))]
20714   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20715
20716 (define_peephole2
20717   [(parallel
20718     [(set (match_operand:DI 0 "register_operand" "")
20719           (mult:DI (match_operand:DI 1 "register_operand" "")
20720                    (match_operand:DI 2 "const_int_operand" "")))
20721      (clobber (reg:CC FLAGS_REG))])]
20722   "TARGET_64BIT
20723    && (INTVAL (operands[2]) == 3
20724        || INTVAL (operands[2]) == 5
20725        || INTVAL (operands[2]) == 9)"
20726   [(set (match_dup 0)
20727         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20728                  (match_dup 1)))]
20729   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20730
20731 (define_peephole2
20732   [(parallel
20733     [(set (match_operand:DI 0 "register_operand" "")
20734           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20735                    (match_operand:DI 2 "const_int_operand" "")))
20736      (clobber (reg:CC FLAGS_REG))])]
20737   "TARGET_64BIT
20738    && !optimize_size
20739    && (INTVAL (operands[2]) == 3
20740        || INTVAL (operands[2]) == 5
20741        || INTVAL (operands[2]) == 9)"
20742   [(set (match_dup 0) (match_dup 1))
20743    (set (match_dup 0)
20744         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20745                  (match_dup 0)))]
20746   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20747
20748 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20749 ;; imul $32bit_imm, reg, reg is direct decoded.
20750 (define_peephole2
20751   [(match_scratch:DI 3 "r")
20752    (parallel [(set (match_operand:DI 0 "register_operand" "")
20753                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20754                             (match_operand:DI 2 "immediate_operand" "")))
20755               (clobber (reg:CC FLAGS_REG))])]
20756   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20757    && !satisfies_constraint_K (operands[2])"
20758   [(set (match_dup 3) (match_dup 1))
20759    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20760               (clobber (reg:CC FLAGS_REG))])]
20761 "")
20762
20763 (define_peephole2
20764   [(match_scratch:SI 3 "r")
20765    (parallel [(set (match_operand:SI 0 "register_operand" "")
20766                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20767                             (match_operand:SI 2 "immediate_operand" "")))
20768               (clobber (reg:CC FLAGS_REG))])]
20769   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20770    && !satisfies_constraint_K (operands[2])"
20771   [(set (match_dup 3) (match_dup 1))
20772    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20773               (clobber (reg:CC FLAGS_REG))])]
20774 "")
20775
20776 (define_peephole2
20777   [(match_scratch:SI 3 "r")
20778    (parallel [(set (match_operand:DI 0 "register_operand" "")
20779                    (zero_extend:DI
20780                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20781                               (match_operand:SI 2 "immediate_operand" ""))))
20782               (clobber (reg:CC FLAGS_REG))])]
20783   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20784    && !satisfies_constraint_K (operands[2])"
20785   [(set (match_dup 3) (match_dup 1))
20786    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20787               (clobber (reg:CC FLAGS_REG))])]
20788 "")
20789
20790 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20791 ;; Convert it into imul reg, reg
20792 ;; It would be better to force assembler to encode instruction using long
20793 ;; immediate, but there is apparently no way to do so.
20794 (define_peephole2
20795   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20796                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20797                             (match_operand:DI 2 "const_int_operand" "")))
20798               (clobber (reg:CC FLAGS_REG))])
20799    (match_scratch:DI 3 "r")]
20800   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20801    && satisfies_constraint_K (operands[2])"
20802   [(set (match_dup 3) (match_dup 2))
20803    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20804               (clobber (reg:CC FLAGS_REG))])]
20805 {
20806   if (!rtx_equal_p (operands[0], operands[1]))
20807     emit_move_insn (operands[0], operands[1]);
20808 })
20809
20810 (define_peephole2
20811   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20812                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20813                             (match_operand:SI 2 "const_int_operand" "")))
20814               (clobber (reg:CC FLAGS_REG))])
20815    (match_scratch:SI 3 "r")]
20816   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20817    && satisfies_constraint_K (operands[2])"
20818   [(set (match_dup 3) (match_dup 2))
20819    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20820               (clobber (reg:CC FLAGS_REG))])]
20821 {
20822   if (!rtx_equal_p (operands[0], operands[1]))
20823     emit_move_insn (operands[0], operands[1]);
20824 })
20825
20826 (define_peephole2
20827   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20828                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20829                             (match_operand:HI 2 "immediate_operand" "")))
20830               (clobber (reg:CC FLAGS_REG))])
20831    (match_scratch:HI 3 "r")]
20832   "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20833   [(set (match_dup 3) (match_dup 2))
20834    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20835               (clobber (reg:CC FLAGS_REG))])]
20836 {
20837   if (!rtx_equal_p (operands[0], operands[1]))
20838     emit_move_insn (operands[0], operands[1]);
20839 })
20840
20841 ;; After splitting up read-modify operations, array accesses with memory
20842 ;; operands might end up in form:
20843 ;;  sall    $2, %eax
20844 ;;  movl    4(%esp), %edx
20845 ;;  addl    %edx, %eax
20846 ;; instead of pre-splitting:
20847 ;;  sall    $2, %eax
20848 ;;  addl    4(%esp), %eax
20849 ;; Turn it into:
20850 ;;  movl    4(%esp), %edx
20851 ;;  leal    (%edx,%eax,4), %eax
20852
20853 (define_peephole2
20854   [(parallel [(set (match_operand 0 "register_operand" "")
20855                    (ashift (match_operand 1 "register_operand" "")
20856                            (match_operand 2 "const_int_operand" "")))
20857                (clobber (reg:CC FLAGS_REG))])
20858    (set (match_operand 3 "register_operand")
20859         (match_operand 4 "x86_64_general_operand" ""))
20860    (parallel [(set (match_operand 5 "register_operand" "")
20861                    (plus (match_operand 6 "register_operand" "")
20862                          (match_operand 7 "register_operand" "")))
20863                    (clobber (reg:CC FLAGS_REG))])]
20864   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20865    /* Validate MODE for lea.  */
20866    && ((!TARGET_PARTIAL_REG_STALL
20867         && (GET_MODE (operands[0]) == QImode
20868             || GET_MODE (operands[0]) == HImode))
20869        || GET_MODE (operands[0]) == SImode
20870        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20871    /* We reorder load and the shift.  */
20872    && !rtx_equal_p (operands[1], operands[3])
20873    && !reg_overlap_mentioned_p (operands[0], operands[4])
20874    /* Last PLUS must consist of operand 0 and 3.  */
20875    && !rtx_equal_p (operands[0], operands[3])
20876    && (rtx_equal_p (operands[3], operands[6])
20877        || rtx_equal_p (operands[3], operands[7]))
20878    && (rtx_equal_p (operands[0], operands[6])
20879        || rtx_equal_p (operands[0], operands[7]))
20880    /* The intermediate operand 0 must die or be same as output.  */
20881    && (rtx_equal_p (operands[0], operands[5])
20882        || peep2_reg_dead_p (3, operands[0]))"
20883   [(set (match_dup 3) (match_dup 4))
20884    (set (match_dup 0) (match_dup 1))]
20885 {
20886   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20887   int scale = 1 << INTVAL (operands[2]);
20888   rtx index = gen_lowpart (Pmode, operands[1]);
20889   rtx base = gen_lowpart (Pmode, operands[3]);
20890   rtx dest = gen_lowpart (mode, operands[5]);
20891
20892   operands[1] = gen_rtx_PLUS (Pmode, base,
20893                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20894   if (mode != Pmode)
20895     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20896   operands[0] = dest;
20897 })
20898 \f
20899 ;; Call-value patterns last so that the wildcard operand does not
20900 ;; disrupt insn-recog's switch tables.
20901
20902 (define_insn "*call_value_pop_0"
20903   [(set (match_operand 0 "" "")
20904         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20905               (match_operand:SI 2 "" "")))
20906    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20907                             (match_operand:SI 3 "immediate_operand" "")))]
20908   "!TARGET_64BIT"
20909 {
20910   if (SIBLING_CALL_P (insn))
20911     return "jmp\t%P1";
20912   else
20913     return "call\t%P1";
20914 }
20915   [(set_attr "type" "callv")])
20916
20917 (define_insn "*call_value_pop_1"
20918   [(set (match_operand 0 "" "")
20919         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20920               (match_operand:SI 2 "" "")))
20921    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20922                             (match_operand:SI 3 "immediate_operand" "i")))]
20923   "!TARGET_64BIT"
20924 {
20925   if (constant_call_address_operand (operands[1], Pmode))
20926     {
20927       if (SIBLING_CALL_P (insn))
20928         return "jmp\t%P1";
20929       else
20930         return "call\t%P1";
20931     }
20932   if (SIBLING_CALL_P (insn))
20933     return "jmp\t%A1";
20934   else
20935     return "call\t%A1";
20936 }
20937   [(set_attr "type" "callv")])
20938
20939 (define_insn "*call_value_0"
20940   [(set (match_operand 0 "" "")
20941         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20942               (match_operand:SI 2 "" "")))]
20943   "!TARGET_64BIT"
20944 {
20945   if (SIBLING_CALL_P (insn))
20946     return "jmp\t%P1";
20947   else
20948     return "call\t%P1";
20949 }
20950   [(set_attr "type" "callv")])
20951
20952 (define_insn "*call_value_0_rex64"
20953   [(set (match_operand 0 "" "")
20954         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20955               (match_operand:DI 2 "const_int_operand" "")))]
20956   "TARGET_64BIT"
20957 {
20958   if (SIBLING_CALL_P (insn))
20959     return "jmp\t%P1";
20960   else
20961     return "call\t%P1";
20962 }
20963   [(set_attr "type" "callv")])
20964
20965 (define_insn "*call_value_1"
20966   [(set (match_operand 0 "" "")
20967         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20968               (match_operand:SI 2 "" "")))]
20969   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20970 {
20971   if (constant_call_address_operand (operands[1], Pmode))
20972     return "call\t%P1";
20973   return "call\t%A1";
20974 }
20975   [(set_attr "type" "callv")])
20976
20977 (define_insn "*sibcall_value_1"
20978   [(set (match_operand 0 "" "")
20979         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20980               (match_operand:SI 2 "" "")))]
20981   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20982 {
20983   if (constant_call_address_operand (operands[1], Pmode))
20984     return "jmp\t%P1";
20985   return "jmp\t%A1";
20986 }
20987   [(set_attr "type" "callv")])
20988
20989 (define_insn "*call_value_1_rex64"
20990   [(set (match_operand 0 "" "")
20991         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20992               (match_operand:DI 2 "" "")))]
20993   "!SIBLING_CALL_P (insn) && TARGET_64BIT
20994    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20995 {
20996   if (constant_call_address_operand (operands[1], Pmode))
20997     return "call\t%P1";
20998   return "call\t%A1";
20999 }
21000   [(set_attr "type" "callv")])
21001
21002 (define_insn "*call_value_1_rex64_large"
21003   [(set (match_operand 0 "" "")
21004         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21005               (match_operand:DI 2 "" "")))]
21006   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21007   "call\t%A1"
21008   [(set_attr "type" "callv")])
21009
21010 (define_insn "*sibcall_value_1_rex64"
21011   [(set (match_operand 0 "" "")
21012         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21013               (match_operand:DI 2 "" "")))]
21014   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21015   "jmp\t%P1"
21016   [(set_attr "type" "callv")])
21017
21018 (define_insn "*sibcall_value_1_rex64_v"
21019   [(set (match_operand 0 "" "")
21020         (call (mem:QI (reg:DI R11_REG))
21021               (match_operand:DI 1 "" "")))]
21022   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21023   "jmp\t{*%%}r11"
21024   [(set_attr "type" "callv")])
21025 \f
21026 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21027 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21028 ;; caught for use by garbage collectors and the like.  Using an insn that
21029 ;; maps to SIGILL makes it more likely the program will rightfully die.
21030 ;; Keeping with tradition, "6" is in honor of #UD.
21031 (define_insn "trap"
21032   [(trap_if (const_int 1) (const_int 6))]
21033   ""
21034   { return ASM_SHORT "0x0b0f"; }
21035   [(set_attr "length" "2")])
21036
21037 (define_expand "sse_prologue_save"
21038   [(parallel [(set (match_operand:BLK 0 "" "")
21039                    (unspec:BLK [(reg:DI 21)
21040                                 (reg:DI 22)
21041                                 (reg:DI 23)
21042                                 (reg:DI 24)
21043                                 (reg:DI 25)
21044                                 (reg:DI 26)
21045                                 (reg:DI 27)
21046                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21047               (use (match_operand:DI 1 "register_operand" ""))
21048               (use (match_operand:DI 2 "immediate_operand" ""))
21049               (use (label_ref:DI (match_operand 3 "" "")))])]
21050   "TARGET_64BIT"
21051   "")
21052
21053 (define_insn "*sse_prologue_save_insn"
21054   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21055                           (match_operand:DI 4 "const_int_operand" "n")))
21056         (unspec:BLK [(reg:DI 21)
21057                      (reg:DI 22)
21058                      (reg:DI 23)
21059                      (reg:DI 24)
21060                      (reg:DI 25)
21061                      (reg:DI 26)
21062                      (reg:DI 27)
21063                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21064    (use (match_operand:DI 1 "register_operand" "r"))
21065    (use (match_operand:DI 2 "const_int_operand" "i"))
21066    (use (label_ref:DI (match_operand 3 "" "X")))]
21067   "TARGET_64BIT
21068    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21069    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21070   "*
21071 {
21072   int i;
21073   operands[0] = gen_rtx_MEM (Pmode,
21074                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21075   output_asm_insn (\"jmp\\t%A1\", operands);
21076   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21077     {
21078       operands[4] = adjust_address (operands[0], DImode, i*16);
21079       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21080       PUT_MODE (operands[4], TImode);
21081       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21082         output_asm_insn (\"rex\", operands);
21083       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21084     }
21085   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21086                              CODE_LABEL_NUMBER (operands[3]));
21087   return \"\";
21088 }
21089   "
21090   [(set_attr "type" "other")
21091    (set_attr "length_immediate" "0")
21092    (set_attr "length_address" "0")
21093    (set_attr "length" "135")
21094    (set_attr "memory" "store")
21095    (set_attr "modrm" "0")
21096    (set_attr "mode" "DI")])
21097
21098 (define_expand "prefetch"
21099   [(prefetch (match_operand 0 "address_operand" "")
21100              (match_operand:SI 1 "const_int_operand" "")
21101              (match_operand:SI 2 "const_int_operand" ""))]
21102   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21103 {
21104   int rw = INTVAL (operands[1]);
21105   int locality = INTVAL (operands[2]);
21106
21107   gcc_assert (rw == 0 || rw == 1);
21108   gcc_assert (locality >= 0 && locality <= 3);
21109   gcc_assert (GET_MODE (operands[0]) == Pmode
21110               || GET_MODE (operands[0]) == VOIDmode);
21111
21112   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21113      supported by SSE counterpart or the SSE prefetch is not available
21114      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21115      of locality.  */
21116   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21117     operands[2] = GEN_INT (3);
21118   else
21119     operands[1] = const0_rtx;
21120 })
21121
21122 (define_insn "*prefetch_sse"
21123   [(prefetch (match_operand:SI 0 "address_operand" "p")
21124              (const_int 0)
21125              (match_operand:SI 1 "const_int_operand" ""))]
21126   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21127 {
21128   static const char * const patterns[4] = {
21129    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21130   };
21131
21132   int locality = INTVAL (operands[1]);
21133   gcc_assert (locality >= 0 && locality <= 3);
21134
21135   return patterns[locality];
21136 }
21137   [(set_attr "type" "sse")
21138    (set_attr "memory" "none")])
21139
21140 (define_insn "*prefetch_sse_rex"
21141   [(prefetch (match_operand:DI 0 "address_operand" "p")
21142              (const_int 0)
21143              (match_operand:SI 1 "const_int_operand" ""))]
21144   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21145 {
21146   static const char * const patterns[4] = {
21147    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21148   };
21149
21150   int locality = INTVAL (operands[1]);
21151   gcc_assert (locality >= 0 && locality <= 3);
21152
21153   return patterns[locality];
21154 }
21155   [(set_attr "type" "sse")
21156    (set_attr "memory" "none")])
21157
21158 (define_insn "*prefetch_3dnow"
21159   [(prefetch (match_operand:SI 0 "address_operand" "p")
21160              (match_operand:SI 1 "const_int_operand" "n")
21161              (const_int 3))]
21162   "TARGET_3DNOW && !TARGET_64BIT"
21163 {
21164   if (INTVAL (operands[1]) == 0)
21165     return "prefetch\t%a0";
21166   else
21167     return "prefetchw\t%a0";
21168 }
21169   [(set_attr "type" "mmx")
21170    (set_attr "memory" "none")])
21171
21172 (define_insn "*prefetch_3dnow_rex"
21173   [(prefetch (match_operand:DI 0 "address_operand" "p")
21174              (match_operand:SI 1 "const_int_operand" "n")
21175              (const_int 3))]
21176   "TARGET_3DNOW && TARGET_64BIT"
21177 {
21178   if (INTVAL (operands[1]) == 0)
21179     return "prefetch\t%a0";
21180   else
21181     return "prefetchw\t%a0";
21182 }
21183   [(set_attr "type" "mmx")
21184    (set_attr "memory" "none")])
21185
21186 (define_expand "stack_protect_set"
21187   [(match_operand 0 "memory_operand" "")
21188    (match_operand 1 "memory_operand" "")]
21189   ""
21190 {
21191 #ifdef TARGET_THREAD_SSP_OFFSET
21192   if (TARGET_64BIT)
21193     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21194                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21195   else
21196     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21197                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21198 #else
21199   if (TARGET_64BIT)
21200     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21201   else
21202     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21203 #endif
21204   DONE;
21205 })
21206
21207 (define_insn "stack_protect_set_si"
21208   [(set (match_operand:SI 0 "memory_operand" "=m")
21209         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21210    (set (match_scratch:SI 2 "=&r") (const_int 0))
21211    (clobber (reg:CC FLAGS_REG))]
21212   ""
21213   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21214   [(set_attr "type" "multi")])
21215
21216 (define_insn "stack_protect_set_di"
21217   [(set (match_operand:DI 0 "memory_operand" "=m")
21218         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21219    (set (match_scratch:DI 2 "=&r") (const_int 0))
21220    (clobber (reg:CC FLAGS_REG))]
21221   "TARGET_64BIT"
21222   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21223   [(set_attr "type" "multi")])
21224
21225 (define_insn "stack_tls_protect_set_si"
21226   [(set (match_operand:SI 0 "memory_operand" "=m")
21227         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21228    (set (match_scratch:SI 2 "=&r") (const_int 0))
21229    (clobber (reg:CC FLAGS_REG))]
21230   ""
21231   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21232   [(set_attr "type" "multi")])
21233
21234 (define_insn "stack_tls_protect_set_di"
21235   [(set (match_operand:DI 0 "memory_operand" "=m")
21236         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21237    (set (match_scratch:DI 2 "=&r") (const_int 0))
21238    (clobber (reg:CC FLAGS_REG))]
21239   "TARGET_64BIT"
21240   {
21241      /* The kernel uses a different segment register for performance reasons; a
21242         system call would not have to trash the userspace segment register,
21243         which would be expensive */
21244      if (ix86_cmodel != CM_KERNEL)
21245         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21246      else
21247         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21248   }
21249   [(set_attr "type" "multi")])
21250
21251 (define_expand "stack_protect_test"
21252   [(match_operand 0 "memory_operand" "")
21253    (match_operand 1 "memory_operand" "")
21254    (match_operand 2 "" "")]
21255   ""
21256 {
21257   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21258   ix86_compare_op0 = operands[0];
21259   ix86_compare_op1 = operands[1];
21260   ix86_compare_emitted = flags;
21261
21262 #ifdef TARGET_THREAD_SSP_OFFSET
21263   if (TARGET_64BIT)
21264     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21265                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21266   else
21267     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21268                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21269 #else
21270   if (TARGET_64BIT)
21271     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21272   else
21273     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21274 #endif
21275   emit_jump_insn (gen_beq (operands[2]));
21276   DONE;
21277 })
21278
21279 (define_insn "stack_protect_test_si"
21280   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21281         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21282                      (match_operand:SI 2 "memory_operand" "m")]
21283                     UNSPEC_SP_TEST))
21284    (clobber (match_scratch:SI 3 "=&r"))]
21285   ""
21286   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21287   [(set_attr "type" "multi")])
21288
21289 (define_insn "stack_protect_test_di"
21290   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21291         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21292                      (match_operand:DI 2 "memory_operand" "m")]
21293                     UNSPEC_SP_TEST))
21294    (clobber (match_scratch:DI 3 "=&r"))]
21295   "TARGET_64BIT"
21296   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21297   [(set_attr "type" "multi")])
21298
21299 (define_insn "stack_tls_protect_test_si"
21300   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21301         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21302                      (match_operand:SI 2 "const_int_operand" "i")]
21303                     UNSPEC_SP_TLS_TEST))
21304    (clobber (match_scratch:SI 3 "=r"))]
21305   ""
21306   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21307   [(set_attr "type" "multi")])
21308
21309 (define_insn "stack_tls_protect_test_di"
21310   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21311         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21312                      (match_operand:DI 2 "const_int_operand" "i")]
21313                     UNSPEC_SP_TLS_TEST))
21314    (clobber (match_scratch:DI 3 "=r"))]
21315   "TARGET_64BIT"
21316   {
21317      /* The kernel uses a different segment register for performance reasons; a
21318         system call would not have to trash the userspace segment register,
21319         which would be expensive */
21320      if (ix86_cmodel != CM_KERNEL)
21321         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21322      else
21323         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21324   }
21325   [(set_attr "type" "multi")])
21326
21327 (define_mode_iterator CRC32MODE [QI HI SI])
21328 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21329 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21330
21331 (define_insn "sse4_2_crc32<mode>"
21332   [(set (match_operand:SI 0 "register_operand" "=r")
21333         (unspec:SI
21334           [(match_operand:SI 1 "register_operand" "0")
21335            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21336           UNSPEC_CRC32))]
21337   "TARGET_SSE4_2"
21338   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21339   [(set_attr "type" "sselog1")
21340    (set_attr "prefix_rep" "1")
21341    (set_attr "prefix_extra" "1")
21342    (set_attr "mode" "SI")])
21343
21344 (define_insn "sse4_2_crc32di"
21345   [(set (match_operand:DI 0 "register_operand" "=r")
21346         (unspec:DI
21347           [(match_operand:DI 1 "register_operand" "0")
21348            (match_operand:DI 2 "nonimmediate_operand" "rm")]
21349           UNSPEC_CRC32))]
21350   "TARGET_SSE4_2 && TARGET_64BIT"
21351   "crc32q\t{%2, %0|%0, %2}"
21352   [(set_attr "type" "sselog1")
21353    (set_attr "prefix_rep" "1")
21354    (set_attr "prefix_extra" "1")
21355    (set_attr "mode" "DI")])
21356
21357 (include "mmx.md")
21358 (include "sse.md")
21359 (include "sync.md")