OSDN Git Service

PR target/36064
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.  */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
31 ;;     operands[1].
32 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
33 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
34 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
35 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
36 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
37 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
38 ;; 'J' Print the appropriate jump operand.
39 ;;
40 ;; 'b' Print the QImode name of the register for the indicated operand.
41 ;;     %b0 would print %al if operands[0] is reg 0.
42 ;; 'w' Likewise, print the HImode name of the register.
43 ;; 'k' Likewise, print the SImode name of the register.
44 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
45 ;; 'y' Print "st(0)" instead of "st" as a register.
46
47 ;; UNSPEC usage:
48
49 (define_constants
50   [; Relocation specifiers
51    (UNSPEC_GOT                  0)
52    (UNSPEC_GOTOFF               1)
53    (UNSPEC_GOTPCREL             2)
54    (UNSPEC_GOTTPOFF             3)
55    (UNSPEC_TPOFF                4)
56    (UNSPEC_NTPOFF               5)
57    (UNSPEC_DTPOFF               6)
58    (UNSPEC_GOTNTPOFF            7)
59    (UNSPEC_INDNTPOFF            8)
60    (UNSPEC_PLTOFF               9)
61
62    ; Prologue support
63    (UNSPEC_STACK_ALLOC          11)
64    (UNSPEC_SET_GOT              12)
65    (UNSPEC_SSE_PROLOGUE_SAVE    13)
66    (UNSPEC_REG_SAVE             14)
67    (UNSPEC_DEF_CFA              15)
68    (UNSPEC_SET_RIP              16)
69    (UNSPEC_SET_GOT_OFFSET       17)
70
71    ; TLS support
72    (UNSPEC_TP                   18)
73    (UNSPEC_TLS_GD               19)
74    (UNSPEC_TLS_LD_BASE          20)
75    (UNSPEC_TLSDESC              21)
76
77    ; Other random patterns
78    (UNSPEC_SCAS                 30)
79    (UNSPEC_FNSTSW               31)
80    (UNSPEC_SAHF                 32)
81    (UNSPEC_FSTCW                33)
82    (UNSPEC_ADD_CARRY            34)
83    (UNSPEC_FLDCW                35)
84    (UNSPEC_REP                  36)
85    (UNSPEC_EH_RETURN            37)
86    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
87    (UNSPEC_TRUNC_NOOP           39)
88
89    ; For SSE/MMX support:
90    (UNSPEC_FIX_NOTRUNC          40)
91    (UNSPEC_MASKMOV              41)
92    (UNSPEC_MOVMSK               42)
93    (UNSPEC_MOVNT                43)
94    (UNSPEC_MOVU                 44)
95    (UNSPEC_RCP                  45)
96    (UNSPEC_RSQRT                46)
97    (UNSPEC_SFENCE               47)
98    (UNSPEC_PFRCP                49)
99    (UNSPEC_PFRCPIT1             40)
100    (UNSPEC_PFRCPIT2             41)
101    (UNSPEC_PFRSQRT              42)
102    (UNSPEC_PFRSQIT1             43)
103    (UNSPEC_MFENCE               44)
104    (UNSPEC_LFENCE               45)
105    (UNSPEC_PSADBW               46)
106    (UNSPEC_LDDQU                47)
107
108    ; Generic math support
109    (UNSPEC_COPYSIGN             50)
110    (UNSPEC_IEEE_MIN             51)     ; not commutative
111    (UNSPEC_IEEE_MAX             52)     ; not commutative
112
113    ; x87 Floating point
114    (UNSPEC_SIN                  60)
115    (UNSPEC_COS                  61)
116    (UNSPEC_FPATAN               62)
117    (UNSPEC_FYL2X                63)
118    (UNSPEC_FYL2XP1              64)
119    (UNSPEC_FRNDINT              65)
120    (UNSPEC_FIST                 66)
121    (UNSPEC_F2XM1                67)
122    (UNSPEC_TAN                  68)
123    (UNSPEC_FXAM                 69)
124
125    ; x87 Rounding
126    (UNSPEC_FRNDINT_FLOOR        70)
127    (UNSPEC_FRNDINT_CEIL         71)
128    (UNSPEC_FRNDINT_TRUNC        72)
129    (UNSPEC_FRNDINT_MASK_PM      73)
130    (UNSPEC_FIST_FLOOR           74)
131    (UNSPEC_FIST_CEIL            75)
132
133    ; x87 Double output FP
134    (UNSPEC_SINCOS_COS           80)
135    (UNSPEC_SINCOS_SIN           81)
136    (UNSPEC_XTRACT_FRACT         84)
137    (UNSPEC_XTRACT_EXP           85)
138    (UNSPEC_FSCALE_FRACT         86)
139    (UNSPEC_FSCALE_EXP           87)
140    (UNSPEC_FPREM_F              88)
141    (UNSPEC_FPREM_U              89)
142    (UNSPEC_FPREM1_F             90)
143    (UNSPEC_FPREM1_U             91)
144
145    (UNSPEC_C2_FLAG              95)
146
147    ; SSP patterns
148    (UNSPEC_SP_SET               100)
149    (UNSPEC_SP_TEST              101)
150    (UNSPEC_SP_TLS_SET           102)
151    (UNSPEC_SP_TLS_TEST          103)
152
153    ; SSSE3
154    (UNSPEC_PSHUFB               120)
155    (UNSPEC_PSIGN                121)
156    (UNSPEC_PALIGNR              122)
157
158    ; For SSE4A support
159    (UNSPEC_EXTRQI               130)
160    (UNSPEC_EXTRQ                131)
161    (UNSPEC_INSERTQI             132)
162    (UNSPEC_INSERTQ              133)
163
164    ; For SSE4.1 support
165    (UNSPEC_BLENDV               134)
166    (UNSPEC_INSERTPS             135)
167    (UNSPEC_DP                   136)
168    (UNSPEC_MOVNTDQA             137)
169    (UNSPEC_MPSADBW              138)
170    (UNSPEC_PHMINPOSUW           139)
171    (UNSPEC_PTEST                140)
172    (UNSPEC_ROUND                141)
173
174    ; For SSE4.2 support
175    (UNSPEC_CRC32                143)
176    (UNSPEC_PCMPESTR             144)
177    (UNSPEC_PCMPISTR             145)
178
179    ;; For SSE5
180    (UNSPEC_SSE5_INTRINSIC       150)
181    (UNSPEC_SSE5_UNSIGNED_CMP    151)
182    (UNSPEC_SSE5_TRUEFALSE       152)
183    (UNSPEC_SSE5_PERMUTE         153)
184    (UNSPEC_SSE5_ASHIFT          154)
185    (UNSPEC_SSE5_LSHIFT          155)
186    (UNSPEC_FRCZ                 156)
187    (UNSPEC_CVTPH2PS             157)
188    (UNSPEC_CVTPS2PH             158)
189
190    ; For AES support
191    (UNSPEC_AESENC               159)
192    (UNSPEC_AESENCLAST           160)
193    (UNSPEC_AESDEC               161)
194    (UNSPEC_AESDECLAST           162)
195    (UNSPEC_AESIMC               163)
196    (UNSPEC_AESKEYGENASSIST      164)
197
198    ; For PCLMUL support
199    (UNSPEC_PCLMUL               165)
200   ])
201
202 (define_constants
203   [(UNSPECV_BLOCKAGE            0)
204    (UNSPECV_STACK_PROBE         1)
205    (UNSPECV_EMMS                2)
206    (UNSPECV_LDMXCSR             3)
207    (UNSPECV_STMXCSR             4)
208    (UNSPECV_FEMMS               5)
209    (UNSPECV_CLFLUSH             6)
210    (UNSPECV_ALIGN               7)
211    (UNSPECV_MONITOR             8)
212    (UNSPECV_MWAIT               9)
213    (UNSPECV_CMPXCHG_1           10)
214    (UNSPECV_CMPXCHG_2           11)
215    (UNSPECV_XCHG                12)
216    (UNSPECV_LOCK                13)
217    (UNSPECV_PROLOGUE_USE        14)
218   ])
219
220 ;; Constants to represent pcomtrue/pcomfalse variants
221 (define_constants
222   [(PCOM_FALSE                  0)
223    (PCOM_TRUE                   1)
224    (COM_FALSE_S                 2)
225    (COM_FALSE_P                 3)
226    (COM_TRUE_S                  4)
227    (COM_TRUE_P                  5)
228   ])
229
230 ;; Registers by name.
231 (define_constants
232   [(AX_REG                       0)
233    (DX_REG                       1)
234    (CX_REG                       2)
235    (SI_REG                       4)
236    (DI_REG                       5)
237    (BP_REG                       6)
238    (SP_REG                       7)
239    (FLAGS_REG                   17)
240    (FPSR_REG                    18)
241    (FPCR_REG                    19)
242    (R10_REG                     39)
243    (R11_REG                     40)
244   ])
245
246 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
247 ;; from i386.c.
248
249 ;; In C guard expressions, put expressions which may be compile-time
250 ;; constants first.  This allows for better optimization.  For
251 ;; example, write "TARGET_64BIT && reload_completed", not
252 ;; "reload_completed && TARGET_64BIT".
253
254 \f
255 ;; Processor type.  This attribute must exactly match the processor_type
256 ;; enumeration in i386.h.
257 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
258                     nocona,core2,generic32,generic64,amdfam10"
259   (const (symbol_ref "ix86_tune")))
260
261 ;; A basic instruction type.  Refinements due to arguments to be
262 ;; provided in other attributes.
263 (define_attr "type"
264   "other,multi,
265    alu,alu1,negnot,imov,imovx,lea,
266    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
267    icmp,test,ibr,setcc,icmov,
268    push,pop,call,callv,leave,
269    str,bitmanip,
270    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
271    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
272    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
273    ssemuladd,sse4arg,
274    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
275   (const_string "other"))
276
277 ;; Main data type used by the insn
278 (define_attr "mode"
279   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
280   (const_string "unknown"))
281
282 ;; The CPU unit operations uses.
283 (define_attr "unit" "integer,i387,sse,mmx,unknown"
284   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
285            (const_string "i387")
286          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
287                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
288                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
289            (const_string "sse")
290          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
291            (const_string "mmx")
292          (eq_attr "type" "other")
293            (const_string "unknown")]
294          (const_string "integer")))
295
296 ;; The (bounding maximum) length of an instruction immediate.
297 (define_attr "length_immediate" ""
298   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
299                           bitmanip")
300            (const_int 0)
301          (eq_attr "unit" "i387,sse,mmx")
302            (const_int 0)
303          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
304                           imul,icmp,push,pop")
305            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
306          (eq_attr "type" "imov,test")
307            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
308          (eq_attr "type" "call")
309            (if_then_else (match_operand 0 "constant_call_address_operand" "")
310              (const_int 4)
311              (const_int 0))
312          (eq_attr "type" "callv")
313            (if_then_else (match_operand 1 "constant_call_address_operand" "")
314              (const_int 4)
315              (const_int 0))
316          ;; We don't know the size before shorten_branches.  Expect
317          ;; the instruction to fit for better scheduling.
318          (eq_attr "type" "ibr")
319            (const_int 1)
320          ]
321          (symbol_ref "/* Update immediate_length and other attributes! */
322                       gcc_unreachable (),1")))
323
324 ;; The (bounding maximum) length of an instruction address.
325 (define_attr "length_address" ""
326   (cond [(eq_attr "type" "str,other,multi,fxch")
327            (const_int 0)
328          (and (eq_attr "type" "call")
329               (match_operand 0 "constant_call_address_operand" ""))
330              (const_int 0)
331          (and (eq_attr "type" "callv")
332               (match_operand 1 "constant_call_address_operand" ""))
333              (const_int 0)
334          ]
335          (symbol_ref "ix86_attr_length_address_default (insn)")))
336
337 ;; Set when length prefix is used.
338 (define_attr "prefix_data16" ""
339   (if_then_else (ior (eq_attr "mode" "HI")
340                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
341     (const_int 1)
342     (const_int 0)))
343
344 ;; Set when string REP prefix is used.
345 (define_attr "prefix_rep" ""
346   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
347     (const_int 1)
348     (const_int 0)))
349
350 ;; Set when 0f opcode prefix is used.
351 (define_attr "prefix_0f" ""
352   (if_then_else
353     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
354          (eq_attr "unit" "sse,mmx"))
355     (const_int 1)
356     (const_int 0)))
357
358 ;; Set when REX opcode prefix is used.
359 (define_attr "prefix_rex" ""
360   (cond [(and (eq_attr "mode" "DI")
361               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
362            (const_int 1)
363          (and (eq_attr "mode" "QI")
364               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
365                   (const_int 0)))
366            (const_int 1)
367          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
368              (const_int 0))
369            (const_int 1)
370         ]
371         (const_int 0)))
372
373 ;; There are also additional prefixes in SSSE3.
374 (define_attr "prefix_extra" "" (const_int 0))
375
376 ;; Set when modrm byte is used.
377 (define_attr "modrm" ""
378   (cond [(eq_attr "type" "str,leave")
379            (const_int 0)
380          (eq_attr "unit" "i387")
381            (const_int 0)
382          (and (eq_attr "type" "incdec")
383               (ior (match_operand:SI 1 "register_operand" "")
384                    (match_operand:HI 1 "register_operand" "")))
385            (const_int 0)
386          (and (eq_attr "type" "push")
387               (not (match_operand 1 "memory_operand" "")))
388            (const_int 0)
389          (and (eq_attr "type" "pop")
390               (not (match_operand 0 "memory_operand" "")))
391            (const_int 0)
392          (and (eq_attr "type" "imov")
393               (ior (and (match_operand 0 "register_operand" "")
394                         (match_operand 1 "immediate_operand" ""))
395                    (ior (and (match_operand 0 "ax_reg_operand" "")
396                              (match_operand 1 "memory_displacement_only_operand" ""))
397                         (and (match_operand 0 "memory_displacement_only_operand" "")
398                              (match_operand 1 "ax_reg_operand" "")))))
399            (const_int 0)
400          (and (eq_attr "type" "call")
401               (match_operand 0 "constant_call_address_operand" ""))
402              (const_int 0)
403          (and (eq_attr "type" "callv")
404               (match_operand 1 "constant_call_address_operand" ""))
405              (const_int 0)
406          ]
407          (const_int 1)))
408
409 ;; The (bounding maximum) length of an instruction in bytes.
410 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
411 ;; Later we may want to split them and compute proper length as for
412 ;; other insns.
413 (define_attr "length" ""
414   (cond [(eq_attr "type" "other,multi,fistp,frndint")
415            (const_int 16)
416          (eq_attr "type" "fcmp")
417            (const_int 4)
418          (eq_attr "unit" "i387")
419            (plus (const_int 2)
420                  (plus (attr "prefix_data16")
421                        (attr "length_address")))]
422          (plus (plus (attr "modrm")
423                      (plus (attr "prefix_0f")
424                            (plus (attr "prefix_rex")
425                                  (plus (attr "prefix_extra")
426                                        (const_int 1)))))
427                (plus (attr "prefix_rep")
428                      (plus (attr "prefix_data16")
429                            (plus (attr "length_immediate")
430                                  (attr "length_address")))))))
431
432 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
433 ;; `store' if there is a simple memory reference therein, or `unknown'
434 ;; if the instruction is complex.
435
436 (define_attr "memory" "none,load,store,both,unknown"
437   (cond [(eq_attr "type" "other,multi,str")
438            (const_string "unknown")
439          (eq_attr "type" "lea,fcmov,fpspc")
440            (const_string "none")
441          (eq_attr "type" "fistp,leave")
442            (const_string "both")
443          (eq_attr "type" "frndint")
444            (const_string "load")
445          (eq_attr "type" "push")
446            (if_then_else (match_operand 1 "memory_operand" "")
447              (const_string "both")
448              (const_string "store"))
449          (eq_attr "type" "pop")
450            (if_then_else (match_operand 0 "memory_operand" "")
451              (const_string "both")
452              (const_string "load"))
453          (eq_attr "type" "setcc")
454            (if_then_else (match_operand 0 "memory_operand" "")
455              (const_string "store")
456              (const_string "none"))
457          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
458            (if_then_else (ior (match_operand 0 "memory_operand" "")
459                               (match_operand 1 "memory_operand" ""))
460              (const_string "load")
461              (const_string "none"))
462          (eq_attr "type" "ibr")
463            (if_then_else (match_operand 0 "memory_operand" "")
464              (const_string "load")
465              (const_string "none"))
466          (eq_attr "type" "call")
467            (if_then_else (match_operand 0 "constant_call_address_operand" "")
468              (const_string "none")
469              (const_string "load"))
470          (eq_attr "type" "callv")
471            (if_then_else (match_operand 1 "constant_call_address_operand" "")
472              (const_string "none")
473              (const_string "load"))
474          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
475               (match_operand 1 "memory_operand" ""))
476            (const_string "both")
477          (and (match_operand 0 "memory_operand" "")
478               (match_operand 1 "memory_operand" ""))
479            (const_string "both")
480          (match_operand 0 "memory_operand" "")
481            (const_string "store")
482          (match_operand 1 "memory_operand" "")
483            (const_string "load")
484          (and (eq_attr "type"
485                  "!alu1,negnot,ishift1,
486                    imov,imovx,icmp,test,bitmanip,
487                    fmov,fcmp,fsgn,
488                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
489                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
490               (match_operand 2 "memory_operand" ""))
491            (const_string "load")
492          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
493               (match_operand 3 "memory_operand" ""))
494            (const_string "load")
495         ]
496         (const_string "none")))
497
498 ;; Indicates if an instruction has both an immediate and a displacement.
499
500 (define_attr "imm_disp" "false,true,unknown"
501   (cond [(eq_attr "type" "other,multi")
502            (const_string "unknown")
503          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
504               (and (match_operand 0 "memory_displacement_operand" "")
505                    (match_operand 1 "immediate_operand" "")))
506            (const_string "true")
507          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
508               (and (match_operand 0 "memory_displacement_operand" "")
509                    (match_operand 2 "immediate_operand" "")))
510            (const_string "true")
511         ]
512         (const_string "false")))
513
514 ;; Indicates if an FP operation has an integer source.
515
516 (define_attr "fp_int_src" "false,true"
517   (const_string "false"))
518
519 ;; Defines rounding mode of an FP operation.
520
521 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
522   (const_string "any"))
523
524 ;; Describe a user's asm statement.
525 (define_asm_attributes
526   [(set_attr "length" "128")
527    (set_attr "type" "multi")])
528
529 ;; All integer comparison codes.
530 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
531
532 ;; All floating-point comparison codes.
533 (define_code_iterator fp_cond [unordered ordered
534                                uneq unge ungt unle unlt ltgt ])
535
536 (define_code_iterator plusminus [plus minus])
537
538 ;; Base name for define_insn and insn mnemonic.
539 (define_code_attr addsub [(plus "add") (minus "sub")])
540
541 ;; Mark commutative operators as such in constraints.
542 (define_code_attr comm [(plus "%") (minus "")])
543
544 ;; Mapping of signed max and min
545 (define_code_iterator smaxmin [smax smin])
546
547 ;; Mapping of unsigned max and min
548 (define_code_iterator umaxmin [umax umin])
549
550 ;; Base name for integer and FP insn mnemonic
551 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
552                                  (umax "maxu") (umin "minu")])
553 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
554
555 ;; Mapping of parallel logic operators
556 (define_code_iterator plogic [and ior xor])
557
558 ;; Base name for insn mnemonic.
559 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
560
561 ;; Mapping of abs neg operators
562 (define_code_iterator absneg [abs neg])
563
564 ;; Base name for x87 insn mnemonic.
565 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
566
567 ;; All single word integer modes.
568 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
569
570 ;; Instruction suffix for integer modes.
571 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
572
573 ;; Register class for integer modes.
574 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
575
576 ;; Immediate operand constraint for integer modes.
577 (define_mode_attr i [(QI "i") (HI "i") (SI "i") (DI "e")])
578
579 ;; General operand predicate for integer modes.
580 (define_mode_attr general_operand
581         [(QI "general_operand")
582          (HI "general_operand")
583          (SI "general_operand")
584          (DI "x86_64_general_operand")])
585
586 ;; SSE and x87 SFmode and DFmode floating point modes
587 (define_mode_iterator MODEF [SF DF])
588
589 ;; All x87 floating point modes
590 (define_mode_iterator X87MODEF [SF DF XF])
591
592 ;; All integer modes handled by x87 fisttp operator.
593 (define_mode_iterator X87MODEI [HI SI DI])
594
595 ;; All integer modes handled by integer x87 operators.
596 (define_mode_iterator X87MODEI12 [HI SI])
597
598 ;; All integer modes handled by SSE cvtts?2si* operators.
599 (define_mode_iterator SSEMODEI24 [SI DI])
600
601 ;; SSE asm suffix for floating point modes
602 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
603
604 ;; SSE vector mode corresponding to a scalar mode
605 (define_mode_attr ssevecmode
606   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
607
608 ;; Instruction suffix for REX 64bit operators.
609 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
610 \f
611 ;; Scheduling descriptions
612
613 (include "pentium.md")
614 (include "ppro.md")
615 (include "k6.md")
616 (include "athlon.md")
617 (include "geode.md")
618
619 \f
620 ;; Operand and operator predicates and constraints
621
622 (include "predicates.md")
623 (include "constraints.md")
624
625 \f
626 ;; Compare instructions.
627
628 ;; All compare insns have expanders that save the operands away without
629 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
630 ;; after the cmp) will actually emit the cmpM.
631
632 (define_expand "cmpti"
633   [(set (reg:CC FLAGS_REG)
634         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
635                     (match_operand:TI 1 "x86_64_general_operand" "")))]
636   "TARGET_64BIT"
637 {
638   if (MEM_P (operands[0]) && MEM_P (operands[1]))
639     operands[0] = force_reg (TImode, operands[0]);
640   ix86_compare_op0 = operands[0];
641   ix86_compare_op1 = operands[1];
642   DONE;
643 })
644
645 (define_expand "cmpdi"
646   [(set (reg:CC FLAGS_REG)
647         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
648                     (match_operand:DI 1 "x86_64_general_operand" "")))]
649   ""
650 {
651   if (MEM_P (operands[0]) && MEM_P (operands[1]))
652     operands[0] = force_reg (DImode, operands[0]);
653   ix86_compare_op0 = operands[0];
654   ix86_compare_op1 = operands[1];
655   DONE;
656 })
657
658 (define_expand "cmpsi"
659   [(set (reg:CC FLAGS_REG)
660         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
661                     (match_operand:SI 1 "general_operand" "")))]
662   ""
663 {
664   if (MEM_P (operands[0]) && MEM_P (operands[1]))
665     operands[0] = force_reg (SImode, operands[0]);
666   ix86_compare_op0 = operands[0];
667   ix86_compare_op1 = operands[1];
668   DONE;
669 })
670
671 (define_expand "cmphi"
672   [(set (reg:CC FLAGS_REG)
673         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
674                     (match_operand:HI 1 "general_operand" "")))]
675   ""
676 {
677   if (MEM_P (operands[0]) && MEM_P (operands[1]))
678     operands[0] = force_reg (HImode, operands[0]);
679   ix86_compare_op0 = operands[0];
680   ix86_compare_op1 = operands[1];
681   DONE;
682 })
683
684 (define_expand "cmpqi"
685   [(set (reg:CC FLAGS_REG)
686         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
687                     (match_operand:QI 1 "general_operand" "")))]
688   "TARGET_QIMODE_MATH"
689 {
690   if (MEM_P (operands[0]) && MEM_P (operands[1]))
691     operands[0] = force_reg (QImode, operands[0]);
692   ix86_compare_op0 = operands[0];
693   ix86_compare_op1 = operands[1];
694   DONE;
695 })
696
697 (define_insn "cmpdi_ccno_1_rex64"
698   [(set (reg FLAGS_REG)
699         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
700                  (match_operand:DI 1 "const0_operand" "n,n")))]
701   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
702   "@
703    test{q}\t%0, %0
704    cmp{q}\t{%1, %0|%0, %1}"
705   [(set_attr "type" "test,icmp")
706    (set_attr "length_immediate" "0,1")
707    (set_attr "mode" "DI")])
708
709 (define_insn "*cmpdi_minus_1_rex64"
710   [(set (reg FLAGS_REG)
711         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
712                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
713                  (const_int 0)))]
714   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
715   "cmp{q}\t{%1, %0|%0, %1}"
716   [(set_attr "type" "icmp")
717    (set_attr "mode" "DI")])
718
719 (define_expand "cmpdi_1_rex64"
720   [(set (reg:CC FLAGS_REG)
721         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
722                     (match_operand:DI 1 "general_operand" "")))]
723   "TARGET_64BIT"
724   "")
725
726 (define_insn "cmpdi_1_insn_rex64"
727   [(set (reg FLAGS_REG)
728         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
729                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
730   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
731   "cmp{q}\t{%1, %0|%0, %1}"
732   [(set_attr "type" "icmp")
733    (set_attr "mode" "DI")])
734
735
736 (define_insn "*cmpsi_ccno_1"
737   [(set (reg FLAGS_REG)
738         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
739                  (match_operand:SI 1 "const0_operand" "n,n")))]
740   "ix86_match_ccmode (insn, CCNOmode)"
741   "@
742    test{l}\t%0, %0
743    cmp{l}\t{%1, %0|%0, %1}"
744   [(set_attr "type" "test,icmp")
745    (set_attr "length_immediate" "0,1")
746    (set_attr "mode" "SI")])
747
748 (define_insn "*cmpsi_minus_1"
749   [(set (reg FLAGS_REG)
750         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
751                            (match_operand:SI 1 "general_operand" "ri,mr"))
752                  (const_int 0)))]
753   "ix86_match_ccmode (insn, CCGOCmode)"
754   "cmp{l}\t{%1, %0|%0, %1}"
755   [(set_attr "type" "icmp")
756    (set_attr "mode" "SI")])
757
758 (define_expand "cmpsi_1"
759   [(set (reg:CC FLAGS_REG)
760         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
761                     (match_operand:SI 1 "general_operand" "")))]
762   ""
763   "")
764
765 (define_insn "*cmpsi_1_insn"
766   [(set (reg FLAGS_REG)
767         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
768                  (match_operand:SI 1 "general_operand" "ri,mr")))]
769   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
770     && ix86_match_ccmode (insn, CCmode)"
771   "cmp{l}\t{%1, %0|%0, %1}"
772   [(set_attr "type" "icmp")
773    (set_attr "mode" "SI")])
774
775 (define_insn "*cmphi_ccno_1"
776   [(set (reg FLAGS_REG)
777         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
778                  (match_operand:HI 1 "const0_operand" "n,n")))]
779   "ix86_match_ccmode (insn, CCNOmode)"
780   "@
781    test{w}\t%0, %0
782    cmp{w}\t{%1, %0|%0, %1}"
783   [(set_attr "type" "test,icmp")
784    (set_attr "length_immediate" "0,1")
785    (set_attr "mode" "HI")])
786
787 (define_insn "*cmphi_minus_1"
788   [(set (reg FLAGS_REG)
789         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
790                            (match_operand:HI 1 "general_operand" "ri,mr"))
791                  (const_int 0)))]
792   "ix86_match_ccmode (insn, CCGOCmode)"
793   "cmp{w}\t{%1, %0|%0, %1}"
794   [(set_attr "type" "icmp")
795    (set_attr "mode" "HI")])
796
797 (define_insn "*cmphi_1"
798   [(set (reg FLAGS_REG)
799         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
800                  (match_operand:HI 1 "general_operand" "ri,mr")))]
801   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
802    && ix86_match_ccmode (insn, CCmode)"
803   "cmp{w}\t{%1, %0|%0, %1}"
804   [(set_attr "type" "icmp")
805    (set_attr "mode" "HI")])
806
807 (define_insn "*cmpqi_ccno_1"
808   [(set (reg FLAGS_REG)
809         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
810                  (match_operand:QI 1 "const0_operand" "n,n")))]
811   "ix86_match_ccmode (insn, CCNOmode)"
812   "@
813    test{b}\t%0, %0
814    cmp{b}\t{$0, %0|%0, 0}"
815   [(set_attr "type" "test,icmp")
816    (set_attr "length_immediate" "0,1")
817    (set_attr "mode" "QI")])
818
819 (define_insn "*cmpqi_1"
820   [(set (reg FLAGS_REG)
821         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
822                  (match_operand:QI 1 "general_operand" "qi,mq")))]
823   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
824     && ix86_match_ccmode (insn, CCmode)"
825   "cmp{b}\t{%1, %0|%0, %1}"
826   [(set_attr "type" "icmp")
827    (set_attr "mode" "QI")])
828
829 (define_insn "*cmpqi_minus_1"
830   [(set (reg FLAGS_REG)
831         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
832                            (match_operand:QI 1 "general_operand" "qi,mq"))
833                  (const_int 0)))]
834   "ix86_match_ccmode (insn, CCGOCmode)"
835   "cmp{b}\t{%1, %0|%0, %1}"
836   [(set_attr "type" "icmp")
837    (set_attr "mode" "QI")])
838
839 (define_insn "*cmpqi_ext_1"
840   [(set (reg FLAGS_REG)
841         (compare
842           (match_operand:QI 0 "general_operand" "Qm")
843           (subreg:QI
844             (zero_extract:SI
845               (match_operand 1 "ext_register_operand" "Q")
846               (const_int 8)
847               (const_int 8)) 0)))]
848   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
849   "cmp{b}\t{%h1, %0|%0, %h1}"
850   [(set_attr "type" "icmp")
851    (set_attr "mode" "QI")])
852
853 (define_insn "*cmpqi_ext_1_rex64"
854   [(set (reg FLAGS_REG)
855         (compare
856           (match_operand:QI 0 "register_operand" "Q")
857           (subreg:QI
858             (zero_extract:SI
859               (match_operand 1 "ext_register_operand" "Q")
860               (const_int 8)
861               (const_int 8)) 0)))]
862   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
863   "cmp{b}\t{%h1, %0|%0, %h1}"
864   [(set_attr "type" "icmp")
865    (set_attr "mode" "QI")])
866
867 (define_insn "*cmpqi_ext_2"
868   [(set (reg FLAGS_REG)
869         (compare
870           (subreg:QI
871             (zero_extract:SI
872               (match_operand 0 "ext_register_operand" "Q")
873               (const_int 8)
874               (const_int 8)) 0)
875           (match_operand:QI 1 "const0_operand" "n")))]
876   "ix86_match_ccmode (insn, CCNOmode)"
877   "test{b}\t%h0, %h0"
878   [(set_attr "type" "test")
879    (set_attr "length_immediate" "0")
880    (set_attr "mode" "QI")])
881
882 (define_expand "cmpqi_ext_3"
883   [(set (reg:CC FLAGS_REG)
884         (compare:CC
885           (subreg:QI
886             (zero_extract:SI
887               (match_operand 0 "ext_register_operand" "")
888               (const_int 8)
889               (const_int 8)) 0)
890           (match_operand:QI 1 "general_operand" "")))]
891   ""
892   "")
893
894 (define_insn "cmpqi_ext_3_insn"
895   [(set (reg FLAGS_REG)
896         (compare
897           (subreg:QI
898             (zero_extract:SI
899               (match_operand 0 "ext_register_operand" "Q")
900               (const_int 8)
901               (const_int 8)) 0)
902           (match_operand:QI 1 "general_operand" "Qmn")))]
903   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
904   "cmp{b}\t{%1, %h0|%h0, %1}"
905   [(set_attr "type" "icmp")
906    (set_attr "mode" "QI")])
907
908 (define_insn "cmpqi_ext_3_insn_rex64"
909   [(set (reg FLAGS_REG)
910         (compare
911           (subreg:QI
912             (zero_extract:SI
913               (match_operand 0 "ext_register_operand" "Q")
914               (const_int 8)
915               (const_int 8)) 0)
916           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
917   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
918   "cmp{b}\t{%1, %h0|%h0, %1}"
919   [(set_attr "type" "icmp")
920    (set_attr "mode" "QI")])
921
922 (define_insn "*cmpqi_ext_4"
923   [(set (reg FLAGS_REG)
924         (compare
925           (subreg:QI
926             (zero_extract:SI
927               (match_operand 0 "ext_register_operand" "Q")
928               (const_int 8)
929               (const_int 8)) 0)
930           (subreg:QI
931             (zero_extract:SI
932               (match_operand 1 "ext_register_operand" "Q")
933               (const_int 8)
934               (const_int 8)) 0)))]
935   "ix86_match_ccmode (insn, CCmode)"
936   "cmp{b}\t{%h1, %h0|%h0, %h1}"
937   [(set_attr "type" "icmp")
938    (set_attr "mode" "QI")])
939
940 ;; These implement float point compares.
941 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
942 ;; which would allow mix and match FP modes on the compares.  Which is what
943 ;; the old patterns did, but with many more of them.
944
945 (define_expand "cmpxf"
946   [(set (reg:CC FLAGS_REG)
947         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
948                     (match_operand:XF 1 "nonmemory_operand" "")))]
949   "TARGET_80387"
950 {
951   ix86_compare_op0 = operands[0];
952   ix86_compare_op1 = operands[1];
953   DONE;
954 })
955
956 (define_expand "cmp<mode>"
957   [(set (reg:CC FLAGS_REG)
958         (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
959                     (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
960   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
961 {
962   ix86_compare_op0 = operands[0];
963   ix86_compare_op1 = operands[1];
964   DONE;
965 })
966
967 ;; FP compares, step 1:
968 ;; Set the FP condition codes.
969 ;;
970 ;; CCFPmode     compare with exceptions
971 ;; CCFPUmode    compare with no exceptions
972
973 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
974 ;; used to manage the reg stack popping would not be preserved.
975
976 (define_insn "*cmpfp_0"
977   [(set (match_operand:HI 0 "register_operand" "=a")
978         (unspec:HI
979           [(compare:CCFP
980              (match_operand 1 "register_operand" "f")
981              (match_operand 2 "const0_operand" "X"))]
982         UNSPEC_FNSTSW))]
983   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
984    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
985   "* return output_fp_compare (insn, operands, 0, 0);"
986   [(set_attr "type" "multi")
987    (set_attr "unit" "i387")
988    (set (attr "mode")
989      (cond [(match_operand:SF 1 "" "")
990               (const_string "SF")
991             (match_operand:DF 1 "" "")
992               (const_string "DF")
993            ]
994            (const_string "XF")))])
995
996 (define_insn_and_split "*cmpfp_0_cc"
997   [(set (reg:CCFP FLAGS_REG)
998         (compare:CCFP
999           (match_operand 1 "register_operand" "f")
1000           (match_operand 2 "const0_operand" "X")))
1001    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1002   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1003    && TARGET_SAHF && !TARGET_CMOVE
1004    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1005   "#"
1006   "&& reload_completed"
1007   [(set (match_dup 0)
1008         (unspec:HI
1009           [(compare:CCFP (match_dup 1)(match_dup 2))]
1010         UNSPEC_FNSTSW))
1011    (set (reg:CC FLAGS_REG)
1012         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1013   ""
1014   [(set_attr "type" "multi")
1015    (set_attr "unit" "i387")
1016    (set (attr "mode")
1017      (cond [(match_operand:SF 1 "" "")
1018               (const_string "SF")
1019             (match_operand:DF 1 "" "")
1020               (const_string "DF")
1021            ]
1022            (const_string "XF")))])
1023
1024 (define_insn "*cmpfp_xf"
1025   [(set (match_operand:HI 0 "register_operand" "=a")
1026         (unspec:HI
1027           [(compare:CCFP
1028              (match_operand:XF 1 "register_operand" "f")
1029              (match_operand:XF 2 "register_operand" "f"))]
1030           UNSPEC_FNSTSW))]
1031   "TARGET_80387"
1032   "* return output_fp_compare (insn, operands, 0, 0);"
1033   [(set_attr "type" "multi")
1034    (set_attr "unit" "i387")
1035    (set_attr "mode" "XF")])
1036
1037 (define_insn_and_split "*cmpfp_xf_cc"
1038   [(set (reg:CCFP FLAGS_REG)
1039         (compare:CCFP
1040           (match_operand:XF 1 "register_operand" "f")
1041           (match_operand:XF 2 "register_operand" "f")))
1042    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1043   "TARGET_80387
1044    && TARGET_SAHF && !TARGET_CMOVE"
1045   "#"
1046   "&& reload_completed"
1047   [(set (match_dup 0)
1048         (unspec:HI
1049           [(compare:CCFP (match_dup 1)(match_dup 2))]
1050         UNSPEC_FNSTSW))
1051    (set (reg:CC FLAGS_REG)
1052         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1053   ""
1054   [(set_attr "type" "multi")
1055    (set_attr "unit" "i387")
1056    (set_attr "mode" "XF")])
1057
1058 (define_insn "*cmpfp_<mode>"
1059   [(set (match_operand:HI 0 "register_operand" "=a")
1060         (unspec:HI
1061           [(compare:CCFP
1062              (match_operand:MODEF 1 "register_operand" "f")
1063              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1064           UNSPEC_FNSTSW))]
1065   "TARGET_80387"
1066   "* return output_fp_compare (insn, operands, 0, 0);"
1067   [(set_attr "type" "multi")
1068    (set_attr "unit" "i387")
1069    (set_attr "mode" "<MODE>")])
1070
1071 (define_insn_and_split "*cmpfp_<mode>_cc"
1072   [(set (reg:CCFP FLAGS_REG)
1073         (compare:CCFP
1074           (match_operand:MODEF 1 "register_operand" "f")
1075           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1076    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1077   "TARGET_80387
1078    && TARGET_SAHF && !TARGET_CMOVE"
1079   "#"
1080   "&& reload_completed"
1081   [(set (match_dup 0)
1082         (unspec:HI
1083           [(compare:CCFP (match_dup 1)(match_dup 2))]
1084         UNSPEC_FNSTSW))
1085    (set (reg:CC FLAGS_REG)
1086         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1087   ""
1088   [(set_attr "type" "multi")
1089    (set_attr "unit" "i387")
1090    (set_attr "mode" "<MODE>")])
1091
1092 (define_insn "*cmpfp_u"
1093   [(set (match_operand:HI 0 "register_operand" "=a")
1094         (unspec:HI
1095           [(compare:CCFPU
1096              (match_operand 1 "register_operand" "f")
1097              (match_operand 2 "register_operand" "f"))]
1098           UNSPEC_FNSTSW))]
1099   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1100    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1101   "* return output_fp_compare (insn, operands, 0, 1);"
1102   [(set_attr "type" "multi")
1103    (set_attr "unit" "i387")
1104    (set (attr "mode")
1105      (cond [(match_operand:SF 1 "" "")
1106               (const_string "SF")
1107             (match_operand:DF 1 "" "")
1108               (const_string "DF")
1109            ]
1110            (const_string "XF")))])
1111
1112 (define_insn_and_split "*cmpfp_u_cc"
1113   [(set (reg:CCFPU FLAGS_REG)
1114         (compare:CCFPU
1115           (match_operand 1 "register_operand" "f")
1116           (match_operand 2 "register_operand" "f")))
1117    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1118   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1119    && TARGET_SAHF && !TARGET_CMOVE
1120    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1121   "#"
1122   "&& reload_completed"
1123   [(set (match_dup 0)
1124         (unspec:HI
1125           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1126         UNSPEC_FNSTSW))
1127    (set (reg:CC FLAGS_REG)
1128         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1129   ""
1130   [(set_attr "type" "multi")
1131    (set_attr "unit" "i387")
1132    (set (attr "mode")
1133      (cond [(match_operand:SF 1 "" "")
1134               (const_string "SF")
1135             (match_operand:DF 1 "" "")
1136               (const_string "DF")
1137            ]
1138            (const_string "XF")))])
1139
1140 (define_insn "*cmpfp_<mode>"
1141   [(set (match_operand:HI 0 "register_operand" "=a")
1142         (unspec:HI
1143           [(compare:CCFP
1144              (match_operand 1 "register_operand" "f")
1145              (match_operator 3 "float_operator"
1146                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1147           UNSPEC_FNSTSW))]
1148   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1149    && TARGET_USE_<MODE>MODE_FIOP
1150    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1151   "* return output_fp_compare (insn, operands, 0, 0);"
1152   [(set_attr "type" "multi")
1153    (set_attr "unit" "i387")
1154    (set_attr "fp_int_src" "true")
1155    (set_attr "mode" "<MODE>")])
1156
1157 (define_insn_and_split "*cmpfp_<mode>_cc"
1158   [(set (reg:CCFP FLAGS_REG)
1159         (compare:CCFP
1160           (match_operand 1 "register_operand" "f")
1161           (match_operator 3 "float_operator"
1162             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1163    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1164   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1165    && TARGET_SAHF && !TARGET_CMOVE
1166    && TARGET_USE_<MODE>MODE_FIOP
1167    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1168   "#"
1169   "&& reload_completed"
1170   [(set (match_dup 0)
1171         (unspec:HI
1172           [(compare:CCFP
1173              (match_dup 1)
1174              (match_op_dup 3 [(match_dup 2)]))]
1175         UNSPEC_FNSTSW))
1176    (set (reg:CC FLAGS_REG)
1177         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1178   ""
1179   [(set_attr "type" "multi")
1180    (set_attr "unit" "i387")
1181    (set_attr "fp_int_src" "true")
1182    (set_attr "mode" "<MODE>")])
1183
1184 ;; FP compares, step 2
1185 ;; Move the fpsw to ax.
1186
1187 (define_insn "x86_fnstsw_1"
1188   [(set (match_operand:HI 0 "register_operand" "=a")
1189         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1190   "TARGET_80387"
1191   "fnstsw\t%0"
1192   [(set_attr "length" "2")
1193    (set_attr "mode" "SI")
1194    (set_attr "unit" "i387")])
1195
1196 ;; FP compares, step 3
1197 ;; Get ax into flags, general case.
1198
1199 (define_insn "x86_sahf_1"
1200   [(set (reg:CC FLAGS_REG)
1201         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1202                    UNSPEC_SAHF))]
1203   "TARGET_SAHF"
1204 {
1205 #ifdef HAVE_AS_IX86_SAHF
1206   return "sahf";
1207 #else
1208   return ".byte\t0x9e";
1209 #endif
1210 }
1211   [(set_attr "length" "1")
1212    (set_attr "athlon_decode" "vector")
1213    (set_attr "amdfam10_decode" "direct")
1214    (set_attr "mode" "SI")])
1215
1216 ;; Pentium Pro can do steps 1 through 3 in one go.
1217 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1218 (define_insn "*cmpfp_i_mixed"
1219   [(set (reg:CCFP FLAGS_REG)
1220         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1221                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1222   "TARGET_MIX_SSE_I387
1223    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1224    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1225   "* return output_fp_compare (insn, operands, 1, 0);"
1226   [(set_attr "type" "fcmp,ssecomi")
1227    (set (attr "mode")
1228      (if_then_else (match_operand:SF 1 "" "")
1229         (const_string "SF")
1230         (const_string "DF")))
1231    (set_attr "athlon_decode" "vector")
1232    (set_attr "amdfam10_decode" "direct")])
1233
1234 (define_insn "*cmpfp_i_sse"
1235   [(set (reg:CCFP FLAGS_REG)
1236         (compare:CCFP (match_operand 0 "register_operand" "x")
1237                       (match_operand 1 "nonimmediate_operand" "xm")))]
1238   "TARGET_SSE_MATH
1239    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1240    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1241   "* return output_fp_compare (insn, operands, 1, 0);"
1242   [(set_attr "type" "ssecomi")
1243    (set (attr "mode")
1244      (if_then_else (match_operand:SF 1 "" "")
1245         (const_string "SF")
1246         (const_string "DF")))
1247    (set_attr "athlon_decode" "vector")
1248    (set_attr "amdfam10_decode" "direct")])
1249
1250 (define_insn "*cmpfp_i_i387"
1251   [(set (reg:CCFP FLAGS_REG)
1252         (compare:CCFP (match_operand 0 "register_operand" "f")
1253                       (match_operand 1 "register_operand" "f")))]
1254   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1255    && TARGET_CMOVE
1256    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1257    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1258   "* return output_fp_compare (insn, operands, 1, 0);"
1259   [(set_attr "type" "fcmp")
1260    (set (attr "mode")
1261      (cond [(match_operand:SF 1 "" "")
1262               (const_string "SF")
1263             (match_operand:DF 1 "" "")
1264               (const_string "DF")
1265            ]
1266            (const_string "XF")))
1267    (set_attr "athlon_decode" "vector")
1268    (set_attr "amdfam10_decode" "direct")])
1269
1270 (define_insn "*cmpfp_iu_mixed"
1271   [(set (reg:CCFPU FLAGS_REG)
1272         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1273                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1274   "TARGET_MIX_SSE_I387
1275    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1276    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1277   "* return output_fp_compare (insn, operands, 1, 1);"
1278   [(set_attr "type" "fcmp,ssecomi")
1279    (set (attr "mode")
1280      (if_then_else (match_operand:SF 1 "" "")
1281         (const_string "SF")
1282         (const_string "DF")))
1283    (set_attr "athlon_decode" "vector")
1284    (set_attr "amdfam10_decode" "direct")])
1285
1286 (define_insn "*cmpfp_iu_sse"
1287   [(set (reg:CCFPU FLAGS_REG)
1288         (compare:CCFPU (match_operand 0 "register_operand" "x")
1289                        (match_operand 1 "nonimmediate_operand" "xm")))]
1290   "TARGET_SSE_MATH
1291    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1292    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1293   "* return output_fp_compare (insn, operands, 1, 1);"
1294   [(set_attr "type" "ssecomi")
1295    (set (attr "mode")
1296      (if_then_else (match_operand:SF 1 "" "")
1297         (const_string "SF")
1298         (const_string "DF")))
1299    (set_attr "athlon_decode" "vector")
1300    (set_attr "amdfam10_decode" "direct")])
1301
1302 (define_insn "*cmpfp_iu_387"
1303   [(set (reg:CCFPU FLAGS_REG)
1304         (compare:CCFPU (match_operand 0 "register_operand" "f")
1305                        (match_operand 1 "register_operand" "f")))]
1306   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1307    && TARGET_CMOVE
1308    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1309    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1310   "* return output_fp_compare (insn, operands, 1, 1);"
1311   [(set_attr "type" "fcmp")
1312    (set (attr "mode")
1313      (cond [(match_operand:SF 1 "" "")
1314               (const_string "SF")
1315             (match_operand:DF 1 "" "")
1316               (const_string "DF")
1317            ]
1318            (const_string "XF")))
1319    (set_attr "athlon_decode" "vector")
1320    (set_attr "amdfam10_decode" "direct")])
1321 \f
1322 ;; Move instructions.
1323
1324 ;; General case of fullword move.
1325
1326 (define_expand "movsi"
1327   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1328         (match_operand:SI 1 "general_operand" ""))]
1329   ""
1330   "ix86_expand_move (SImode, operands); DONE;")
1331
1332 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1333 ;; general_operand.
1334 ;;
1335 ;; %%% We don't use a post-inc memory reference because x86 is not a
1336 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1337 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1338 ;; targets without our curiosities, and it is just as easy to represent
1339 ;; this differently.
1340
1341 (define_insn "*pushsi2"
1342   [(set (match_operand:SI 0 "push_operand" "=<")
1343         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1344   "!TARGET_64BIT"
1345   "push{l}\t%1"
1346   [(set_attr "type" "push")
1347    (set_attr "mode" "SI")])
1348
1349 ;; For 64BIT abi we always round up to 8 bytes.
1350 (define_insn "*pushsi2_rex64"
1351   [(set (match_operand:SI 0 "push_operand" "=X")
1352         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1353   "TARGET_64BIT"
1354   "push{q}\t%q1"
1355   [(set_attr "type" "push")
1356    (set_attr "mode" "SI")])
1357
1358 (define_insn "*pushsi2_prologue"
1359   [(set (match_operand:SI 0 "push_operand" "=<")
1360         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1361    (clobber (mem:BLK (scratch)))]
1362   "!TARGET_64BIT"
1363   "push{l}\t%1"
1364   [(set_attr "type" "push")
1365    (set_attr "mode" "SI")])
1366
1367 (define_insn "*popsi1_epilogue"
1368   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1369         (mem:SI (reg:SI SP_REG)))
1370    (set (reg:SI SP_REG)
1371         (plus:SI (reg:SI SP_REG) (const_int 4)))
1372    (clobber (mem:BLK (scratch)))]
1373   "!TARGET_64BIT"
1374   "pop{l}\t%0"
1375   [(set_attr "type" "pop")
1376    (set_attr "mode" "SI")])
1377
1378 (define_insn "popsi1"
1379   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1380         (mem:SI (reg:SI SP_REG)))
1381    (set (reg:SI SP_REG)
1382         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1383   "!TARGET_64BIT"
1384   "pop{l}\t%0"
1385   [(set_attr "type" "pop")
1386    (set_attr "mode" "SI")])
1387
1388 (define_insn "*movsi_xor"
1389   [(set (match_operand:SI 0 "register_operand" "=r")
1390         (match_operand:SI 1 "const0_operand" "i"))
1391    (clobber (reg:CC FLAGS_REG))]
1392   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1393   "xor{l}\t%0, %0"
1394   [(set_attr "type" "alu1")
1395    (set_attr "mode" "SI")
1396    (set_attr "length_immediate" "0")])
1397
1398 (define_insn "*movsi_or"
1399   [(set (match_operand:SI 0 "register_operand" "=r")
1400         (match_operand:SI 1 "immediate_operand" "i"))
1401    (clobber (reg:CC FLAGS_REG))]
1402   "reload_completed
1403    && operands[1] == constm1_rtx
1404    && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1405 {
1406   operands[1] = constm1_rtx;
1407   return "or{l}\t{%1, %0|%0, %1}";
1408 }
1409   [(set_attr "type" "alu1")
1410    (set_attr "mode" "SI")
1411    (set_attr "length_immediate" "1")])
1412
1413 (define_insn "*movsi_1"
1414   [(set (match_operand:SI 0 "nonimmediate_operand"
1415                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1416         (match_operand:SI 1 "general_operand"
1417                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1418   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1419 {
1420   switch (get_attr_type (insn))
1421     {
1422     case TYPE_SSELOG1:
1423       if (get_attr_mode (insn) == MODE_TI)
1424         return "pxor\t%0, %0";
1425       return "xorps\t%0, %0";
1426
1427     case TYPE_SSEMOV:
1428       switch (get_attr_mode (insn))
1429         {
1430         case MODE_TI:
1431           return "movdqa\t{%1, %0|%0, %1}";
1432         case MODE_V4SF:
1433           return "movaps\t{%1, %0|%0, %1}";
1434         case MODE_SI:
1435           return "movd\t{%1, %0|%0, %1}";
1436         case MODE_SF:
1437           return "movss\t{%1, %0|%0, %1}";
1438         default:
1439           gcc_unreachable ();
1440         }
1441
1442     case TYPE_MMXADD:
1443       return "pxor\t%0, %0";
1444
1445     case TYPE_MMXMOV:
1446       if (get_attr_mode (insn) == MODE_DI)
1447         return "movq\t{%1, %0|%0, %1}";
1448       return "movd\t{%1, %0|%0, %1}";
1449
1450     case TYPE_LEA:
1451       return "lea{l}\t{%1, %0|%0, %1}";
1452
1453     default:
1454       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1455       return "mov{l}\t{%1, %0|%0, %1}";
1456     }
1457 }
1458   [(set (attr "type")
1459      (cond [(eq_attr "alternative" "2")
1460               (const_string "mmxadd")
1461             (eq_attr "alternative" "3,4,5")
1462               (const_string "mmxmov")
1463             (eq_attr "alternative" "6")
1464               (const_string "sselog1")
1465             (eq_attr "alternative" "7,8,9,10,11")
1466               (const_string "ssemov")
1467             (match_operand:DI 1 "pic_32bit_operand" "")
1468               (const_string "lea")
1469            ]
1470            (const_string "imov")))
1471    (set (attr "mode")
1472      (cond [(eq_attr "alternative" "2,3")
1473               (const_string "DI")
1474             (eq_attr "alternative" "6,7")
1475               (if_then_else
1476                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1477                 (const_string "V4SF")
1478                 (const_string "TI"))
1479             (and (eq_attr "alternative" "8,9,10,11")
1480                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1481               (const_string "SF")
1482            ]
1483            (const_string "SI")))])
1484
1485 ;; Stores and loads of ax to arbitrary constant address.
1486 ;; We fake an second form of instruction to force reload to load address
1487 ;; into register when rax is not available
1488 (define_insn "*movabssi_1_rex64"
1489   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1490         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1491   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1492   "@
1493    movabs{l}\t{%1, %P0|%P0, %1}
1494    mov{l}\t{%1, %a0|%a0, %1}"
1495   [(set_attr "type" "imov")
1496    (set_attr "modrm" "0,*")
1497    (set_attr "length_address" "8,0")
1498    (set_attr "length_immediate" "0,*")
1499    (set_attr "memory" "store")
1500    (set_attr "mode" "SI")])
1501
1502 (define_insn "*movabssi_2_rex64"
1503   [(set (match_operand:SI 0 "register_operand" "=a,r")
1504         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1505   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1506   "@
1507    movabs{l}\t{%P1, %0|%0, %P1}
1508    mov{l}\t{%a1, %0|%0, %a1}"
1509   [(set_attr "type" "imov")
1510    (set_attr "modrm" "0,*")
1511    (set_attr "length_address" "8,0")
1512    (set_attr "length_immediate" "0")
1513    (set_attr "memory" "load")
1514    (set_attr "mode" "SI")])
1515
1516 (define_insn "*swapsi"
1517   [(set (match_operand:SI 0 "register_operand" "+r")
1518         (match_operand:SI 1 "register_operand" "+r"))
1519    (set (match_dup 1)
1520         (match_dup 0))]
1521   ""
1522   "xchg{l}\t%1, %0"
1523   [(set_attr "type" "imov")
1524    (set_attr "mode" "SI")
1525    (set_attr "pent_pair" "np")
1526    (set_attr "athlon_decode" "vector")
1527    (set_attr "amdfam10_decode" "double")])
1528
1529 (define_expand "movhi"
1530   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1531         (match_operand:HI 1 "general_operand" ""))]
1532   ""
1533   "ix86_expand_move (HImode, operands); DONE;")
1534
1535 (define_insn "*pushhi2"
1536   [(set (match_operand:HI 0 "push_operand" "=X")
1537         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1538   "!TARGET_64BIT"
1539   "push{l}\t%k1"
1540   [(set_attr "type" "push")
1541    (set_attr "mode" "SI")])
1542
1543 ;; For 64BIT abi we always round up to 8 bytes.
1544 (define_insn "*pushhi2_rex64"
1545   [(set (match_operand:HI 0 "push_operand" "=X")
1546         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1547   "TARGET_64BIT"
1548   "push{q}\t%q1"
1549   [(set_attr "type" "push")
1550    (set_attr "mode" "DI")])
1551
1552 (define_insn "*movhi_1"
1553   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1554         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1555   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1556 {
1557   switch (get_attr_type (insn))
1558     {
1559     case TYPE_IMOVX:
1560       /* movzwl is faster than movw on p2 due to partial word stalls,
1561          though not as fast as an aligned movl.  */
1562       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1563     default:
1564       if (get_attr_mode (insn) == MODE_SI)
1565         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1566       else
1567         return "mov{w}\t{%1, %0|%0, %1}";
1568     }
1569 }
1570   [(set (attr "type")
1571      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1572               (const_string "imov")
1573             (and (eq_attr "alternative" "0")
1574                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1575                           (const_int 0))
1576                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1577                           (const_int 0))))
1578               (const_string "imov")
1579             (and (eq_attr "alternative" "1,2")
1580                  (match_operand:HI 1 "aligned_operand" ""))
1581               (const_string "imov")
1582             (and (ne (symbol_ref "TARGET_MOVX")
1583                      (const_int 0))
1584                  (eq_attr "alternative" "0,2"))
1585               (const_string "imovx")
1586            ]
1587            (const_string "imov")))
1588     (set (attr "mode")
1589       (cond [(eq_attr "type" "imovx")
1590                (const_string "SI")
1591              (and (eq_attr "alternative" "1,2")
1592                   (match_operand:HI 1 "aligned_operand" ""))
1593                (const_string "SI")
1594              (and (eq_attr "alternative" "0")
1595                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1596                            (const_int 0))
1597                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1598                            (const_int 0))))
1599                (const_string "SI")
1600             ]
1601             (const_string "HI")))])
1602
1603 ;; Stores and loads of ax to arbitrary constant address.
1604 ;; We fake an second form of instruction to force reload to load address
1605 ;; into register when rax is not available
1606 (define_insn "*movabshi_1_rex64"
1607   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1608         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1609   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1610   "@
1611    movabs{w}\t{%1, %P0|%P0, %1}
1612    mov{w}\t{%1, %a0|%a0, %1}"
1613   [(set_attr "type" "imov")
1614    (set_attr "modrm" "0,*")
1615    (set_attr "length_address" "8,0")
1616    (set_attr "length_immediate" "0,*")
1617    (set_attr "memory" "store")
1618    (set_attr "mode" "HI")])
1619
1620 (define_insn "*movabshi_2_rex64"
1621   [(set (match_operand:HI 0 "register_operand" "=a,r")
1622         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1623   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1624   "@
1625    movabs{w}\t{%P1, %0|%0, %P1}
1626    mov{w}\t{%a1, %0|%0, %a1}"
1627   [(set_attr "type" "imov")
1628    (set_attr "modrm" "0,*")
1629    (set_attr "length_address" "8,0")
1630    (set_attr "length_immediate" "0")
1631    (set_attr "memory" "load")
1632    (set_attr "mode" "HI")])
1633
1634 (define_insn "*swaphi_1"
1635   [(set (match_operand:HI 0 "register_operand" "+r")
1636         (match_operand:HI 1 "register_operand" "+r"))
1637    (set (match_dup 1)
1638         (match_dup 0))]
1639   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1640   "xchg{l}\t%k1, %k0"
1641   [(set_attr "type" "imov")
1642    (set_attr "mode" "SI")
1643    (set_attr "pent_pair" "np")
1644    (set_attr "athlon_decode" "vector")
1645    (set_attr "amdfam10_decode" "double")])
1646
1647 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1648 (define_insn "*swaphi_2"
1649   [(set (match_operand:HI 0 "register_operand" "+r")
1650         (match_operand:HI 1 "register_operand" "+r"))
1651    (set (match_dup 1)
1652         (match_dup 0))]
1653   "TARGET_PARTIAL_REG_STALL"
1654   "xchg{w}\t%1, %0"
1655   [(set_attr "type" "imov")
1656    (set_attr "mode" "HI")
1657    (set_attr "pent_pair" "np")
1658    (set_attr "athlon_decode" "vector")])
1659
1660 (define_expand "movstricthi"
1661   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1662         (match_operand:HI 1 "general_operand" ""))]
1663   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1664 {
1665   /* Don't generate memory->memory moves, go through a register */
1666   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1667     operands[1] = force_reg (HImode, operands[1]);
1668 })
1669
1670 (define_insn "*movstricthi_1"
1671   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1672         (match_operand:HI 1 "general_operand" "rn,m"))]
1673   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1674    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1675   "mov{w}\t{%1, %0|%0, %1}"
1676   [(set_attr "type" "imov")
1677    (set_attr "mode" "HI")])
1678
1679 (define_insn "*movstricthi_xor"
1680   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1681         (match_operand:HI 1 "const0_operand" "i"))
1682    (clobber (reg:CC FLAGS_REG))]
1683   "reload_completed
1684    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1685   "xor{w}\t%0, %0"
1686   [(set_attr "type" "alu1")
1687    (set_attr "mode" "HI")
1688    (set_attr "length_immediate" "0")])
1689
1690 (define_expand "movqi"
1691   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1692         (match_operand:QI 1 "general_operand" ""))]
1693   ""
1694   "ix86_expand_move (QImode, operands); DONE;")
1695
1696 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1697 ;; "push a byte".  But actually we use pushl, which has the effect
1698 ;; of rounding the amount pushed up to a word.
1699
1700 (define_insn "*pushqi2"
1701   [(set (match_operand:QI 0 "push_operand" "=X")
1702         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1703   "!TARGET_64BIT"
1704   "push{l}\t%k1"
1705   [(set_attr "type" "push")
1706    (set_attr "mode" "SI")])
1707
1708 ;; For 64BIT abi we always round up to 8 bytes.
1709 (define_insn "*pushqi2_rex64"
1710   [(set (match_operand:QI 0 "push_operand" "=X")
1711         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1712   "TARGET_64BIT"
1713   "push{q}\t%q1"
1714   [(set_attr "type" "push")
1715    (set_attr "mode" "DI")])
1716
1717 ;; Situation is quite tricky about when to choose full sized (SImode) move
1718 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1719 ;; partial register dependency machines (such as AMD Athlon), where QImode
1720 ;; moves issue extra dependency and for partial register stalls machines
1721 ;; that don't use QImode patterns (and QImode move cause stall on the next
1722 ;; instruction).
1723 ;;
1724 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1725 ;; register stall machines with, where we use QImode instructions, since
1726 ;; partial register stall can be caused there.  Then we use movzx.
1727 (define_insn "*movqi_1"
1728   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1729         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1730   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1731 {
1732   switch (get_attr_type (insn))
1733     {
1734     case TYPE_IMOVX:
1735       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1736       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1737     default:
1738       if (get_attr_mode (insn) == MODE_SI)
1739         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1740       else
1741         return "mov{b}\t{%1, %0|%0, %1}";
1742     }
1743 }
1744   [(set (attr "type")
1745      (cond [(and (eq_attr "alternative" "5")
1746                  (not (match_operand:QI 1 "aligned_operand" "")))
1747               (const_string "imovx")
1748             (ne (symbol_ref "optimize_size") (const_int 0))
1749               (const_string "imov")
1750             (and (eq_attr "alternative" "3")
1751                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1752                           (const_int 0))
1753                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1754                           (const_int 0))))
1755               (const_string "imov")
1756             (eq_attr "alternative" "3,5")
1757               (const_string "imovx")
1758             (and (ne (symbol_ref "TARGET_MOVX")
1759                      (const_int 0))
1760                  (eq_attr "alternative" "2"))
1761               (const_string "imovx")
1762            ]
1763            (const_string "imov")))
1764    (set (attr "mode")
1765       (cond [(eq_attr "alternative" "3,4,5")
1766                (const_string "SI")
1767              (eq_attr "alternative" "6")
1768                (const_string "QI")
1769              (eq_attr "type" "imovx")
1770                (const_string "SI")
1771              (and (eq_attr "type" "imov")
1772                   (and (eq_attr "alternative" "0,1")
1773                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1774                                 (const_int 0))
1775                             (and (eq (symbol_ref "optimize_size")
1776                                      (const_int 0))
1777                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1778                                      (const_int 0))))))
1779                (const_string "SI")
1780              ;; Avoid partial register stalls when not using QImode arithmetic
1781              (and (eq_attr "type" "imov")
1782                   (and (eq_attr "alternative" "0,1")
1783                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1784                                 (const_int 0))
1785                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1786                                 (const_int 0)))))
1787                (const_string "SI")
1788            ]
1789            (const_string "QI")))])
1790
1791 (define_expand "reload_outqi"
1792   [(parallel [(match_operand:QI 0 "" "=m")
1793               (match_operand:QI 1 "register_operand" "r")
1794               (match_operand:QI 2 "register_operand" "=&q")])]
1795   ""
1796 {
1797   rtx op0, op1, op2;
1798   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1799
1800   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1801   if (! q_regs_operand (op1, QImode))
1802     {
1803       emit_insn (gen_movqi (op2, op1));
1804       op1 = op2;
1805     }
1806   emit_insn (gen_movqi (op0, op1));
1807   DONE;
1808 })
1809
1810 (define_insn "*swapqi_1"
1811   [(set (match_operand:QI 0 "register_operand" "+r")
1812         (match_operand:QI 1 "register_operand" "+r"))
1813    (set (match_dup 1)
1814         (match_dup 0))]
1815   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1816   "xchg{l}\t%k1, %k0"
1817   [(set_attr "type" "imov")
1818    (set_attr "mode" "SI")
1819    (set_attr "pent_pair" "np")
1820    (set_attr "athlon_decode" "vector")
1821    (set_attr "amdfam10_decode" "vector")])
1822
1823 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1824 (define_insn "*swapqi_2"
1825   [(set (match_operand:QI 0 "register_operand" "+q")
1826         (match_operand:QI 1 "register_operand" "+q"))
1827    (set (match_dup 1)
1828         (match_dup 0))]
1829   "TARGET_PARTIAL_REG_STALL"
1830   "xchg{b}\t%1, %0"
1831   [(set_attr "type" "imov")
1832    (set_attr "mode" "QI")
1833    (set_attr "pent_pair" "np")
1834    (set_attr "athlon_decode" "vector")])
1835
1836 (define_expand "movstrictqi"
1837   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1838         (match_operand:QI 1 "general_operand" ""))]
1839   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1840 {
1841   /* Don't generate memory->memory moves, go through a register.  */
1842   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1843     operands[1] = force_reg (QImode, operands[1]);
1844 })
1845
1846 (define_insn "*movstrictqi_1"
1847   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1848         (match_operand:QI 1 "general_operand" "*qn,m"))]
1849   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1850    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1851   "mov{b}\t{%1, %0|%0, %1}"
1852   [(set_attr "type" "imov")
1853    (set_attr "mode" "QI")])
1854
1855 (define_insn "*movstrictqi_xor"
1856   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1857         (match_operand:QI 1 "const0_operand" "i"))
1858    (clobber (reg:CC FLAGS_REG))]
1859   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1860   "xor{b}\t%0, %0"
1861   [(set_attr "type" "alu1")
1862    (set_attr "mode" "QI")
1863    (set_attr "length_immediate" "0")])
1864
1865 (define_insn "*movsi_extv_1"
1866   [(set (match_operand:SI 0 "register_operand" "=R")
1867         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1868                          (const_int 8)
1869                          (const_int 8)))]
1870   ""
1871   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1872   [(set_attr "type" "imovx")
1873    (set_attr "mode" "SI")])
1874
1875 (define_insn "*movhi_extv_1"
1876   [(set (match_operand:HI 0 "register_operand" "=R")
1877         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1878                          (const_int 8)
1879                          (const_int 8)))]
1880   ""
1881   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1882   [(set_attr "type" "imovx")
1883    (set_attr "mode" "SI")])
1884
1885 (define_insn "*movqi_extv_1"
1886   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1887         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1888                          (const_int 8)
1889                          (const_int 8)))]
1890   "!TARGET_64BIT"
1891 {
1892   switch (get_attr_type (insn))
1893     {
1894     case TYPE_IMOVX:
1895       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1896     default:
1897       return "mov{b}\t{%h1, %0|%0, %h1}";
1898     }
1899 }
1900   [(set (attr "type")
1901      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1902                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1903                              (ne (symbol_ref "TARGET_MOVX")
1904                                  (const_int 0))))
1905         (const_string "imovx")
1906         (const_string "imov")))
1907    (set (attr "mode")
1908      (if_then_else (eq_attr "type" "imovx")
1909         (const_string "SI")
1910         (const_string "QI")))])
1911
1912 (define_insn "*movqi_extv_1_rex64"
1913   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1914         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1915                          (const_int 8)
1916                          (const_int 8)))]
1917   "TARGET_64BIT"
1918 {
1919   switch (get_attr_type (insn))
1920     {
1921     case TYPE_IMOVX:
1922       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1923     default:
1924       return "mov{b}\t{%h1, %0|%0, %h1}";
1925     }
1926 }
1927   [(set (attr "type")
1928      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1929                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1930                              (ne (symbol_ref "TARGET_MOVX")
1931                                  (const_int 0))))
1932         (const_string "imovx")
1933         (const_string "imov")))
1934    (set (attr "mode")
1935      (if_then_else (eq_attr "type" "imovx")
1936         (const_string "SI")
1937         (const_string "QI")))])
1938
1939 ;; Stores and loads of ax to arbitrary constant address.
1940 ;; We fake an second form of instruction to force reload to load address
1941 ;; into register when rax is not available
1942 (define_insn "*movabsqi_1_rex64"
1943   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1944         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1945   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1946   "@
1947    movabs{b}\t{%1, %P0|%P0, %1}
1948    mov{b}\t{%1, %a0|%a0, %1}"
1949   [(set_attr "type" "imov")
1950    (set_attr "modrm" "0,*")
1951    (set_attr "length_address" "8,0")
1952    (set_attr "length_immediate" "0,*")
1953    (set_attr "memory" "store")
1954    (set_attr "mode" "QI")])
1955
1956 (define_insn "*movabsqi_2_rex64"
1957   [(set (match_operand:QI 0 "register_operand" "=a,r")
1958         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1959   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1960   "@
1961    movabs{b}\t{%P1, %0|%0, %P1}
1962    mov{b}\t{%a1, %0|%0, %a1}"
1963   [(set_attr "type" "imov")
1964    (set_attr "modrm" "0,*")
1965    (set_attr "length_address" "8,0")
1966    (set_attr "length_immediate" "0")
1967    (set_attr "memory" "load")
1968    (set_attr "mode" "QI")])
1969
1970 (define_insn "*movdi_extzv_1"
1971   [(set (match_operand:DI 0 "register_operand" "=R")
1972         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1973                          (const_int 8)
1974                          (const_int 8)))]
1975   "TARGET_64BIT"
1976   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1977   [(set_attr "type" "imovx")
1978    (set_attr "mode" "DI")])
1979
1980 (define_insn "*movsi_extzv_1"
1981   [(set (match_operand:SI 0 "register_operand" "=R")
1982         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1983                          (const_int 8)
1984                          (const_int 8)))]
1985   ""
1986   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1987   [(set_attr "type" "imovx")
1988    (set_attr "mode" "SI")])
1989
1990 (define_insn "*movqi_extzv_2"
1991   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1992         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1993                                     (const_int 8)
1994                                     (const_int 8)) 0))]
1995   "!TARGET_64BIT"
1996 {
1997   switch (get_attr_type (insn))
1998     {
1999     case TYPE_IMOVX:
2000       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2001     default:
2002       return "mov{b}\t{%h1, %0|%0, %h1}";
2003     }
2004 }
2005   [(set (attr "type")
2006      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2007                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2008                              (ne (symbol_ref "TARGET_MOVX")
2009                                  (const_int 0))))
2010         (const_string "imovx")
2011         (const_string "imov")))
2012    (set (attr "mode")
2013      (if_then_else (eq_attr "type" "imovx")
2014         (const_string "SI")
2015         (const_string "QI")))])
2016
2017 (define_insn "*movqi_extzv_2_rex64"
2018   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2019         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2020                                     (const_int 8)
2021                                     (const_int 8)) 0))]
2022   "TARGET_64BIT"
2023 {
2024   switch (get_attr_type (insn))
2025     {
2026     case TYPE_IMOVX:
2027       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2028     default:
2029       return "mov{b}\t{%h1, %0|%0, %h1}";
2030     }
2031 }
2032   [(set (attr "type")
2033      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2034                         (ne (symbol_ref "TARGET_MOVX")
2035                             (const_int 0)))
2036         (const_string "imovx")
2037         (const_string "imov")))
2038    (set (attr "mode")
2039      (if_then_else (eq_attr "type" "imovx")
2040         (const_string "SI")
2041         (const_string "QI")))])
2042
2043 (define_insn "movsi_insv_1"
2044   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2045                          (const_int 8)
2046                          (const_int 8))
2047         (match_operand:SI 1 "general_operand" "Qmn"))]
2048   "!TARGET_64BIT"
2049   "mov{b}\t{%b1, %h0|%h0, %b1}"
2050   [(set_attr "type" "imov")
2051    (set_attr "mode" "QI")])
2052
2053 (define_insn "*movsi_insv_1_rex64"
2054   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2055                          (const_int 8)
2056                          (const_int 8))
2057         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2058   "TARGET_64BIT"
2059   "mov{b}\t{%b1, %h0|%h0, %b1}"
2060   [(set_attr "type" "imov")
2061    (set_attr "mode" "QI")])
2062
2063 (define_insn "movdi_insv_1_rex64"
2064   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2065                          (const_int 8)
2066                          (const_int 8))
2067         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2068   "TARGET_64BIT"
2069   "mov{b}\t{%b1, %h0|%h0, %b1}"
2070   [(set_attr "type" "imov")
2071    (set_attr "mode" "QI")])
2072
2073 (define_insn "*movqi_insv_2"
2074   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2075                          (const_int 8)
2076                          (const_int 8))
2077         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2078                      (const_int 8)))]
2079   ""
2080   "mov{b}\t{%h1, %h0|%h0, %h1}"
2081   [(set_attr "type" "imov")
2082    (set_attr "mode" "QI")])
2083
2084 (define_expand "movdi"
2085   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2086         (match_operand:DI 1 "general_operand" ""))]
2087   ""
2088   "ix86_expand_move (DImode, operands); DONE;")
2089
2090 (define_insn "*pushdi"
2091   [(set (match_operand:DI 0 "push_operand" "=<")
2092         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2093   "!TARGET_64BIT"
2094   "#")
2095
2096 (define_insn "*pushdi2_rex64"
2097   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2098         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2099   "TARGET_64BIT"
2100   "@
2101    push{q}\t%1
2102    #"
2103   [(set_attr "type" "push,multi")
2104    (set_attr "mode" "DI")])
2105
2106 ;; Convert impossible pushes of immediate to existing instructions.
2107 ;; First try to get scratch register and go through it.  In case this
2108 ;; fails, push sign extended lower part first and then overwrite
2109 ;; upper part by 32bit move.
2110 (define_peephole2
2111   [(match_scratch:DI 2 "r")
2112    (set (match_operand:DI 0 "push_operand" "")
2113         (match_operand:DI 1 "immediate_operand" ""))]
2114   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2115    && !x86_64_immediate_operand (operands[1], DImode)"
2116   [(set (match_dup 2) (match_dup 1))
2117    (set (match_dup 0) (match_dup 2))]
2118   "")
2119
2120 ;; We need to define this as both peepholer and splitter for case
2121 ;; peephole2 pass is not run.
2122 ;; "&& 1" is needed to keep it from matching the previous pattern.
2123 (define_peephole2
2124   [(set (match_operand:DI 0 "push_operand" "")
2125         (match_operand:DI 1 "immediate_operand" ""))]
2126   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2127    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2128   [(set (match_dup 0) (match_dup 1))
2129    (set (match_dup 2) (match_dup 3))]
2130   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2131    operands[1] = gen_lowpart (DImode, operands[2]);
2132    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2133                                                     GEN_INT (4)));
2134   ")
2135
2136 (define_split
2137   [(set (match_operand:DI 0 "push_operand" "")
2138         (match_operand:DI 1 "immediate_operand" ""))]
2139   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2140                     ? epilogue_completed : reload_completed)
2141    && !symbolic_operand (operands[1], DImode)
2142    && !x86_64_immediate_operand (operands[1], DImode)"
2143   [(set (match_dup 0) (match_dup 1))
2144    (set (match_dup 2) (match_dup 3))]
2145   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2146    operands[1] = gen_lowpart (DImode, operands[2]);
2147    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2148                                                     GEN_INT (4)));
2149   ")
2150
2151 (define_insn "*pushdi2_prologue_rex64"
2152   [(set (match_operand:DI 0 "push_operand" "=<")
2153         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2154    (clobber (mem:BLK (scratch)))]
2155   "TARGET_64BIT"
2156   "push{q}\t%1"
2157   [(set_attr "type" "push")
2158    (set_attr "mode" "DI")])
2159
2160 (define_insn "*popdi1_epilogue_rex64"
2161   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2162         (mem:DI (reg:DI SP_REG)))
2163    (set (reg:DI SP_REG)
2164         (plus:DI (reg:DI SP_REG) (const_int 8)))
2165    (clobber (mem:BLK (scratch)))]
2166   "TARGET_64BIT"
2167   "pop{q}\t%0"
2168   [(set_attr "type" "pop")
2169    (set_attr "mode" "DI")])
2170
2171 (define_insn "popdi1"
2172   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2173         (mem:DI (reg:DI SP_REG)))
2174    (set (reg:DI SP_REG)
2175         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2176   "TARGET_64BIT"
2177   "pop{q}\t%0"
2178   [(set_attr "type" "pop")
2179    (set_attr "mode" "DI")])
2180
2181 (define_insn "*movdi_xor_rex64"
2182   [(set (match_operand:DI 0 "register_operand" "=r")
2183         (match_operand:DI 1 "const0_operand" "i"))
2184    (clobber (reg:CC FLAGS_REG))]
2185   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2186    && reload_completed"
2187   "xor{l}\t%k0, %k0";
2188   [(set_attr "type" "alu1")
2189    (set_attr "mode" "SI")
2190    (set_attr "length_immediate" "0")])
2191
2192 (define_insn "*movdi_or_rex64"
2193   [(set (match_operand:DI 0 "register_operand" "=r")
2194         (match_operand:DI 1 "const_int_operand" "i"))
2195    (clobber (reg:CC FLAGS_REG))]
2196   "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2197    && reload_completed
2198    && operands[1] == constm1_rtx"
2199 {
2200   operands[1] = constm1_rtx;
2201   return "or{q}\t{%1, %0|%0, %1}";
2202 }
2203   [(set_attr "type" "alu1")
2204    (set_attr "mode" "DI")
2205    (set_attr "length_immediate" "1")])
2206
2207 (define_insn "*movdi_2"
2208   [(set (match_operand:DI 0 "nonimmediate_operand"
2209                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2210         (match_operand:DI 1 "general_operand"
2211                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2212   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2213   "@
2214    #
2215    #
2216    pxor\t%0, %0
2217    movq\t{%1, %0|%0, %1}
2218    movq\t{%1, %0|%0, %1}
2219    pxor\t%0, %0
2220    movq\t{%1, %0|%0, %1}
2221    movdqa\t{%1, %0|%0, %1}
2222    movq\t{%1, %0|%0, %1}
2223    xorps\t%0, %0
2224    movlps\t{%1, %0|%0, %1}
2225    movaps\t{%1, %0|%0, %1}
2226    movlps\t{%1, %0|%0, %1}"
2227   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2228    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2229
2230 (define_split
2231   [(set (match_operand:DI 0 "push_operand" "")
2232         (match_operand:DI 1 "general_operand" ""))]
2233   "!TARGET_64BIT && reload_completed
2234    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2235   [(const_int 0)]
2236   "ix86_split_long_move (operands); DONE;")
2237
2238 ;; %%% This multiword shite has got to go.
2239 (define_split
2240   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2241         (match_operand:DI 1 "general_operand" ""))]
2242   "!TARGET_64BIT && reload_completed
2243    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2244    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2245   [(const_int 0)]
2246   "ix86_split_long_move (operands); DONE;")
2247
2248 (define_insn "*movdi_1_rex64"
2249   [(set (match_operand:DI 0 "nonimmediate_operand"
2250           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2251         (match_operand:DI 1 "general_operand"
2252           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2253   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2254 {
2255   switch (get_attr_type (insn))
2256     {
2257     case TYPE_SSECVT:
2258       if (SSE_REG_P (operands[0]))
2259         return "movq2dq\t{%1, %0|%0, %1}";
2260       else
2261         return "movdq2q\t{%1, %0|%0, %1}";
2262
2263     case TYPE_SSEMOV:
2264       if (get_attr_mode (insn) == MODE_TI)
2265         return "movdqa\t{%1, %0|%0, %1}";
2266       /* FALLTHRU */
2267
2268     case TYPE_MMXMOV:
2269       /* Moves from and into integer register is done using movd
2270          opcode with REX prefix.  */
2271       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2272         return "movd\t{%1, %0|%0, %1}";
2273       return "movq\t{%1, %0|%0, %1}";
2274
2275     case TYPE_SSELOG1:
2276     case TYPE_MMXADD:
2277       return "pxor\t%0, %0";
2278
2279     case TYPE_MULTI:
2280       return "#";
2281
2282     case TYPE_LEA:
2283       return "lea{q}\t{%a1, %0|%0, %a1}";
2284
2285     default:
2286       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2287       if (get_attr_mode (insn) == MODE_SI)
2288         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2289       else if (which_alternative == 2)
2290         return "movabs{q}\t{%1, %0|%0, %1}";
2291       else
2292         return "mov{q}\t{%1, %0|%0, %1}";
2293     }
2294 }
2295   [(set (attr "type")
2296      (cond [(eq_attr "alternative" "5")
2297               (const_string "mmxadd")
2298             (eq_attr "alternative" "6,7,8,9,10")
2299               (const_string "mmxmov")
2300             (eq_attr "alternative" "11")
2301               (const_string "sselog1")
2302             (eq_attr "alternative" "12,13,14,15,16")
2303               (const_string "ssemov")
2304             (eq_attr "alternative" "17,18")
2305               (const_string "ssecvt")
2306             (eq_attr "alternative" "4")
2307               (const_string "multi")
2308             (match_operand:DI 1 "pic_32bit_operand" "")
2309               (const_string "lea")
2310            ]
2311            (const_string "imov")))
2312    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2313    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2314    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2315
2316 ;; Stores and loads of ax to arbitrary constant address.
2317 ;; We fake an second form of instruction to force reload to load address
2318 ;; into register when rax is not available
2319 (define_insn "*movabsdi_1_rex64"
2320   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2321         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2322   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2323   "@
2324    movabs{q}\t{%1, %P0|%P0, %1}
2325    mov{q}\t{%1, %a0|%a0, %1}"
2326   [(set_attr "type" "imov")
2327    (set_attr "modrm" "0,*")
2328    (set_attr "length_address" "8,0")
2329    (set_attr "length_immediate" "0,*")
2330    (set_attr "memory" "store")
2331    (set_attr "mode" "DI")])
2332
2333 (define_insn "*movabsdi_2_rex64"
2334   [(set (match_operand:DI 0 "register_operand" "=a,r")
2335         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2336   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2337   "@
2338    movabs{q}\t{%P1, %0|%0, %P1}
2339    mov{q}\t{%a1, %0|%0, %a1}"
2340   [(set_attr "type" "imov")
2341    (set_attr "modrm" "0,*")
2342    (set_attr "length_address" "8,0")
2343    (set_attr "length_immediate" "0")
2344    (set_attr "memory" "load")
2345    (set_attr "mode" "DI")])
2346
2347 ;; Convert impossible stores of immediate to existing instructions.
2348 ;; First try to get scratch register and go through it.  In case this
2349 ;; fails, move by 32bit parts.
2350 (define_peephole2
2351   [(match_scratch:DI 2 "r")
2352    (set (match_operand:DI 0 "memory_operand" "")
2353         (match_operand:DI 1 "immediate_operand" ""))]
2354   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2355    && !x86_64_immediate_operand (operands[1], DImode)"
2356   [(set (match_dup 2) (match_dup 1))
2357    (set (match_dup 0) (match_dup 2))]
2358   "")
2359
2360 ;; We need to define this as both peepholer and splitter for case
2361 ;; peephole2 pass is not run.
2362 ;; "&& 1" is needed to keep it from matching the previous pattern.
2363 (define_peephole2
2364   [(set (match_operand:DI 0 "memory_operand" "")
2365         (match_operand:DI 1 "immediate_operand" ""))]
2366   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2367    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2368   [(set (match_dup 2) (match_dup 3))
2369    (set (match_dup 4) (match_dup 5))]
2370   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2371
2372 (define_split
2373   [(set (match_operand:DI 0 "memory_operand" "")
2374         (match_operand:DI 1 "immediate_operand" ""))]
2375   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2376                     ? epilogue_completed : reload_completed)
2377    && !symbolic_operand (operands[1], DImode)
2378    && !x86_64_immediate_operand (operands[1], DImode)"
2379   [(set (match_dup 2) (match_dup 3))
2380    (set (match_dup 4) (match_dup 5))]
2381   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2382
2383 (define_insn "*swapdi_rex64"
2384   [(set (match_operand:DI 0 "register_operand" "+r")
2385         (match_operand:DI 1 "register_operand" "+r"))
2386    (set (match_dup 1)
2387         (match_dup 0))]
2388   "TARGET_64BIT"
2389   "xchg{q}\t%1, %0"
2390   [(set_attr "type" "imov")
2391    (set_attr "mode" "DI")
2392    (set_attr "pent_pair" "np")
2393    (set_attr "athlon_decode" "vector")
2394    (set_attr "amdfam10_decode" "double")])
2395
2396 (define_expand "movti"
2397   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2398         (match_operand:TI 1 "nonimmediate_operand" ""))]
2399   "TARGET_SSE || TARGET_64BIT"
2400 {
2401   if (TARGET_64BIT)
2402     ix86_expand_move (TImode, operands);
2403   else if (push_operand (operands[0], TImode))
2404     ix86_expand_push (TImode, operands[1]);
2405   else
2406     ix86_expand_vector_move (TImode, operands);
2407   DONE;
2408 })
2409
2410 (define_insn "*movti_internal"
2411   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2412         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2413   "TARGET_SSE && !TARGET_64BIT
2414    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2415 {
2416   switch (which_alternative)
2417     {
2418     case 0:
2419       if (get_attr_mode (insn) == MODE_V4SF)
2420         return "xorps\t%0, %0";
2421       else
2422         return "pxor\t%0, %0";
2423     case 1:
2424     case 2:
2425       /* TDmode values are passed as TImode on the stack.  Moving them
2426          to stack may result in unaligned memory access.  */
2427       if (misaligned_operand (operands[0], TImode)
2428           || misaligned_operand (operands[1], TImode))
2429         { 
2430           if (get_attr_mode (insn) == MODE_V4SF)
2431             return "movups\t{%1, %0|%0, %1}";
2432          else
2433            return "movdqu\t{%1, %0|%0, %1}";
2434         }
2435       else
2436         { 
2437           if (get_attr_mode (insn) == MODE_V4SF)
2438             return "movaps\t{%1, %0|%0, %1}";
2439          else
2440            return "movdqa\t{%1, %0|%0, %1}";
2441         }
2442     default:
2443       gcc_unreachable ();
2444     }
2445 }
2446   [(set_attr "type" "sselog1,ssemov,ssemov")
2447    (set (attr "mode")
2448         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2449                     (ne (symbol_ref "optimize_size") (const_int 0)))
2450                  (const_string "V4SF")
2451                (and (eq_attr "alternative" "2")
2452                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2453                         (const_int 0)))
2454                  (const_string "V4SF")]
2455               (const_string "TI")))])
2456
2457 (define_insn "*movti_rex64"
2458   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2459         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2460   "TARGET_64BIT
2461    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2462 {
2463   switch (which_alternative)
2464     {
2465     case 0:
2466     case 1:
2467       return "#";
2468     case 2:
2469       if (get_attr_mode (insn) == MODE_V4SF)
2470         return "xorps\t%0, %0";
2471       else
2472         return "pxor\t%0, %0";
2473     case 3:
2474     case 4:
2475       /* TDmode values are passed as TImode on the stack.  Moving them
2476          to stack may result in unaligned memory access.  */
2477       if (misaligned_operand (operands[0], TImode)
2478           || misaligned_operand (operands[1], TImode))
2479         { 
2480           if (get_attr_mode (insn) == MODE_V4SF)
2481             return "movups\t{%1, %0|%0, %1}";
2482          else
2483            return "movdqu\t{%1, %0|%0, %1}";
2484         }
2485       else
2486         { 
2487           if (get_attr_mode (insn) == MODE_V4SF)
2488             return "movaps\t{%1, %0|%0, %1}";
2489          else
2490            return "movdqa\t{%1, %0|%0, %1}";
2491         }
2492     default:
2493       gcc_unreachable ();
2494     }
2495 }
2496   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2497    (set (attr "mode")
2498         (cond [(eq_attr "alternative" "2,3")
2499                  (if_then_else
2500                    (ne (symbol_ref "optimize_size")
2501                        (const_int 0))
2502                    (const_string "V4SF")
2503                    (const_string "TI"))
2504                (eq_attr "alternative" "4")
2505                  (if_then_else
2506                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2507                             (const_int 0))
2508                         (ne (symbol_ref "optimize_size")
2509                             (const_int 0)))
2510                    (const_string "V4SF")
2511                    (const_string "TI"))]
2512                (const_string "DI")))])
2513
2514 (define_split
2515   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2516         (match_operand:TI 1 "general_operand" ""))]
2517   "reload_completed && !SSE_REG_P (operands[0])
2518    && !SSE_REG_P (operands[1])"
2519   [(const_int 0)]
2520   "ix86_split_long_move (operands); DONE;")
2521
2522 ;; This expands to what emit_move_complex would generate if we didn't
2523 ;; have a movti pattern.  Having this avoids problems with reload on
2524 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2525 ;; to have around all the time.
2526 (define_expand "movcdi"
2527   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2528         (match_operand:CDI 1 "general_operand" ""))]
2529   ""
2530 {
2531   if (push_operand (operands[0], CDImode))
2532     emit_move_complex_push (CDImode, operands[0], operands[1]);
2533   else
2534     emit_move_complex_parts (operands[0], operands[1]);
2535   DONE;
2536 })
2537
2538 (define_expand "movsf"
2539   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2540         (match_operand:SF 1 "general_operand" ""))]
2541   ""
2542   "ix86_expand_move (SFmode, operands); DONE;")
2543
2544 (define_insn "*pushsf"
2545   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2546         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2547   "!TARGET_64BIT"
2548 {
2549   /* Anything else should be already split before reg-stack.  */
2550   gcc_assert (which_alternative == 1);
2551   return "push{l}\t%1";
2552 }
2553   [(set_attr "type" "multi,push,multi")
2554    (set_attr "unit" "i387,*,*")
2555    (set_attr "mode" "SF,SI,SF")])
2556
2557 (define_insn "*pushsf_rex64"
2558   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2559         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2560   "TARGET_64BIT"
2561 {
2562   /* Anything else should be already split before reg-stack.  */
2563   gcc_assert (which_alternative == 1);
2564   return "push{q}\t%q1";
2565 }
2566   [(set_attr "type" "multi,push,multi")
2567    (set_attr "unit" "i387,*,*")
2568    (set_attr "mode" "SF,DI,SF")])
2569
2570 (define_split
2571   [(set (match_operand:SF 0 "push_operand" "")
2572         (match_operand:SF 1 "memory_operand" ""))]
2573   "reload_completed
2574    && MEM_P (operands[1])
2575    && (operands[2] = find_constant_src (insn))"
2576   [(set (match_dup 0)
2577         (match_dup 2))])
2578
2579
2580 ;; %%% Kill this when call knows how to work this out.
2581 (define_split
2582   [(set (match_operand:SF 0 "push_operand" "")
2583         (match_operand:SF 1 "any_fp_register_operand" ""))]
2584   "!TARGET_64BIT"
2585   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2586    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2587
2588 (define_split
2589   [(set (match_operand:SF 0 "push_operand" "")
2590         (match_operand:SF 1 "any_fp_register_operand" ""))]
2591   "TARGET_64BIT"
2592   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2593    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2594
2595 (define_insn "*movsf_1"
2596   [(set (match_operand:SF 0 "nonimmediate_operand"
2597           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2598         (match_operand:SF 1 "general_operand"
2599           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2600   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2601    && (reload_in_progress || reload_completed
2602        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2603        || (!TARGET_SSE_MATH && optimize_size
2604            && standard_80387_constant_p (operands[1]))
2605        || GET_CODE (operands[1]) != CONST_DOUBLE
2606        || memory_operand (operands[0], SFmode))"
2607 {
2608   switch (which_alternative)
2609     {
2610     case 0:
2611     case 1:
2612       return output_387_reg_move (insn, operands);
2613
2614     case 2:
2615       return standard_80387_constant_opcode (operands[1]);
2616
2617     case 3:
2618     case 4:
2619       return "mov{l}\t{%1, %0|%0, %1}";
2620     case 5:
2621       if (get_attr_mode (insn) == MODE_TI)
2622         return "pxor\t%0, %0";
2623       else
2624         return "xorps\t%0, %0";
2625     case 6:
2626       if (get_attr_mode (insn) == MODE_V4SF)
2627         return "movaps\t{%1, %0|%0, %1}";
2628       else
2629         return "movss\t{%1, %0|%0, %1}";
2630     case 7: case 8:
2631       return "movss\t{%1, %0|%0, %1}";
2632
2633     case 9: case 10:
2634     case 12: case 13: case 14: case 15:
2635       return "movd\t{%1, %0|%0, %1}";
2636
2637     case 11:
2638       return "movq\t{%1, %0|%0, %1}";
2639
2640     default:
2641       gcc_unreachable ();
2642     }
2643 }
2644   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2645    (set (attr "mode")
2646         (cond [(eq_attr "alternative" "3,4,9,10")
2647                  (const_string "SI")
2648                (eq_attr "alternative" "5")
2649                  (if_then_else
2650                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2651                                  (const_int 0))
2652                              (ne (symbol_ref "TARGET_SSE2")
2653                                  (const_int 0)))
2654                         (eq (symbol_ref "optimize_size")
2655                             (const_int 0)))
2656                    (const_string "TI")
2657                    (const_string "V4SF"))
2658                /* For architectures resolving dependencies on
2659                   whole SSE registers use APS move to break dependency
2660                   chains, otherwise use short move to avoid extra work.
2661
2662                   Do the same for architectures resolving dependencies on
2663                   the parts.  While in DF mode it is better to always handle
2664                   just register parts, the SF mode is different due to lack
2665                   of instructions to load just part of the register.  It is
2666                   better to maintain the whole registers in single format
2667                   to avoid problems on using packed logical operations.  */
2668                (eq_attr "alternative" "6")
2669                  (if_then_else
2670                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2671                             (const_int 0))
2672                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2673                             (const_int 0)))
2674                    (const_string "V4SF")
2675                    (const_string "SF"))
2676                (eq_attr "alternative" "11")
2677                  (const_string "DI")]
2678                (const_string "SF")))])
2679
2680 (define_insn "*swapsf"
2681   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2682         (match_operand:SF 1 "fp_register_operand" "+f"))
2683    (set (match_dup 1)
2684         (match_dup 0))]
2685   "reload_completed || TARGET_80387"
2686 {
2687   if (STACK_TOP_P (operands[0]))
2688     return "fxch\t%1";
2689   else
2690     return "fxch\t%0";
2691 }
2692   [(set_attr "type" "fxch")
2693    (set_attr "mode" "SF")])
2694
2695 (define_expand "movdf"
2696   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2697         (match_operand:DF 1 "general_operand" ""))]
2698   ""
2699   "ix86_expand_move (DFmode, operands); DONE;")
2700
2701 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2702 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2703 ;; On the average, pushdf using integers can be still shorter.  Allow this
2704 ;; pattern for optimize_size too.
2705
2706 (define_insn "*pushdf_nointeger"
2707   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2708         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2709   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2710 {
2711   /* This insn should be already split before reg-stack.  */
2712   gcc_unreachable ();
2713 }
2714   [(set_attr "type" "multi")
2715    (set_attr "unit" "i387,*,*,*")
2716    (set_attr "mode" "DF,SI,SI,DF")])
2717
2718 (define_insn "*pushdf_integer"
2719   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2720         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2721   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2722 {
2723   /* This insn should be already split before reg-stack.  */
2724   gcc_unreachable ();
2725 }
2726   [(set_attr "type" "multi")
2727    (set_attr "unit" "i387,*,*")
2728    (set_attr "mode" "DF,SI,DF")])
2729
2730 ;; %%% Kill this when call knows how to work this out.
2731 (define_split
2732   [(set (match_operand:DF 0 "push_operand" "")
2733         (match_operand:DF 1 "any_fp_register_operand" ""))]
2734   "!TARGET_64BIT && reload_completed"
2735   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2736    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2737   "")
2738
2739 (define_split
2740   [(set (match_operand:DF 0 "push_operand" "")
2741         (match_operand:DF 1 "any_fp_register_operand" ""))]
2742   "TARGET_64BIT && reload_completed"
2743   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2744    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2745   "")
2746
2747 (define_split
2748   [(set (match_operand:DF 0 "push_operand" "")
2749         (match_operand:DF 1 "general_operand" ""))]
2750   "reload_completed"
2751   [(const_int 0)]
2752   "ix86_split_long_move (operands); DONE;")
2753
2754 ;; Moving is usually shorter when only FP registers are used. This separate
2755 ;; movdf pattern avoids the use of integer registers for FP operations
2756 ;; when optimizing for size.
2757
2758 (define_insn "*movdf_nointeger"
2759   [(set (match_operand:DF 0 "nonimmediate_operand"
2760                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2761         (match_operand:DF 1 "general_operand"
2762                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
2763   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2764    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2765    && (reload_in_progress || reload_completed
2766        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2767        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2768            && !memory_operand (operands[0], DFmode)
2769            && standard_80387_constant_p (operands[1]))
2770        || GET_CODE (operands[1]) != CONST_DOUBLE
2771        || ((optimize_size
2772             || !TARGET_MEMORY_MISMATCH_STALL
2773             || reload_in_progress || reload_completed)
2774            && memory_operand (operands[0], DFmode)))"
2775 {
2776   switch (which_alternative)
2777     {
2778     case 0:
2779     case 1:
2780       return output_387_reg_move (insn, operands);
2781
2782     case 2:
2783       return standard_80387_constant_opcode (operands[1]);
2784
2785     case 3:
2786     case 4:
2787       return "#";
2788     case 5:
2789       switch (get_attr_mode (insn))
2790         {
2791         case MODE_V4SF:
2792           return "xorps\t%0, %0";
2793         case MODE_V2DF:
2794           return "xorpd\t%0, %0";
2795         case MODE_TI:
2796           return "pxor\t%0, %0";
2797         default:
2798           gcc_unreachable ();
2799         }
2800     case 6:
2801     case 7:
2802     case 8:
2803       switch (get_attr_mode (insn))
2804         {
2805         case MODE_V4SF:
2806           return "movaps\t{%1, %0|%0, %1}";
2807         case MODE_V2DF:
2808           return "movapd\t{%1, %0|%0, %1}";
2809         case MODE_TI:
2810           return "movdqa\t{%1, %0|%0, %1}";
2811         case MODE_DI:
2812           return "movq\t{%1, %0|%0, %1}";
2813         case MODE_DF:
2814           return "movsd\t{%1, %0|%0, %1}";
2815         case MODE_V1DF:
2816           return "movlpd\t{%1, %0|%0, %1}";
2817         case MODE_V2SF:
2818           return "movlps\t{%1, %0|%0, %1}";
2819         default:
2820           gcc_unreachable ();
2821         }
2822
2823     default:
2824       gcc_unreachable ();
2825     }
2826 }
2827   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2828    (set (attr "mode")
2829         (cond [(eq_attr "alternative" "0,1,2")
2830                  (const_string "DF")
2831                (eq_attr "alternative" "3,4")
2832                  (const_string "SI")
2833
2834                /* For SSE1, we have many fewer alternatives.  */
2835                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2836                  (cond [(eq_attr "alternative" "5,6")
2837                           (const_string "V4SF")
2838                        ]
2839                    (const_string "V2SF"))
2840
2841                /* xorps is one byte shorter.  */
2842                (eq_attr "alternative" "5")
2843                  (cond [(ne (symbol_ref "optimize_size")
2844                             (const_int 0))
2845                           (const_string "V4SF")
2846                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2847                             (const_int 0))
2848                           (const_string "TI")
2849                        ]
2850                        (const_string "V2DF"))
2851
2852                /* For architectures resolving dependencies on
2853                   whole SSE registers use APD move to break dependency
2854                   chains, otherwise use short move to avoid extra work.
2855
2856                   movaps encodes one byte shorter.  */
2857                (eq_attr "alternative" "6")
2858                  (cond
2859                    [(ne (symbol_ref "optimize_size")
2860                         (const_int 0))
2861                       (const_string "V4SF")
2862                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2863                         (const_int 0))
2864                       (const_string "V2DF")
2865                    ]
2866                    (const_string "DF"))
2867                /* For architectures resolving dependencies on register
2868                   parts we may avoid extra work to zero out upper part
2869                   of register.  */
2870                (eq_attr "alternative" "7")
2871                  (if_then_else
2872                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2873                        (const_int 0))
2874                    (const_string "V1DF")
2875                    (const_string "DF"))
2876               ]
2877               (const_string "DF")))])
2878
2879 (define_insn "*movdf_integer_rex64"
2880   [(set (match_operand:DF 0 "nonimmediate_operand"
2881                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2882         (match_operand:DF 1 "general_operand"
2883                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2884   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2885    && (reload_in_progress || reload_completed
2886        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2887        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2888            && standard_80387_constant_p (operands[1]))
2889        || GET_CODE (operands[1]) != CONST_DOUBLE
2890        || memory_operand (operands[0], DFmode))"
2891 {
2892   switch (which_alternative)
2893     {
2894     case 0:
2895     case 1:
2896       return output_387_reg_move (insn, operands);
2897
2898     case 2:
2899       return standard_80387_constant_opcode (operands[1]);
2900
2901     case 3:
2902     case 4:
2903       return "#";
2904
2905     case 5:
2906       switch (get_attr_mode (insn))
2907         {
2908         case MODE_V4SF:
2909           return "xorps\t%0, %0";
2910         case MODE_V2DF:
2911           return "xorpd\t%0, %0";
2912         case MODE_TI:
2913           return "pxor\t%0, %0";
2914         default:
2915           gcc_unreachable ();
2916         }
2917     case 6:
2918     case 7:
2919     case 8:
2920       switch (get_attr_mode (insn))
2921         {
2922         case MODE_V4SF:
2923           return "movaps\t{%1, %0|%0, %1}";
2924         case MODE_V2DF:
2925           return "movapd\t{%1, %0|%0, %1}";
2926         case MODE_TI:
2927           return "movdqa\t{%1, %0|%0, %1}";
2928         case MODE_DI:
2929           return "movq\t{%1, %0|%0, %1}";
2930         case MODE_DF:
2931           return "movsd\t{%1, %0|%0, %1}";
2932         case MODE_V1DF:
2933           return "movlpd\t{%1, %0|%0, %1}";
2934         case MODE_V2SF:
2935           return "movlps\t{%1, %0|%0, %1}";
2936         default:
2937           gcc_unreachable ();
2938         }
2939
2940     case 9:
2941     case 10:
2942       return "movd\t{%1, %0|%0, %1}";
2943
2944     default:
2945       gcc_unreachable();
2946     }
2947 }
2948   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2949    (set (attr "mode")
2950         (cond [(eq_attr "alternative" "0,1,2")
2951                  (const_string "DF")
2952                (eq_attr "alternative" "3,4,9,10")
2953                  (const_string "DI")
2954
2955                /* For SSE1, we have many fewer alternatives.  */
2956                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2957                  (cond [(eq_attr "alternative" "5,6")
2958                           (const_string "V4SF")
2959                        ]
2960                    (const_string "V2SF"))
2961
2962                /* xorps is one byte shorter.  */
2963                (eq_attr "alternative" "5")
2964                  (cond [(ne (symbol_ref "optimize_size")
2965                             (const_int 0))
2966                           (const_string "V4SF")
2967                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2968                             (const_int 0))
2969                           (const_string "TI")
2970                        ]
2971                        (const_string "V2DF"))
2972
2973                /* For architectures resolving dependencies on
2974                   whole SSE registers use APD move to break dependency
2975                   chains, otherwise use short move to avoid extra work.
2976
2977                   movaps encodes one byte shorter.  */
2978                (eq_attr "alternative" "6")
2979                  (cond
2980                    [(ne (symbol_ref "optimize_size")
2981                         (const_int 0))
2982                       (const_string "V4SF")
2983                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2984                         (const_int 0))
2985                       (const_string "V2DF")
2986                    ]
2987                    (const_string "DF"))
2988                /* For architectures resolving dependencies on register
2989                   parts we may avoid extra work to zero out upper part
2990                   of register.  */
2991                (eq_attr "alternative" "7")
2992                  (if_then_else
2993                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2994                        (const_int 0))
2995                    (const_string "V1DF")
2996                    (const_string "DF"))
2997               ]
2998               (const_string "DF")))])
2999
3000 (define_insn "*movdf_integer"
3001   [(set (match_operand:DF 0 "nonimmediate_operand"
3002                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3003         (match_operand:DF 1 "general_operand"
3004                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3005   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3006    && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
3007    && (reload_in_progress || reload_completed
3008        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3009        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
3010            && standard_80387_constant_p (operands[1]))
3011        || GET_CODE (operands[1]) != CONST_DOUBLE
3012        || memory_operand (operands[0], DFmode))"
3013 {
3014   switch (which_alternative)
3015     {
3016     case 0:
3017     case 1:
3018       return output_387_reg_move (insn, operands);
3019
3020     case 2:
3021       return standard_80387_constant_opcode (operands[1]);
3022
3023     case 3:
3024     case 4:
3025       return "#";
3026
3027     case 5:
3028       switch (get_attr_mode (insn))
3029         {
3030         case MODE_V4SF:
3031           return "xorps\t%0, %0";
3032         case MODE_V2DF:
3033           return "xorpd\t%0, %0";
3034         case MODE_TI:
3035           return "pxor\t%0, %0";
3036         default:
3037           gcc_unreachable ();
3038         }
3039     case 6:
3040     case 7:
3041     case 8:
3042       switch (get_attr_mode (insn))
3043         {
3044         case MODE_V4SF:
3045           return "movaps\t{%1, %0|%0, %1}";
3046         case MODE_V2DF:
3047           return "movapd\t{%1, %0|%0, %1}";
3048         case MODE_TI:
3049           return "movdqa\t{%1, %0|%0, %1}";
3050         case MODE_DI:
3051           return "movq\t{%1, %0|%0, %1}";
3052         case MODE_DF:
3053           return "movsd\t{%1, %0|%0, %1}";
3054         case MODE_V1DF:
3055           return "movlpd\t{%1, %0|%0, %1}";
3056         case MODE_V2SF:
3057           return "movlps\t{%1, %0|%0, %1}";
3058         default:
3059           gcc_unreachable ();
3060         }
3061
3062     default:
3063       gcc_unreachable();
3064     }
3065 }
3066   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3067    (set (attr "mode")
3068         (cond [(eq_attr "alternative" "0,1,2")
3069                  (const_string "DF")
3070                (eq_attr "alternative" "3,4")
3071                  (const_string "SI")
3072
3073                /* For SSE1, we have many fewer alternatives.  */
3074                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3075                  (cond [(eq_attr "alternative" "5,6")
3076                           (const_string "V4SF")
3077                        ]
3078                    (const_string "V2SF"))
3079
3080                /* xorps is one byte shorter.  */
3081                (eq_attr "alternative" "5")
3082                  (cond [(ne (symbol_ref "optimize_size")
3083                             (const_int 0))
3084                           (const_string "V4SF")
3085                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3086                             (const_int 0))
3087                           (const_string "TI")
3088                        ]
3089                        (const_string "V2DF"))
3090
3091                /* For architectures resolving dependencies on
3092                   whole SSE registers use APD move to break dependency
3093                   chains, otherwise use short move to avoid extra work.
3094
3095                   movaps encodes one byte shorter.  */
3096                (eq_attr "alternative" "6")
3097                  (cond
3098                    [(ne (symbol_ref "optimize_size")
3099                         (const_int 0))
3100                       (const_string "V4SF")
3101                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3102                         (const_int 0))
3103                       (const_string "V2DF")
3104                    ]
3105                    (const_string "DF"))
3106                /* For architectures resolving dependencies on register
3107                   parts we may avoid extra work to zero out upper part
3108                   of register.  */
3109                (eq_attr "alternative" "7")
3110                  (if_then_else
3111                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3112                        (const_int 0))
3113                    (const_string "V1DF")
3114                    (const_string "DF"))
3115               ]
3116               (const_string "DF")))])
3117
3118 (define_split
3119   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3120         (match_operand:DF 1 "general_operand" ""))]
3121   "reload_completed
3122    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3123    && ! (ANY_FP_REG_P (operands[0]) ||
3124          (GET_CODE (operands[0]) == SUBREG
3125           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3126    && ! (ANY_FP_REG_P (operands[1]) ||
3127          (GET_CODE (operands[1]) == SUBREG
3128           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3129   [(const_int 0)]
3130   "ix86_split_long_move (operands); DONE;")
3131
3132 (define_insn "*swapdf"
3133   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3134         (match_operand:DF 1 "fp_register_operand" "+f"))
3135    (set (match_dup 1)
3136         (match_dup 0))]
3137   "reload_completed || TARGET_80387"
3138 {
3139   if (STACK_TOP_P (operands[0]))
3140     return "fxch\t%1";
3141   else
3142     return "fxch\t%0";
3143 }
3144   [(set_attr "type" "fxch")
3145    (set_attr "mode" "DF")])
3146
3147 (define_expand "movxf"
3148   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3149         (match_operand:XF 1 "general_operand" ""))]
3150   ""
3151   "ix86_expand_move (XFmode, operands); DONE;")
3152
3153 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3154 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3155 ;; Pushing using integer instructions is longer except for constants
3156 ;; and direct memory references.
3157 ;; (assuming that any given constant is pushed only once, but this ought to be
3158 ;;  handled elsewhere).
3159
3160 (define_insn "*pushxf_nointeger"
3161   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3162         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3163   "optimize_size"
3164 {
3165   /* This insn should be already split before reg-stack.  */
3166   gcc_unreachable ();
3167 }
3168   [(set_attr "type" "multi")
3169    (set_attr "unit" "i387,*,*")
3170    (set_attr "mode" "XF,SI,SI")])
3171
3172 (define_insn "*pushxf_integer"
3173   [(set (match_operand:XF 0 "push_operand" "=<,<")
3174         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3175   "!optimize_size"
3176 {
3177   /* This insn should be already split before reg-stack.  */
3178   gcc_unreachable ();
3179 }
3180   [(set_attr "type" "multi")
3181    (set_attr "unit" "i387,*")
3182    (set_attr "mode" "XF,SI")])
3183
3184 (define_split
3185   [(set (match_operand 0 "push_operand" "")
3186         (match_operand 1 "general_operand" ""))]
3187   "reload_completed
3188    && (GET_MODE (operands[0]) == XFmode
3189        || GET_MODE (operands[0]) == DFmode)
3190    && !ANY_FP_REG_P (operands[1])"
3191   [(const_int 0)]
3192   "ix86_split_long_move (operands); DONE;")
3193
3194 (define_split
3195   [(set (match_operand:XF 0 "push_operand" "")
3196         (match_operand:XF 1 "any_fp_register_operand" ""))]
3197   "!TARGET_64BIT"
3198   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3199    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
3200   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3201
3202 (define_split
3203   [(set (match_operand:XF 0 "push_operand" "")
3204         (match_operand:XF 1 "any_fp_register_operand" ""))]
3205   "TARGET_64BIT"
3206   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3207    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
3208   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3209
3210 ;; Do not use integer registers when optimizing for size
3211 (define_insn "*movxf_nointeger"
3212   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3213         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3214   "optimize_size
3215    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3216    && (reload_in_progress || reload_completed
3217        || (optimize_size && standard_80387_constant_p (operands[1]))
3218        || GET_CODE (operands[1]) != CONST_DOUBLE
3219        || memory_operand (operands[0], XFmode))"
3220 {
3221   switch (which_alternative)
3222     {
3223     case 0:
3224     case 1:
3225       return output_387_reg_move (insn, operands);
3226
3227     case 2:
3228       return standard_80387_constant_opcode (operands[1]);
3229
3230     case 3: case 4:
3231       return "#";
3232     default:
3233       gcc_unreachable ();
3234     }
3235 }
3236   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3237    (set_attr "mode" "XF,XF,XF,SI,SI")])
3238
3239 (define_insn "*movxf_integer"
3240   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3241         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3242   "!optimize_size
3243    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3244    && (reload_in_progress || reload_completed
3245        || (optimize_size && standard_80387_constant_p (operands[1]))
3246        || GET_CODE (operands[1]) != CONST_DOUBLE
3247        || memory_operand (operands[0], XFmode))"
3248 {
3249   switch (which_alternative)
3250     {
3251     case 0:
3252     case 1:
3253       return output_387_reg_move (insn, operands);
3254
3255     case 2:
3256       return standard_80387_constant_opcode (operands[1]);
3257
3258     case 3: case 4:
3259       return "#";
3260
3261     default:
3262       gcc_unreachable ();
3263     }
3264 }
3265   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3266    (set_attr "mode" "XF,XF,XF,SI,SI")])
3267
3268 (define_expand "movtf"
3269   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3270         (match_operand:TF 1 "nonimmediate_operand" ""))]
3271   "TARGET_64BIT"
3272 {
3273   ix86_expand_move (TFmode, operands);
3274   DONE;
3275 })
3276
3277 (define_insn "*movtf_internal"
3278   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3279         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3280   "TARGET_64BIT
3281    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3282 {
3283   switch (which_alternative)
3284     {
3285     case 0:
3286     case 1:
3287       if (get_attr_mode (insn) == MODE_V4SF)
3288         return "movaps\t{%1, %0|%0, %1}";
3289       else
3290         return "movdqa\t{%1, %0|%0, %1}";
3291     case 2:
3292       if (get_attr_mode (insn) == MODE_V4SF)
3293         return "xorps\t%0, %0";
3294       else
3295         return "pxor\t%0, %0";
3296     case 3:
3297     case 4:
3298         return "#";
3299     default:
3300       gcc_unreachable ();
3301     }
3302 }
3303   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3304    (set (attr "mode")
3305         (cond [(eq_attr "alternative" "0,2")
3306                  (if_then_else
3307                    (ne (symbol_ref "optimize_size")
3308                        (const_int 0))
3309                    (const_string "V4SF")
3310                    (const_string "TI"))
3311                (eq_attr "alternative" "1")
3312                  (if_then_else
3313                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3314                             (const_int 0))
3315                         (ne (symbol_ref "optimize_size")
3316                             (const_int 0)))
3317                    (const_string "V4SF")
3318                    (const_string "TI"))]
3319                (const_string "DI")))])
3320
3321 (define_split
3322   [(set (match_operand 0 "nonimmediate_operand" "")
3323         (match_operand 1 "general_operand" ""))]
3324   "reload_completed
3325    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3326    && GET_MODE (operands[0]) == XFmode
3327    && ! (ANY_FP_REG_P (operands[0]) ||
3328          (GET_CODE (operands[0]) == SUBREG
3329           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3330    && ! (ANY_FP_REG_P (operands[1]) ||
3331          (GET_CODE (operands[1]) == SUBREG
3332           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3333   [(const_int 0)]
3334   "ix86_split_long_move (operands); DONE;")
3335
3336 (define_split
3337   [(set (match_operand 0 "register_operand" "")
3338         (match_operand 1 "memory_operand" ""))]
3339   "reload_completed
3340    && MEM_P (operands[1])
3341    && (GET_MODE (operands[0]) == TFmode
3342        || GET_MODE (operands[0]) == XFmode
3343        || GET_MODE (operands[0]) == SFmode
3344        || GET_MODE (operands[0]) == DFmode)
3345    && (operands[2] = find_constant_src (insn))"
3346   [(set (match_dup 0) (match_dup 2))]
3347 {
3348   rtx c = operands[2];
3349   rtx r = operands[0];
3350
3351   if (GET_CODE (r) == SUBREG)
3352     r = SUBREG_REG (r);
3353
3354   if (SSE_REG_P (r))
3355     {
3356       if (!standard_sse_constant_p (c))
3357         FAIL;
3358     }
3359   else if (FP_REG_P (r))
3360     {
3361       if (!standard_80387_constant_p (c))
3362         FAIL;
3363     }
3364   else if (MMX_REG_P (r))
3365     FAIL;
3366 })
3367
3368 (define_split
3369   [(set (match_operand 0 "register_operand" "")
3370         (float_extend (match_operand 1 "memory_operand" "")))]
3371   "reload_completed
3372    && MEM_P (operands[1])
3373    && (GET_MODE (operands[0]) == TFmode
3374        || GET_MODE (operands[0]) == XFmode
3375        || GET_MODE (operands[0]) == SFmode
3376        || GET_MODE (operands[0]) == DFmode)
3377    && (operands[2] = find_constant_src (insn))"
3378   [(set (match_dup 0) (match_dup 2))]
3379 {
3380   rtx c = operands[2];
3381   rtx r = operands[0];
3382
3383   if (GET_CODE (r) == SUBREG)
3384     r = SUBREG_REG (r);
3385
3386   if (SSE_REG_P (r))
3387     {
3388       if (!standard_sse_constant_p (c))
3389         FAIL;
3390     }
3391   else if (FP_REG_P (r))
3392     {
3393       if (!standard_80387_constant_p (c))
3394         FAIL;
3395     }
3396   else if (MMX_REG_P (r))
3397     FAIL;
3398 })
3399
3400 (define_insn "swapxf"
3401   [(set (match_operand:XF 0 "register_operand" "+f")
3402         (match_operand:XF 1 "register_operand" "+f"))
3403    (set (match_dup 1)
3404         (match_dup 0))]
3405   "TARGET_80387"
3406 {
3407   if (STACK_TOP_P (operands[0]))
3408     return "fxch\t%1";
3409   else
3410     return "fxch\t%0";
3411 }
3412   [(set_attr "type" "fxch")
3413    (set_attr "mode" "XF")])
3414
3415 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3416 (define_split
3417   [(set (match_operand:X87MODEF 0 "register_operand" "")
3418         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3419   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3420    && (standard_80387_constant_p (operands[1]) == 8
3421        || standard_80387_constant_p (operands[1]) == 9)"
3422   [(set (match_dup 0)(match_dup 1))
3423    (set (match_dup 0)
3424         (neg:X87MODEF (match_dup 0)))]
3425 {
3426   REAL_VALUE_TYPE r;
3427
3428   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3429   if (real_isnegzero (&r))
3430     operands[1] = CONST0_RTX (<MODE>mode);
3431   else
3432     operands[1] = CONST1_RTX (<MODE>mode);
3433 })
3434
3435 (define_split
3436   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3437         (match_operand:TF 1 "general_operand" ""))]
3438   "reload_completed
3439    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3440   [(const_int 0)]
3441   "ix86_split_long_move (operands); DONE;")
3442 \f
3443 ;; Zero extension instructions
3444
3445 (define_expand "zero_extendhisi2"
3446   [(set (match_operand:SI 0 "register_operand" "")
3447      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3448   ""
3449 {
3450   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3451     {
3452       operands[1] = force_reg (HImode, operands[1]);
3453       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3454       DONE;
3455     }
3456 })
3457
3458 (define_insn "zero_extendhisi2_and"
3459   [(set (match_operand:SI 0 "register_operand" "=r")
3460      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3461    (clobber (reg:CC FLAGS_REG))]
3462   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3463   "#"
3464   [(set_attr "type" "alu1")
3465    (set_attr "mode" "SI")])
3466
3467 (define_split
3468   [(set (match_operand:SI 0 "register_operand" "")
3469         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3470    (clobber (reg:CC FLAGS_REG))]
3471   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3472   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3473               (clobber (reg:CC FLAGS_REG))])]
3474   "")
3475
3476 (define_insn "*zero_extendhisi2_movzwl"
3477   [(set (match_operand:SI 0 "register_operand" "=r")
3478      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3479   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3480   "movz{wl|x}\t{%1, %0|%0, %1}"
3481   [(set_attr "type" "imovx")
3482    (set_attr "mode" "SI")])
3483
3484 (define_expand "zero_extendqihi2"
3485   [(parallel
3486     [(set (match_operand:HI 0 "register_operand" "")
3487        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3488      (clobber (reg:CC FLAGS_REG))])]
3489   ""
3490   "")
3491
3492 (define_insn "*zero_extendqihi2_and"
3493   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3494      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3495    (clobber (reg:CC FLAGS_REG))]
3496   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3497   "#"
3498   [(set_attr "type" "alu1")
3499    (set_attr "mode" "HI")])
3500
3501 (define_insn "*zero_extendqihi2_movzbw_and"
3502   [(set (match_operand:HI 0 "register_operand" "=r,r")
3503      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3504    (clobber (reg:CC FLAGS_REG))]
3505   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3506   "#"
3507   [(set_attr "type" "imovx,alu1")
3508    (set_attr "mode" "HI")])
3509
3510 ; zero extend to SImode here to avoid partial register stalls
3511 (define_insn "*zero_extendqihi2_movzbl"
3512   [(set (match_operand:HI 0 "register_operand" "=r")
3513      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3514   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3515   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3516   [(set_attr "type" "imovx")
3517    (set_attr "mode" "SI")])
3518
3519 ;; For the movzbw case strip only the clobber
3520 (define_split
3521   [(set (match_operand:HI 0 "register_operand" "")
3522         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3523    (clobber (reg:CC FLAGS_REG))]
3524   "reload_completed
3525    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3526    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3527   [(set (match_operand:HI 0 "register_operand" "")
3528         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3529
3530 ;; When source and destination does not overlap, clear destination
3531 ;; first and then do the movb
3532 (define_split
3533   [(set (match_operand:HI 0 "register_operand" "")
3534         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3535    (clobber (reg:CC FLAGS_REG))]
3536   "reload_completed
3537    && ANY_QI_REG_P (operands[0])
3538    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3539    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3540   [(set (match_dup 0) (const_int 0))
3541    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3542   "operands[2] = gen_lowpart (QImode, operands[0]);")
3543
3544 ;; Rest is handled by single and.
3545 (define_split
3546   [(set (match_operand:HI 0 "register_operand" "")
3547         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3548    (clobber (reg:CC FLAGS_REG))]
3549   "reload_completed
3550    && true_regnum (operands[0]) == true_regnum (operands[1])"
3551   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3552               (clobber (reg:CC FLAGS_REG))])]
3553   "")
3554
3555 (define_expand "zero_extendqisi2"
3556   [(parallel
3557     [(set (match_operand:SI 0 "register_operand" "")
3558        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3559      (clobber (reg:CC FLAGS_REG))])]
3560   ""
3561   "")
3562
3563 (define_insn "*zero_extendqisi2_and"
3564   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3565      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3566    (clobber (reg:CC FLAGS_REG))]
3567   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3568   "#"
3569   [(set_attr "type" "alu1")
3570    (set_attr "mode" "SI")])
3571
3572 (define_insn "*zero_extendqisi2_movzbw_and"
3573   [(set (match_operand:SI 0 "register_operand" "=r,r")
3574      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3575    (clobber (reg:CC FLAGS_REG))]
3576   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3577   "#"
3578   [(set_attr "type" "imovx,alu1")
3579    (set_attr "mode" "SI")])
3580
3581 (define_insn "*zero_extendqisi2_movzbw"
3582   [(set (match_operand:SI 0 "register_operand" "=r")
3583      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3584   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3585   "movz{bl|x}\t{%1, %0|%0, %1}"
3586   [(set_attr "type" "imovx")
3587    (set_attr "mode" "SI")])
3588
3589 ;; For the movzbl case strip only the clobber
3590 (define_split
3591   [(set (match_operand:SI 0 "register_operand" "")
3592         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3593    (clobber (reg:CC FLAGS_REG))]
3594   "reload_completed
3595    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3596    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3597   [(set (match_dup 0)
3598         (zero_extend:SI (match_dup 1)))])
3599
3600 ;; When source and destination does not overlap, clear destination
3601 ;; first and then do the movb
3602 (define_split
3603   [(set (match_operand:SI 0 "register_operand" "")
3604         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3605    (clobber (reg:CC FLAGS_REG))]
3606   "reload_completed
3607    && ANY_QI_REG_P (operands[0])
3608    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3609    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3610    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3611   [(set (match_dup 0) (const_int 0))
3612    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3613   "operands[2] = gen_lowpart (QImode, operands[0]);")
3614
3615 ;; Rest is handled by single and.
3616 (define_split
3617   [(set (match_operand:SI 0 "register_operand" "")
3618         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3619    (clobber (reg:CC FLAGS_REG))]
3620   "reload_completed
3621    && true_regnum (operands[0]) == true_regnum (operands[1])"
3622   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3623               (clobber (reg:CC FLAGS_REG))])]
3624   "")
3625
3626 ;; %%% Kill me once multi-word ops are sane.
3627 (define_expand "zero_extendsidi2"
3628   [(set (match_operand:DI 0 "register_operand" "")
3629      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3630   ""
3631 {
3632   if (!TARGET_64BIT)
3633     {
3634       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3635       DONE;
3636     }
3637 })
3638
3639 (define_insn "zero_extendsidi2_32"
3640   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3641         (zero_extend:DI
3642          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3643    (clobber (reg:CC FLAGS_REG))]
3644   "!TARGET_64BIT"
3645   "@
3646    #
3647    #
3648    #
3649    movd\t{%1, %0|%0, %1}
3650    movd\t{%1, %0|%0, %1}
3651    movd\t{%1, %0|%0, %1}
3652    movd\t{%1, %0|%0, %1}"
3653   [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3654    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3655
3656 (define_insn "zero_extendsidi2_rex64"
3657   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3658      (zero_extend:DI
3659        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3660   "TARGET_64BIT"
3661   "@
3662    mov\t{%k1, %k0|%k0, %k1}
3663    #
3664    movd\t{%1, %0|%0, %1}
3665    movd\t{%1, %0|%0, %1}
3666    movd\t{%1, %0|%0, %1}
3667    movd\t{%1, %0|%0, %1}"
3668   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3669    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3670
3671 (define_split
3672   [(set (match_operand:DI 0 "memory_operand" "")
3673      (zero_extend:DI (match_dup 0)))]
3674   "TARGET_64BIT"
3675   [(set (match_dup 4) (const_int 0))]
3676   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3677
3678 (define_split
3679   [(set (match_operand:DI 0 "register_operand" "")
3680         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3681    (clobber (reg:CC FLAGS_REG))]
3682   "!TARGET_64BIT && reload_completed
3683    && true_regnum (operands[0]) == true_regnum (operands[1])"
3684   [(set (match_dup 4) (const_int 0))]
3685   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3686
3687 (define_split
3688   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3689         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3690    (clobber (reg:CC FLAGS_REG))]
3691   "!TARGET_64BIT && reload_completed
3692    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3693   [(set (match_dup 3) (match_dup 1))
3694    (set (match_dup 4) (const_int 0))]
3695   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3696
3697 (define_insn "zero_extendhidi2"
3698   [(set (match_operand:DI 0 "register_operand" "=r")
3699      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3700   "TARGET_64BIT"
3701   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3702   [(set_attr "type" "imovx")
3703    (set_attr "mode" "DI")])
3704
3705 (define_insn "zero_extendqidi2"
3706   [(set (match_operand:DI 0 "register_operand" "=r")
3707      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3708   "TARGET_64BIT"
3709   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3710   [(set_attr "type" "imovx")
3711    (set_attr "mode" "DI")])
3712 \f
3713 ;; Sign extension instructions
3714
3715 (define_expand "extendsidi2"
3716   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3717                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3718               (clobber (reg:CC FLAGS_REG))
3719               (clobber (match_scratch:SI 2 ""))])]
3720   ""
3721 {
3722   if (TARGET_64BIT)
3723     {
3724       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3725       DONE;
3726     }
3727 })
3728
3729 (define_insn "*extendsidi2_1"
3730   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3731         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3732    (clobber (reg:CC FLAGS_REG))
3733    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3734   "!TARGET_64BIT"
3735   "#")
3736
3737 (define_insn "extendsidi2_rex64"
3738   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3739         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3740   "TARGET_64BIT"
3741   "@
3742    {cltq|cdqe}
3743    movs{lq|x}\t{%1,%0|%0, %1}"
3744   [(set_attr "type" "imovx")
3745    (set_attr "mode" "DI")
3746    (set_attr "prefix_0f" "0")
3747    (set_attr "modrm" "0,1")])
3748
3749 (define_insn "extendhidi2"
3750   [(set (match_operand:DI 0 "register_operand" "=r")
3751         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3752   "TARGET_64BIT"
3753   "movs{wq|x}\t{%1,%0|%0, %1}"
3754   [(set_attr "type" "imovx")
3755    (set_attr "mode" "DI")])
3756
3757 (define_insn "extendqidi2"
3758   [(set (match_operand:DI 0 "register_operand" "=r")
3759         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3760   "TARGET_64BIT"
3761   "movs{bq|x}\t{%1,%0|%0, %1}"
3762    [(set_attr "type" "imovx")
3763     (set_attr "mode" "DI")])
3764
3765 ;; Extend to memory case when source register does die.
3766 (define_split
3767   [(set (match_operand:DI 0 "memory_operand" "")
3768         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3769    (clobber (reg:CC FLAGS_REG))
3770    (clobber (match_operand:SI 2 "register_operand" ""))]
3771   "(reload_completed
3772     && dead_or_set_p (insn, operands[1])
3773     && !reg_mentioned_p (operands[1], operands[0]))"
3774   [(set (match_dup 3) (match_dup 1))
3775    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3776               (clobber (reg:CC FLAGS_REG))])
3777    (set (match_dup 4) (match_dup 1))]
3778   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3779
3780 ;; Extend to memory case when source register does not die.
3781 (define_split
3782   [(set (match_operand:DI 0 "memory_operand" "")
3783         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3784    (clobber (reg:CC FLAGS_REG))
3785    (clobber (match_operand:SI 2 "register_operand" ""))]
3786   "reload_completed"
3787   [(const_int 0)]
3788 {
3789   split_di (&operands[0], 1, &operands[3], &operands[4]);
3790
3791   emit_move_insn (operands[3], operands[1]);
3792
3793   /* Generate a cltd if possible and doing so it profitable.  */
3794   if ((optimize_size || TARGET_USE_CLTD)
3795       && true_regnum (operands[1]) == AX_REG
3796       && true_regnum (operands[2]) == DX_REG)
3797     {
3798       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3799     }
3800   else
3801     {
3802       emit_move_insn (operands[2], operands[1]);
3803       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3804     }
3805   emit_move_insn (operands[4], operands[2]);
3806   DONE;
3807 })
3808
3809 ;; Extend to register case.  Optimize case where source and destination
3810 ;; registers match and cases where we can use cltd.
3811 (define_split
3812   [(set (match_operand:DI 0 "register_operand" "")
3813         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3814    (clobber (reg:CC FLAGS_REG))
3815    (clobber (match_scratch:SI 2 ""))]
3816   "reload_completed"
3817   [(const_int 0)]
3818 {
3819   split_di (&operands[0], 1, &operands[3], &operands[4]);
3820
3821   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3822     emit_move_insn (operands[3], operands[1]);
3823
3824   /* Generate a cltd if possible and doing so it profitable.  */
3825   if ((optimize_size || TARGET_USE_CLTD)
3826       && true_regnum (operands[3]) == AX_REG)
3827     {
3828       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3829       DONE;
3830     }
3831
3832   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3833     emit_move_insn (operands[4], operands[1]);
3834
3835   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3836   DONE;
3837 })
3838
3839 (define_insn "extendhisi2"
3840   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3841         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3842   ""
3843 {
3844   switch (get_attr_prefix_0f (insn))
3845     {
3846     case 0:
3847       return "{cwtl|cwde}";
3848     default:
3849       return "movs{wl|x}\t{%1,%0|%0, %1}";
3850     }
3851 }
3852   [(set_attr "type" "imovx")
3853    (set_attr "mode" "SI")
3854    (set (attr "prefix_0f")
3855      ;; movsx is short decodable while cwtl is vector decoded.
3856      (if_then_else (and (eq_attr "cpu" "!k6")
3857                         (eq_attr "alternative" "0"))
3858         (const_string "0")
3859         (const_string "1")))
3860    (set (attr "modrm")
3861      (if_then_else (eq_attr "prefix_0f" "0")
3862         (const_string "0")
3863         (const_string "1")))])
3864
3865 (define_insn "*extendhisi2_zext"
3866   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3867         (zero_extend:DI
3868           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3869   "TARGET_64BIT"
3870 {
3871   switch (get_attr_prefix_0f (insn))
3872     {
3873     case 0:
3874       return "{cwtl|cwde}";
3875     default:
3876       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3877     }
3878 }
3879   [(set_attr "type" "imovx")
3880    (set_attr "mode" "SI")
3881    (set (attr "prefix_0f")
3882      ;; movsx is short decodable while cwtl is vector decoded.
3883      (if_then_else (and (eq_attr "cpu" "!k6")
3884                         (eq_attr "alternative" "0"))
3885         (const_string "0")
3886         (const_string "1")))
3887    (set (attr "modrm")
3888      (if_then_else (eq_attr "prefix_0f" "0")
3889         (const_string "0")
3890         (const_string "1")))])
3891
3892 (define_insn "extendqihi2"
3893   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3894         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3895   ""
3896 {
3897   switch (get_attr_prefix_0f (insn))
3898     {
3899     case 0:
3900       return "{cbtw|cbw}";
3901     default:
3902       return "movs{bw|x}\t{%1,%0|%0, %1}";
3903     }
3904 }
3905   [(set_attr "type" "imovx")
3906    (set_attr "mode" "HI")
3907    (set (attr "prefix_0f")
3908      ;; movsx is short decodable while cwtl is vector decoded.
3909      (if_then_else (and (eq_attr "cpu" "!k6")
3910                         (eq_attr "alternative" "0"))
3911         (const_string "0")
3912         (const_string "1")))
3913    (set (attr "modrm")
3914      (if_then_else (eq_attr "prefix_0f" "0")
3915         (const_string "0")
3916         (const_string "1")))])
3917
3918 (define_insn "extendqisi2"
3919   [(set (match_operand:SI 0 "register_operand" "=r")
3920         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3921   ""
3922   "movs{bl|x}\t{%1,%0|%0, %1}"
3923    [(set_attr "type" "imovx")
3924     (set_attr "mode" "SI")])
3925
3926 (define_insn "*extendqisi2_zext"
3927   [(set (match_operand:DI 0 "register_operand" "=r")
3928         (zero_extend:DI
3929           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3930   "TARGET_64BIT"
3931   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3932    [(set_attr "type" "imovx")
3933     (set_attr "mode" "SI")])
3934 \f
3935 ;; Conversions between float and double.
3936
3937 ;; These are all no-ops in the model used for the 80387.  So just
3938 ;; emit moves.
3939
3940 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3941 (define_insn "*dummy_extendsfdf2"
3942   [(set (match_operand:DF 0 "push_operand" "=<")
3943         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3944   "0"
3945   "#")
3946
3947 (define_split
3948   [(set (match_operand:DF 0 "push_operand" "")
3949         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3950   "!TARGET_64BIT"
3951   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3952    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3953
3954 (define_split
3955   [(set (match_operand:DF 0 "push_operand" "")
3956         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3957   "TARGET_64BIT"
3958   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3959    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3960
3961 (define_insn "*dummy_extendsfxf2"
3962   [(set (match_operand:XF 0 "push_operand" "=<")
3963         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3964   "0"
3965   "#")
3966
3967 (define_split
3968   [(set (match_operand:XF 0 "push_operand" "")
3969         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3970   ""
3971   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3972    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3973   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3974
3975 (define_split
3976   [(set (match_operand:XF 0 "push_operand" "")
3977         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3978   "TARGET_64BIT"
3979   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3980    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3981   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3982
3983 (define_split
3984   [(set (match_operand:XF 0 "push_operand" "")
3985         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3986   ""
3987   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3988    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3989   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3990
3991 (define_split
3992   [(set (match_operand:XF 0 "push_operand" "")
3993         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3994   "TARGET_64BIT"
3995   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3996    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3997   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3998
3999 (define_expand "extendsfdf2"
4000   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4001         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4002   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4003 {
4004   /* ??? Needed for compress_float_constant since all fp constants
4005      are LEGITIMATE_CONSTANT_P.  */
4006   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4007     {
4008       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4009           && standard_80387_constant_p (operands[1]) > 0)
4010         {
4011           operands[1] = simplify_const_unary_operation
4012             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4013           emit_move_insn_1 (operands[0], operands[1]);
4014           DONE;
4015         }
4016       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4017     }
4018 })
4019
4020 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4021    cvtss2sd:
4022       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4023       cvtps2pd xmm2,xmm1
4024    We do the conversion post reload to avoid producing of 128bit spills
4025    that might lead to ICE on 32bit target.  The sequence unlikely combine
4026    anyway.  */
4027 (define_split
4028   [(set (match_operand:DF 0 "register_operand" "")
4029         (float_extend:DF
4030           (match_operand:SF 1 "nonimmediate_operand" "")))]
4031   "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4032    && reload_completed && SSE_REG_P (operands[0])"
4033    [(set (match_dup 2)
4034          (float_extend:V2DF
4035            (vec_select:V2SF
4036              (match_dup 3)
4037              (parallel [(const_int 0) (const_int 1)]))))]
4038 {
4039   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4040   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4041   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4042      Try to avoid move when unpacking can be done in source.  */
4043   if (REG_P (operands[1]))
4044     {
4045       /* If it is unsafe to overwrite upper half of source, we need
4046          to move to destination and unpack there.  */
4047       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4048            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4049           && true_regnum (operands[0]) != true_regnum (operands[1]))
4050         {
4051           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4052           emit_move_insn (tmp, operands[1]);
4053         }
4054       else
4055         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4056       emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4057     }
4058   else
4059     emit_insn (gen_vec_setv4sf_0 (operands[3],
4060                                   CONST0_RTX (V4SFmode), operands[1]));
4061 })
4062
4063 (define_insn "*extendsfdf2_mixed"
4064   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4065         (float_extend:DF
4066           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4067   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4068 {
4069   switch (which_alternative)
4070     {
4071     case 0:
4072     case 1:
4073       return output_387_reg_move (insn, operands);
4074
4075     case 2:
4076       return "cvtss2sd\t{%1, %0|%0, %1}";
4077
4078     default:
4079       gcc_unreachable ();
4080     }
4081 }
4082   [(set_attr "type" "fmov,fmov,ssecvt")
4083    (set_attr "mode" "SF,XF,DF")])
4084
4085 (define_insn "*extendsfdf2_sse"
4086   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4087         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4088   "TARGET_SSE2 && TARGET_SSE_MATH"
4089   "cvtss2sd\t{%1, %0|%0, %1}"
4090   [(set_attr "type" "ssecvt")
4091    (set_attr "mode" "DF")])
4092
4093 (define_insn "*extendsfdf2_i387"
4094   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4095         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4096   "TARGET_80387"
4097   "* return output_387_reg_move (insn, operands);"
4098   [(set_attr "type" "fmov")
4099    (set_attr "mode" "SF,XF")])
4100
4101 (define_expand "extend<mode>xf2"
4102   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4103         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4104   "TARGET_80387"
4105 {
4106   /* ??? Needed for compress_float_constant since all fp constants
4107      are LEGITIMATE_CONSTANT_P.  */
4108   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4109     {
4110       if (standard_80387_constant_p (operands[1]) > 0)
4111         {
4112           operands[1] = simplify_const_unary_operation
4113             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4114           emit_move_insn_1 (operands[0], operands[1]);
4115           DONE;
4116         }
4117       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4118     }
4119 })
4120
4121 (define_insn "*extend<mode>xf2_i387"
4122   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4123         (float_extend:XF
4124           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4125   "TARGET_80387"
4126   "* return output_387_reg_move (insn, operands);"
4127   [(set_attr "type" "fmov")
4128    (set_attr "mode" "<MODE>,XF")])
4129
4130 ;; %%% This seems bad bad news.
4131 ;; This cannot output into an f-reg because there is no way to be sure
4132 ;; of truncating in that case.  Otherwise this is just like a simple move
4133 ;; insn.  So we pretend we can output to a reg in order to get better
4134 ;; register preferencing, but we really use a stack slot.
4135
4136 ;; Conversion from DFmode to SFmode.
4137
4138 (define_expand "truncdfsf2"
4139   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4140         (float_truncate:SF
4141           (match_operand:DF 1 "nonimmediate_operand" "")))]
4142   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4143 {
4144   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4145     ;
4146   else if (flag_unsafe_math_optimizations)
4147     ;
4148   else
4149     {
4150       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4151       rtx temp = assign_386_stack_local (SFmode, slot);
4152       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4153       DONE;
4154     }
4155 })
4156
4157 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4158    cvtsd2ss:
4159       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4160       cvtpd2ps xmm2,xmm1
4161    We do the conversion post reload to avoid producing of 128bit spills
4162    that might lead to ICE on 32bit target.  The sequence unlikely combine
4163    anyway.  */
4164 (define_split
4165   [(set (match_operand:SF 0 "register_operand" "")
4166         (float_truncate:SF
4167           (match_operand:DF 1 "nonimmediate_operand" "")))]
4168   "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4169    && reload_completed && SSE_REG_P (operands[0])"
4170    [(set (match_dup 2)
4171          (vec_concat:V4SF
4172            (float_truncate:V2SF
4173              (match_dup 4))
4174            (match_dup 3)))]
4175 {
4176   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4177   operands[3] = CONST0_RTX (V2SFmode);
4178   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4179   /* Use movsd for loading from memory, unpcklpd for registers.
4180      Try to avoid move when unpacking can be done in source, or SSE3
4181      movddup is available.  */
4182   if (REG_P (operands[1]))
4183     {
4184       if (!TARGET_SSE3
4185           && true_regnum (operands[0]) != true_regnum (operands[1])
4186           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4187               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4188         {
4189           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4190           emit_move_insn (tmp, operands[1]);
4191           operands[1] = tmp;
4192         }
4193       else if (!TARGET_SSE3)
4194         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4195       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4196     }
4197   else
4198     emit_insn (gen_sse2_loadlpd (operands[4],
4199                                  CONST0_RTX (V2DFmode), operands[1]));
4200 })
4201
4202 (define_expand "truncdfsf2_with_temp"
4203   [(parallel [(set (match_operand:SF 0 "" "")
4204                    (float_truncate:SF (match_operand:DF 1 "" "")))
4205               (clobber (match_operand:SF 2 "" ""))])]
4206   "")
4207
4208 (define_insn "*truncdfsf_fast_mixed"
4209   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4210         (float_truncate:SF
4211           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4212   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4213 {
4214   switch (which_alternative)
4215     {
4216     case 0:
4217       return output_387_reg_move (insn, operands);
4218     case 1:
4219       return "cvtsd2ss\t{%1, %0|%0, %1}";
4220     default:
4221       gcc_unreachable ();
4222     }
4223 }
4224   [(set_attr "type" "fmov,ssecvt")
4225    (set_attr "mode" "SF")])
4226
4227 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4228 ;; because nothing we do here is unsafe.
4229 (define_insn "*truncdfsf_fast_sse"
4230   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4231         (float_truncate:SF
4232           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4233   "TARGET_SSE2 && TARGET_SSE_MATH"
4234   "cvtsd2ss\t{%1, %0|%0, %1}"
4235   [(set_attr "type" "ssecvt")
4236    (set_attr "mode" "SF")])
4237
4238 (define_insn "*truncdfsf_fast_i387"
4239   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4240         (float_truncate:SF
4241           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4242   "TARGET_80387 && flag_unsafe_math_optimizations"
4243   "* return output_387_reg_move (insn, operands);"
4244   [(set_attr "type" "fmov")
4245    (set_attr "mode" "SF")])
4246
4247 (define_insn "*truncdfsf_mixed"
4248   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y2")
4249         (float_truncate:SF
4250           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Y2m")))
4251    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
4252   "TARGET_MIX_SSE_I387"
4253 {
4254   switch (which_alternative)
4255     {
4256     case 0:
4257       return output_387_reg_move (insn, operands);
4258
4259     case 1:
4260       return "#";
4261     case 2:
4262       return "cvtsd2ss\t{%1, %0|%0, %1}";
4263     default:
4264       gcc_unreachable ();
4265     }
4266 }
4267   [(set_attr "type" "fmov,multi,ssecvt")
4268    (set_attr "unit" "*,i387,*")
4269    (set_attr "mode" "SF")])
4270
4271 (define_insn "*truncdfsf_i387"
4272   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4273         (float_truncate:SF
4274           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4275    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4276   "TARGET_80387"
4277 {
4278   switch (which_alternative)
4279     {
4280     case 0:
4281       return output_387_reg_move (insn, operands);
4282
4283     case 1:
4284       return "#";
4285     default:
4286       gcc_unreachable ();
4287     }
4288 }
4289   [(set_attr "type" "fmov,multi")
4290    (set_attr "unit" "*,i387")
4291    (set_attr "mode" "SF")])
4292
4293 (define_insn "*truncdfsf2_i387_1"
4294   [(set (match_operand:SF 0 "memory_operand" "=m")
4295         (float_truncate:SF
4296           (match_operand:DF 1 "register_operand" "f")))]
4297   "TARGET_80387
4298    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4299    && !TARGET_MIX_SSE_I387"
4300   "* return output_387_reg_move (insn, operands);"
4301   [(set_attr "type" "fmov")
4302    (set_attr "mode" "SF")])
4303
4304 (define_split
4305   [(set (match_operand:SF 0 "register_operand" "")
4306         (float_truncate:SF
4307          (match_operand:DF 1 "fp_register_operand" "")))
4308    (clobber (match_operand 2 "" ""))]
4309   "reload_completed"
4310   [(set (match_dup 2) (match_dup 1))
4311    (set (match_dup 0) (match_dup 2))]
4312 {
4313   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4314 })
4315
4316 ;; Conversion from XFmode to {SF,DF}mode
4317
4318 (define_expand "truncxf<mode>2"
4319   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4320                    (float_truncate:MODEF
4321                      (match_operand:XF 1 "register_operand" "")))
4322               (clobber (match_dup 2))])]
4323   "TARGET_80387"
4324 {
4325   if (flag_unsafe_math_optimizations)
4326     {
4327       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4328       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4329       if (reg != operands[0])
4330         emit_move_insn (operands[0], reg);
4331       DONE;
4332     }
4333   else
4334     {
4335       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4336       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4337     }
4338 })
4339
4340 (define_insn "*truncxfsf2_mixed"
4341   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4342         (float_truncate:SF
4343           (match_operand:XF 1 "register_operand" "f,f")))
4344    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4345   "TARGET_80387"
4346 {
4347   gcc_assert (!which_alternative);
4348   return output_387_reg_move (insn, operands);
4349 }
4350   [(set_attr "type" "fmov,multi")
4351    (set_attr "unit" "*,i387")
4352    (set_attr "mode" "SF")])
4353
4354 (define_insn "*truncxfdf2_mixed"
4355   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4356         (float_truncate:DF
4357           (match_operand:XF 1 "register_operand" "f,f")))
4358    (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4359   "TARGET_80387"
4360 {
4361   gcc_assert (!which_alternative);
4362   return output_387_reg_move (insn, operands);
4363 }
4364   [(set_attr "type" "fmov,multi")
4365    (set_attr "unit" "*,i387")
4366    (set_attr "mode" "DF")])
4367
4368 (define_insn "truncxf<mode>2_i387_noop"
4369   [(set (match_operand:MODEF 0 "register_operand" "=f")
4370         (float_truncate:MODEF
4371           (match_operand:XF 1 "register_operand" "f")))]
4372   "TARGET_80387 && flag_unsafe_math_optimizations"
4373   "* return output_387_reg_move (insn, operands);"
4374   [(set_attr "type" "fmov")
4375    (set_attr "mode" "<MODE>")])
4376
4377 (define_insn "*truncxf<mode>2_i387"
4378   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4379         (float_truncate:MODEF
4380           (match_operand:XF 1 "register_operand" "f")))]
4381   "TARGET_80387"
4382   "* return output_387_reg_move (insn, operands);"
4383   [(set_attr "type" "fmov")
4384    (set_attr "mode" "<MODE>")])
4385
4386 (define_split
4387   [(set (match_operand:MODEF 0 "register_operand" "")
4388         (float_truncate:MODEF
4389           (match_operand:XF 1 "register_operand" "")))
4390    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4391   "TARGET_80387 && reload_completed"
4392   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4393    (set (match_dup 0) (match_dup 2))]
4394   "")
4395
4396 (define_split
4397   [(set (match_operand:MODEF 0 "memory_operand" "")
4398         (float_truncate:MODEF
4399           (match_operand:XF 1 "register_operand" "")))
4400    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4401   "TARGET_80387"
4402   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4403   "")
4404 \f
4405 ;; Signed conversion to DImode.
4406
4407 (define_expand "fix_truncxfdi2"
4408   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4409                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4410               (clobber (reg:CC FLAGS_REG))])]
4411   "TARGET_80387"
4412 {
4413   if (TARGET_FISTTP)
4414    {
4415      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4416      DONE;
4417    }
4418 })
4419
4420 (define_expand "fix_trunc<mode>di2"
4421   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4422                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4423               (clobber (reg:CC FLAGS_REG))])]
4424   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4425 {
4426   if (TARGET_FISTTP
4427       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4428    {
4429      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4430      DONE;
4431    }
4432   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4433    {
4434      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4435      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4436      if (out != operands[0])
4437         emit_move_insn (operands[0], out);
4438      DONE;
4439    }
4440 })
4441
4442 ;; Signed conversion to SImode.
4443
4444 (define_expand "fix_truncxfsi2"
4445   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4446                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4447               (clobber (reg:CC FLAGS_REG))])]
4448   "TARGET_80387"
4449 {
4450   if (TARGET_FISTTP)
4451    {
4452      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4453      DONE;
4454    }
4455 })
4456
4457 (define_expand "fix_trunc<mode>si2"
4458   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4459                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4460               (clobber (reg:CC FLAGS_REG))])]
4461   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4462 {
4463   if (TARGET_FISTTP
4464       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4465    {
4466      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4467      DONE;
4468    }
4469   if (SSE_FLOAT_MODE_P (<MODE>mode))
4470    {
4471      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4472      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4473      if (out != operands[0])
4474         emit_move_insn (operands[0], out);
4475      DONE;
4476    }
4477 })
4478
4479 ;; Signed conversion to HImode.
4480
4481 (define_expand "fix_trunc<mode>hi2"
4482   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4483                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4484               (clobber (reg:CC FLAGS_REG))])]
4485   "TARGET_80387
4486    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4487 {
4488   if (TARGET_FISTTP)
4489    {
4490      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4491      DONE;
4492    }
4493 })
4494
4495 ;; Unsigned conversion to SImode.
4496
4497 (define_expand "fixuns_trunc<mode>si2"
4498   [(parallel
4499     [(set (match_operand:SI 0 "register_operand" "")
4500           (unsigned_fix:SI
4501             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4502      (use (match_dup 2))
4503      (clobber (match_scratch:<ssevecmode> 3 ""))
4504      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4505   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4506 {
4507   enum machine_mode mode = <MODE>mode;
4508   enum machine_mode vecmode = <ssevecmode>mode;
4509   REAL_VALUE_TYPE TWO31r;
4510   rtx two31;
4511
4512   real_ldexp (&TWO31r, &dconst1, 31);
4513   two31 = const_double_from_real_value (TWO31r, mode);
4514   two31 = ix86_build_const_vector (mode, true, two31);
4515   operands[2] = force_reg (vecmode, two31);
4516 })
4517
4518 (define_insn_and_split "*fixuns_trunc<mode>_1"
4519   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4520         (unsigned_fix:SI
4521           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4522    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4523    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4524    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4525   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4526   "#"
4527   "&& reload_completed"
4528   [(const_int 0)]
4529 {
4530   ix86_split_convert_uns_si_sse (operands);
4531   DONE;
4532 })
4533
4534 ;; Unsigned conversion to HImode.
4535 ;; Without these patterns, we'll try the unsigned SI conversion which
4536 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4537
4538 (define_expand "fixuns_trunc<mode>hi2"
4539   [(set (match_dup 2)
4540         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4541    (set (match_operand:HI 0 "nonimmediate_operand" "")
4542         (subreg:HI (match_dup 2) 0))]
4543   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4544   "operands[2] = gen_reg_rtx (SImode);")
4545
4546 ;; When SSE is available, it is always faster to use it!
4547 (define_insn "fix_trunc<mode>di_sse"
4548   [(set (match_operand:DI 0 "register_operand" "=r,r")
4549         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4550   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4551    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4552   "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4553   [(set_attr "type" "sseicvt")
4554    (set_attr "mode" "<MODE>")
4555    (set_attr "athlon_decode" "double,vector")
4556    (set_attr "amdfam10_decode" "double,double")])
4557
4558 (define_insn "fix_trunc<mode>si_sse"
4559   [(set (match_operand:SI 0 "register_operand" "=r,r")
4560         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4561   "SSE_FLOAT_MODE_P (<MODE>mode)
4562    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4563   "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4564   [(set_attr "type" "sseicvt")
4565    (set_attr "mode" "<MODE>")
4566    (set_attr "athlon_decode" "double,vector")
4567    (set_attr "amdfam10_decode" "double,double")])
4568
4569 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4570 (define_peephole2
4571   [(set (match_operand:MODEF 0 "register_operand" "")
4572         (match_operand:MODEF 1 "memory_operand" ""))
4573    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4574         (fix:SSEMODEI24 (match_dup 0)))]
4575   "TARGET_SHORTEN_X87_SSE
4576    && peep2_reg_dead_p (2, operands[0])"
4577   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4578   "")
4579
4580 ;; Avoid vector decoded forms of the instruction.
4581 (define_peephole2
4582   [(match_scratch:DF 2 "Y2")
4583    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4584         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4585   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4586   [(set (match_dup 2) (match_dup 1))
4587    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4588   "")
4589
4590 (define_peephole2
4591   [(match_scratch:SF 2 "x")
4592    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4593         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4594   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4595   [(set (match_dup 2) (match_dup 1))
4596    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4597   "")
4598
4599 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4600   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4601         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4602   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4603    && TARGET_FISTTP
4604    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4605          && (TARGET_64BIT || <MODE>mode != DImode))
4606         && TARGET_SSE_MATH)
4607    && !(reload_completed || reload_in_progress)"
4608   "#"
4609   "&& 1"
4610   [(const_int 0)]
4611 {
4612   if (memory_operand (operands[0], VOIDmode))
4613     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4614   else
4615     {
4616       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4617       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4618                                                             operands[1],
4619                                                             operands[2]));
4620     }
4621   DONE;
4622 }
4623   [(set_attr "type" "fisttp")
4624    (set_attr "mode" "<MODE>")])
4625
4626 (define_insn "fix_trunc<mode>_i387_fisttp"
4627   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4628         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4629    (clobber (match_scratch:XF 2 "=&1f"))]
4630   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4631    && TARGET_FISTTP
4632    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4633          && (TARGET_64BIT || <MODE>mode != DImode))
4634         && TARGET_SSE_MATH)"
4635   "* return output_fix_trunc (insn, operands, 1);"
4636   [(set_attr "type" "fisttp")
4637    (set_attr "mode" "<MODE>")])
4638
4639 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4640   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4641         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4642    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4643    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4644   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4645    && TARGET_FISTTP
4646    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4647         && (TARGET_64BIT || <MODE>mode != DImode))
4648         && TARGET_SSE_MATH)"
4649   "#"
4650   [(set_attr "type" "fisttp")
4651    (set_attr "mode" "<MODE>")])
4652
4653 (define_split
4654   [(set (match_operand:X87MODEI 0 "register_operand" "")
4655         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4656    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4657    (clobber (match_scratch 3 ""))]
4658   "reload_completed"
4659   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4660               (clobber (match_dup 3))])
4661    (set (match_dup 0) (match_dup 2))]
4662   "")
4663
4664 (define_split
4665   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4666         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4667    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4668    (clobber (match_scratch 3 ""))]
4669   "reload_completed"
4670   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4671               (clobber (match_dup 3))])]
4672   "")
4673
4674 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4675 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4676 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4677 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4678 ;; function in i386.c.
4679 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4680   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4681         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4682    (clobber (reg:CC FLAGS_REG))]
4683   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4684    && !TARGET_FISTTP
4685    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4686          && (TARGET_64BIT || <MODE>mode != DImode))
4687    && !(reload_completed || reload_in_progress)"
4688   "#"
4689   "&& 1"
4690   [(const_int 0)]
4691 {
4692   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4693
4694   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4695   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4696   if (memory_operand (operands[0], VOIDmode))
4697     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4698                                          operands[2], operands[3]));
4699   else
4700     {
4701       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4702       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4703                                                      operands[2], operands[3],
4704                                                      operands[4]));
4705     }
4706   DONE;
4707 }
4708   [(set_attr "type" "fistp")
4709    (set_attr "i387_cw" "trunc")
4710    (set_attr "mode" "<MODE>")])
4711
4712 (define_insn "fix_truncdi_i387"
4713   [(set (match_operand:DI 0 "memory_operand" "=m")
4714         (fix:DI (match_operand 1 "register_operand" "f")))
4715    (use (match_operand:HI 2 "memory_operand" "m"))
4716    (use (match_operand:HI 3 "memory_operand" "m"))
4717    (clobber (match_scratch:XF 4 "=&1f"))]
4718   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4719    && !TARGET_FISTTP
4720    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4721   "* return output_fix_trunc (insn, operands, 0);"
4722   [(set_attr "type" "fistp")
4723    (set_attr "i387_cw" "trunc")
4724    (set_attr "mode" "DI")])
4725
4726 (define_insn "fix_truncdi_i387_with_temp"
4727   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4728         (fix:DI (match_operand 1 "register_operand" "f,f")))
4729    (use (match_operand:HI 2 "memory_operand" "m,m"))
4730    (use (match_operand:HI 3 "memory_operand" "m,m"))
4731    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4732    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4733   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4734    && !TARGET_FISTTP
4735    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4736   "#"
4737   [(set_attr "type" "fistp")
4738    (set_attr "i387_cw" "trunc")
4739    (set_attr "mode" "DI")])
4740
4741 (define_split
4742   [(set (match_operand:DI 0 "register_operand" "")
4743         (fix:DI (match_operand 1 "register_operand" "")))
4744    (use (match_operand:HI 2 "memory_operand" ""))
4745    (use (match_operand:HI 3 "memory_operand" ""))
4746    (clobber (match_operand:DI 4 "memory_operand" ""))
4747    (clobber (match_scratch 5 ""))]
4748   "reload_completed"
4749   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4750               (use (match_dup 2))
4751               (use (match_dup 3))
4752               (clobber (match_dup 5))])
4753    (set (match_dup 0) (match_dup 4))]
4754   "")
4755
4756 (define_split
4757   [(set (match_operand:DI 0 "memory_operand" "")
4758         (fix:DI (match_operand 1 "register_operand" "")))
4759    (use (match_operand:HI 2 "memory_operand" ""))
4760    (use (match_operand:HI 3 "memory_operand" ""))
4761    (clobber (match_operand:DI 4 "memory_operand" ""))
4762    (clobber (match_scratch 5 ""))]
4763   "reload_completed"
4764   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4765               (use (match_dup 2))
4766               (use (match_dup 3))
4767               (clobber (match_dup 5))])]
4768   "")
4769
4770 (define_insn "fix_trunc<mode>_i387"
4771   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4772         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4773    (use (match_operand:HI 2 "memory_operand" "m"))
4774    (use (match_operand:HI 3 "memory_operand" "m"))]
4775   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4776    && !TARGET_FISTTP
4777    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4778   "* return output_fix_trunc (insn, operands, 0);"
4779   [(set_attr "type" "fistp")
4780    (set_attr "i387_cw" "trunc")
4781    (set_attr "mode" "<MODE>")])
4782
4783 (define_insn "fix_trunc<mode>_i387_with_temp"
4784   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4785         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4786    (use (match_operand:HI 2 "memory_operand" "m,m"))
4787    (use (match_operand:HI 3 "memory_operand" "m,m"))
4788    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4789   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4790    && !TARGET_FISTTP
4791    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4792   "#"
4793   [(set_attr "type" "fistp")
4794    (set_attr "i387_cw" "trunc")
4795    (set_attr "mode" "<MODE>")])
4796
4797 (define_split
4798   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4799         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4800    (use (match_operand:HI 2 "memory_operand" ""))
4801    (use (match_operand:HI 3 "memory_operand" ""))
4802    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4803   "reload_completed"
4804   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4805               (use (match_dup 2))
4806               (use (match_dup 3))])
4807    (set (match_dup 0) (match_dup 4))]
4808   "")
4809
4810 (define_split
4811   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4812         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4813    (use (match_operand:HI 2 "memory_operand" ""))
4814    (use (match_operand:HI 3 "memory_operand" ""))
4815    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4816   "reload_completed"
4817   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4818               (use (match_dup 2))
4819               (use (match_dup 3))])]
4820   "")
4821
4822 (define_insn "x86_fnstcw_1"
4823   [(set (match_operand:HI 0 "memory_operand" "=m")
4824         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4825   "TARGET_80387"
4826   "fnstcw\t%0"
4827   [(set_attr "length" "2")
4828    (set_attr "mode" "HI")
4829    (set_attr "unit" "i387")])
4830
4831 (define_insn "x86_fldcw_1"
4832   [(set (reg:HI FPCR_REG)
4833         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4834   "TARGET_80387"
4835   "fldcw\t%0"
4836   [(set_attr "length" "2")
4837    (set_attr "mode" "HI")
4838    (set_attr "unit" "i387")
4839    (set_attr "athlon_decode" "vector")
4840    (set_attr "amdfam10_decode" "vector")])
4841 \f
4842 ;; Conversion between fixed point and floating point.
4843
4844 ;; Even though we only accept memory inputs, the backend _really_
4845 ;; wants to be able to do this between registers.
4846
4847 (define_expand "floathi<mode>2"
4848   [(set (match_operand:X87MODEF 0 "register_operand" "")
4849         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4850   "TARGET_80387
4851    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4852        || TARGET_MIX_SSE_I387)"
4853   "")
4854
4855 ;; Pre-reload splitter to add memory clobber to the pattern.
4856 (define_insn_and_split "*floathi<mode>2_1"
4857   [(set (match_operand:X87MODEF 0 "register_operand" "")
4858         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4859   "TARGET_80387
4860    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4861        || TARGET_MIX_SSE_I387)
4862    && !(reload_completed || reload_in_progress)"
4863   "#"
4864   "&& 1"
4865   [(parallel [(set (match_dup 0)
4866               (float:X87MODEF (match_dup 1)))
4867    (clobber (match_dup 2))])]
4868   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4869
4870 (define_insn "*floathi<mode>2_i387_with_temp"
4871   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4872         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4873   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4874   "TARGET_80387
4875    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4876        || TARGET_MIX_SSE_I387)"
4877   "#"
4878   [(set_attr "type" "fmov,multi")
4879    (set_attr "mode" "<MODE>")
4880    (set_attr "unit" "*,i387")
4881    (set_attr "fp_int_src" "true")])
4882
4883 (define_insn "*floathi<mode>2_i387"
4884   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4885         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4886   "TARGET_80387
4887    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4888        || TARGET_MIX_SSE_I387)"
4889   "fild%z1\t%1"
4890   [(set_attr "type" "fmov")
4891    (set_attr "mode" "<MODE>")
4892    (set_attr "fp_int_src" "true")])
4893
4894 (define_split
4895   [(set (match_operand:X87MODEF 0 "register_operand" "")
4896         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4897    (clobber (match_operand:HI 2 "memory_operand" ""))]
4898   "TARGET_80387
4899    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4900        || TARGET_MIX_SSE_I387)
4901    && reload_completed"
4902   [(set (match_dup 2) (match_dup 1))
4903    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4904   "")
4905
4906 (define_split
4907   [(set (match_operand:X87MODEF 0 "register_operand" "")
4908         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4909    (clobber (match_operand:HI 2 "memory_operand" ""))]
4910    "TARGET_80387
4911     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4912         || TARGET_MIX_SSE_I387)
4913     && reload_completed"
4914   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
4915   "")
4916
4917 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4918   [(set (match_operand:X87MODEF 0 "register_operand" "")
4919         (float:X87MODEF
4920           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4921   "TARGET_80387
4922    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4923        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4924   "")
4925
4926 ;; Pre-reload splitter to add memory clobber to the pattern.
4927 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4928   [(set (match_operand:X87MODEF 0 "register_operand" "")
4929         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4930   "((TARGET_80387
4931      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4932            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4933          || TARGET_MIX_SSE_I387))
4934     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4935         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4936         && ((<SSEMODEI24:MODE>mode == SImode
4937              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4938              && flag_trapping_math)
4939             || !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size))))
4940    && !(reload_completed || reload_in_progress)"
4941   "#"
4942   "&& 1"
4943   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4944               (clobber (match_dup 2))])]
4945 {
4946   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4947
4948   /* Avoid store forwarding (partial memory) stall penalty
4949      by passing DImode value through XMM registers.  */
4950   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT 
4951       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES 
4952       && !optimize_size)
4953     {
4954       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4955                                                             operands[1],
4956                                                             operands[2]));
4957       DONE;
4958     }
4959 })
4960
4961 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4962   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4963         (float:MODEF
4964           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4965    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4966   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4967    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4968   "#"
4969   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4970    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4971    (set_attr "unit" "*,i387,*,*,*")
4972    (set_attr "athlon_decode" "*,*,double,direct,double")
4973    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4974    (set_attr "fp_int_src" "true")])
4975
4976 (define_insn "*floatsi<mode>2_vector_mixed"
4977   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4978         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4979   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4980    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4981   "@
4982    fild%z1\t%1
4983    #"
4984   [(set_attr "type" "fmov,sseicvt")
4985    (set_attr "mode" "<MODE>,<ssevecmode>")
4986    (set_attr "unit" "i387,*")
4987    (set_attr "athlon_decode" "*,direct")
4988    (set_attr "amdfam10_decode" "*,double")
4989    (set_attr "fp_int_src" "true")])
4990
4991 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
4992   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4993         (float:MODEF
4994           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
4995   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
4996   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4997    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4998   "#"
4999   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5000    (set_attr "mode" "<MODEF:MODE>")
5001    (set_attr "unit" "*,i387,*,*")
5002    (set_attr "athlon_decode" "*,*,double,direct")
5003    (set_attr "amdfam10_decode" "*,*,vector,double")
5004    (set_attr "fp_int_src" "true")])
5005
5006 (define_split
5007   [(set (match_operand:MODEF 0 "register_operand" "")
5008         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5009    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5010   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5011    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5012    && TARGET_INTER_UNIT_CONVERSIONS
5013    && reload_completed
5014    && (SSE_REG_P (operands[0])
5015        || (GET_CODE (operands[0]) == SUBREG
5016            && SSE_REG_P (operands[0])))"
5017   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5018   "")
5019
5020 (define_split
5021   [(set (match_operand:MODEF 0 "register_operand" "")
5022         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5023    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5024   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5025    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5026    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5027    && reload_completed
5028    && (SSE_REG_P (operands[0])
5029        || (GET_CODE (operands[0]) == SUBREG
5030            && SSE_REG_P (operands[0])))"
5031   [(set (match_dup 2) (match_dup 1))
5032    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5033   "")
5034
5035 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5036   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5037         (float:MODEF
5038           (match_operand:SSEMODEI24 1 "register_operand" "m,r,m")))]
5039   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5040    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5041    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5042   "@
5043    fild%z1\t%1
5044    cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}
5045    cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5046   [(set_attr "type" "fmov,sseicvt,sseicvt")
5047    (set_attr "mode" "<MODEF:MODE>")
5048    (set_attr "unit" "i387,*,*")
5049    (set_attr "athlon_decode" "*,double,direct")
5050    (set_attr "amdfam10_decode" "*,vector,double")
5051    (set_attr "fp_int_src" "true")])
5052
5053 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5054   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5055         (float:MODEF
5056           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5057   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5058    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5059    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5060   "@
5061    fild%z1\t%1
5062    cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5063   [(set_attr "type" "fmov,sseicvt")
5064    (set_attr "mode" "<MODEF:MODE>")
5065    (set_attr "athlon_decode" "*,direct")
5066    (set_attr "amdfam10_decode" "*,double")
5067    (set_attr "fp_int_src" "true")])
5068
5069 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5070   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5071         (float:MODEF
5072           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5073    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5074   "TARGET_SSE2 && TARGET_SSE_MATH
5075    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5076   "#"
5077   [(set_attr "type" "sseicvt")
5078    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5079    (set_attr "athlon_decode" "double,direct,double")
5080    (set_attr "amdfam10_decode" "vector,double,double")
5081    (set_attr "fp_int_src" "true")])
5082
5083 (define_insn "*floatsi<mode>2_vector_sse"
5084   [(set (match_operand:MODEF 0 "register_operand" "=x")
5085         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5086   "TARGET_SSE2 && TARGET_SSE_MATH
5087    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5088   "#"
5089   [(set_attr "type" "sseicvt")
5090    (set_attr "mode" "<MODE>")
5091    (set_attr "athlon_decode" "direct")
5092    (set_attr "amdfam10_decode" "double")
5093    (set_attr "fp_int_src" "true")])
5094
5095 (define_split
5096   [(set (match_operand:MODEF 0 "register_operand" "")
5097         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5098    (clobber (match_operand:SI 2 "memory_operand" ""))]
5099   "TARGET_SSE2 && TARGET_SSE_MATH
5100    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5101    && reload_completed
5102    && (SSE_REG_P (operands[0])
5103        || (GET_CODE (operands[0]) == SUBREG
5104            && SSE_REG_P (operands[0])))"
5105   [(const_int 0)]
5106 {
5107   rtx op1 = operands[1];
5108
5109   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5110                                      <MODE>mode, 0);
5111   if (GET_CODE (op1) == SUBREG)
5112     op1 = SUBREG_REG (op1);
5113
5114   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5115     {
5116       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5117       emit_insn (gen_sse2_loadld (operands[4],
5118                                   CONST0_RTX (V4SImode), operands[1]));
5119     }
5120   /* We can ignore possible trapping value in the
5121      high part of SSE register for non-trapping math. */
5122   else if (SSE_REG_P (op1) && !flag_trapping_math)
5123     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5124   else
5125     {
5126       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5127       emit_move_insn (operands[2], operands[1]);
5128       emit_insn (gen_sse2_loadld (operands[4],
5129                                   CONST0_RTX (V4SImode), operands[2]));
5130     }
5131   emit_insn
5132     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5133   DONE;
5134 })
5135
5136 (define_split
5137   [(set (match_operand:MODEF 0 "register_operand" "")
5138         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5139    (clobber (match_operand:SI 2 "memory_operand" ""))]
5140   "TARGET_SSE2 && TARGET_SSE_MATH
5141    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5142    && reload_completed
5143    && (SSE_REG_P (operands[0])
5144        || (GET_CODE (operands[0]) == SUBREG
5145            && SSE_REG_P (operands[0])))"
5146   [(const_int 0)]
5147 {
5148   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5149                                      <MODE>mode, 0);
5150   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5151
5152   emit_insn (gen_sse2_loadld (operands[4],
5153                               CONST0_RTX (V4SImode), operands[1]));
5154   emit_insn
5155     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5156   DONE;
5157 })
5158
5159 (define_split
5160   [(set (match_operand:MODEF 0 "register_operand" "")
5161         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5162   "TARGET_SSE2 && TARGET_SSE_MATH
5163    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5164    && reload_completed
5165    && (SSE_REG_P (operands[0])
5166        || (GET_CODE (operands[0]) == SUBREG
5167            && SSE_REG_P (operands[0])))"
5168   [(const_int 0)]
5169 {
5170   rtx op1 = operands[1];
5171
5172   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5173                                      <MODE>mode, 0);
5174   if (GET_CODE (op1) == SUBREG)
5175     op1 = SUBREG_REG (op1);
5176
5177   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5178     {
5179       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5180       emit_insn (gen_sse2_loadld (operands[4],
5181                                   CONST0_RTX (V4SImode), operands[1]));
5182     }
5183   /* We can ignore possible trapping value in the
5184      high part of SSE register for non-trapping math. */
5185   else if (SSE_REG_P (op1) && !flag_trapping_math)
5186     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5187   else
5188     gcc_unreachable ();
5189 })
5190
5191 (define_split
5192   [(set (match_operand:MODEF 0 "register_operand" "")
5193         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5194   "TARGET_SSE2 && TARGET_SSE_MATH
5195    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5196    && reload_completed
5197    && (SSE_REG_P (operands[0])
5198        || (GET_CODE (operands[0]) == SUBREG
5199            && SSE_REG_P (operands[0])))"
5200   [(const_int 0)]
5201 {
5202   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5203                                      <MODE>mode, 0);
5204   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5205
5206   emit_insn (gen_sse2_loadld (operands[4],
5207                               CONST0_RTX (V4SImode), operands[1]));
5208   emit_insn
5209     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5210   DONE;
5211 })
5212
5213 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5214   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5215         (float:MODEF
5216           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5217   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5218   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5219    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5220   "#"
5221   [(set_attr "type" "sseicvt")
5222    (set_attr "mode" "<MODEF:MODE>")
5223    (set_attr "athlon_decode" "double,direct")
5224    (set_attr "amdfam10_decode" "vector,double")
5225    (set_attr "fp_int_src" "true")])
5226
5227 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5228   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5229         (float:MODEF
5230           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5231   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5232    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5233    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5234   "@
5235    cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}
5236    cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5237   [(set_attr "type" "sseicvt")
5238    (set_attr "mode" "<MODEF:MODE>")
5239    (set_attr "athlon_decode" "double,direct")
5240    (set_attr "amdfam10_decode" "vector,double")
5241    (set_attr "fp_int_src" "true")])
5242
5243 (define_split
5244   [(set (match_operand:MODEF 0 "register_operand" "")
5245         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5246    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5247   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5248    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5249    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5250    && reload_completed
5251    && (SSE_REG_P (operands[0])
5252        || (GET_CODE (operands[0]) == SUBREG
5253            && SSE_REG_P (operands[0])))"
5254   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5255   "")
5256
5257 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5258   [(set (match_operand:MODEF 0 "register_operand" "=x")
5259         (float:MODEF
5260           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5261   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5262    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5263    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5264   "cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5265   [(set_attr "type" "sseicvt")
5266    (set_attr "mode" "<MODEF:MODE>")
5267    (set_attr "athlon_decode" "direct")
5268    (set_attr "amdfam10_decode" "double")
5269    (set_attr "fp_int_src" "true")])
5270
5271 (define_split
5272   [(set (match_operand:MODEF 0 "register_operand" "")
5273         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5274    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5275   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5276    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5277    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5278    && reload_completed
5279    && (SSE_REG_P (operands[0])
5280        || (GET_CODE (operands[0]) == SUBREG
5281            && SSE_REG_P (operands[0])))"
5282   [(set (match_dup 2) (match_dup 1))
5283    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5284   "")
5285
5286 (define_split
5287   [(set (match_operand:MODEF 0 "register_operand" "")
5288         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5289    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5290   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5291    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5292    && reload_completed
5293    && (SSE_REG_P (operands[0])
5294        || (GET_CODE (operands[0]) == SUBREG
5295            && SSE_REG_P (operands[0])))"
5296   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5297   "")
5298
5299 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5300   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5301         (float:X87MODEF
5302           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5303   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5304   "TARGET_80387"
5305   "@
5306    fild%z1\t%1
5307    #"
5308   [(set_attr "type" "fmov,multi")
5309    (set_attr "mode" "<X87MODEF:MODE>")
5310    (set_attr "unit" "*,i387")
5311    (set_attr "fp_int_src" "true")])
5312
5313 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5314   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5315         (float:X87MODEF
5316           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5317   "TARGET_80387"
5318   "fild%z1\t%1"
5319   [(set_attr "type" "fmov")
5320    (set_attr "mode" "<X87MODEF:MODE>")
5321    (set_attr "fp_int_src" "true")])
5322
5323 (define_split
5324   [(set (match_operand:X87MODEF 0 "register_operand" "")
5325         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5326    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5327   "TARGET_80387
5328    && reload_completed
5329    && FP_REG_P (operands[0])"
5330   [(set (match_dup 2) (match_dup 1))
5331    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5332   "")
5333
5334 (define_split
5335   [(set (match_operand:X87MODEF 0 "register_operand" "")
5336         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5337    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5338   "TARGET_80387
5339    && reload_completed
5340    && FP_REG_P (operands[0])"
5341   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5342   "")
5343
5344 ;; Avoid store forwarding (partial memory) stall penalty
5345 ;; by passing DImode value through XMM registers.  */
5346
5347 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5348   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5349         (float:X87MODEF
5350           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5351    (clobber (match_scratch:V4SI 3 "=X,x"))
5352    (clobber (match_scratch:V4SI 4 "=X,x"))
5353    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5354   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5355    && !TARGET_64BIT && !optimize_size"
5356   "#"
5357   [(set_attr "type" "multi")
5358    (set_attr "mode" "<X87MODEF:MODE>")
5359    (set_attr "unit" "i387")
5360    (set_attr "fp_int_src" "true")])
5361
5362 (define_split
5363   [(set (match_operand:X87MODEF 0 "register_operand" "")
5364         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5365    (clobber (match_scratch:V4SI 3 ""))
5366    (clobber (match_scratch:V4SI 4 ""))
5367    (clobber (match_operand:DI 2 "memory_operand" ""))]
5368   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5369    && !TARGET_64BIT && !optimize_size
5370    && reload_completed
5371    && FP_REG_P (operands[0])"
5372   [(set (match_dup 2) (match_dup 3))
5373    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5374 {
5375   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5376      Assemble the 64-bit DImode value in an xmm register.  */
5377   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5378                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5379   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5380                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5381   emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5382
5383   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5384 })
5385
5386 (define_split
5387   [(set (match_operand:X87MODEF 0 "register_operand" "")
5388         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5389    (clobber (match_scratch:V4SI 3 ""))
5390    (clobber (match_scratch:V4SI 4 ""))
5391    (clobber (match_operand:DI 2 "memory_operand" ""))]
5392   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5393    && !TARGET_64BIT && !optimize_size
5394    && reload_completed
5395    && FP_REG_P (operands[0])"
5396   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5397   "")
5398
5399 ;; Avoid store forwarding (partial memory) stall penalty by extending
5400 ;; SImode value to DImode through XMM register instead of pushing two
5401 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5402 ;; targets benefit from this optimization. Also note that fild
5403 ;; loads from memory only.
5404
5405 (define_insn "*floatunssi<mode>2_1"
5406   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5407         (unsigned_float:X87MODEF
5408           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5409    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5410    (clobber (match_scratch:SI 3 "=X,x"))]
5411   "!TARGET_64BIT
5412    && TARGET_80387 && TARGET_SSE"
5413   "#"
5414   [(set_attr "type" "multi")
5415    (set_attr "mode" "<MODE>")])
5416
5417 (define_split
5418   [(set (match_operand:X87MODEF 0 "register_operand" "")
5419         (unsigned_float:X87MODEF
5420           (match_operand:SI 1 "register_operand" "")))
5421    (clobber (match_operand:DI 2 "memory_operand" ""))
5422    (clobber (match_scratch:SI 3 ""))]
5423   "!TARGET_64BIT
5424    && TARGET_80387 && TARGET_SSE
5425    && reload_completed"
5426   [(set (match_dup 2) (match_dup 1))
5427    (set (match_dup 0)
5428         (float:X87MODEF (match_dup 2)))]
5429   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5430
5431 (define_split
5432   [(set (match_operand:X87MODEF 0 "register_operand" "")
5433         (unsigned_float:X87MODEF
5434           (match_operand:SI 1 "memory_operand" "")))
5435    (clobber (match_operand:DI 2 "memory_operand" ""))
5436    (clobber (match_scratch:SI 3 ""))]
5437   "!TARGET_64BIT
5438    && TARGET_80387 && TARGET_SSE
5439    && reload_completed"
5440   [(set (match_dup 2) (match_dup 3))
5441    (set (match_dup 0)
5442         (float:X87MODEF (match_dup 2)))]
5443 {
5444   emit_move_insn (operands[3], operands[1]);
5445   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5446 })
5447
5448 (define_expand "floatunssi<mode>2"
5449   [(parallel
5450      [(set (match_operand:X87MODEF 0 "register_operand" "")
5451            (unsigned_float:X87MODEF
5452              (match_operand:SI 1 "nonimmediate_operand" "")))
5453       (clobber (match_dup 2))
5454       (clobber (match_scratch:SI 3 ""))])]
5455   "!TARGET_64BIT
5456    && ((TARGET_80387 && TARGET_SSE)
5457        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5458 {
5459   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5460     {
5461       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5462       DONE;
5463     }
5464   else
5465     {
5466       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5467       operands[2] = assign_386_stack_local (DImode, slot);
5468     }
5469 })
5470
5471 (define_expand "floatunsdisf2"
5472   [(use (match_operand:SF 0 "register_operand" ""))
5473    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5474   "TARGET_64BIT && TARGET_SSE_MATH"
5475   "x86_emit_floatuns (operands); DONE;")
5476
5477 (define_expand "floatunsdidf2"
5478   [(use (match_operand:DF 0 "register_operand" ""))
5479    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5480   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5481    && TARGET_SSE2 && TARGET_SSE_MATH"
5482 {
5483   if (TARGET_64BIT)
5484     x86_emit_floatuns (operands);
5485   else
5486     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5487   DONE;
5488 })
5489 \f
5490 ;; Add instructions
5491
5492 ;; %%% splits for addditi3
5493
5494 (define_expand "addti3"
5495   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5496         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5497                  (match_operand:TI 2 "x86_64_general_operand" "")))
5498    (clobber (reg:CC FLAGS_REG))]
5499   "TARGET_64BIT"
5500   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5501
5502 (define_insn "*addti3_1"
5503   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5504         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5505                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5506    (clobber (reg:CC FLAGS_REG))]
5507   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5508   "#")
5509
5510 (define_split
5511   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5512         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5513                  (match_operand:TI 2 "x86_64_general_operand" "")))
5514    (clobber (reg:CC FLAGS_REG))]
5515   "TARGET_64BIT && reload_completed"
5516   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5517                                           UNSPEC_ADD_CARRY))
5518               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5519    (parallel [(set (match_dup 3)
5520                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5521                                      (match_dup 4))
5522                             (match_dup 5)))
5523               (clobber (reg:CC FLAGS_REG))])]
5524   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5525
5526 ;; %%% splits for addsidi3
5527 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5528 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5529 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5530
5531 (define_expand "adddi3"
5532   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5533         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5534                  (match_operand:DI 2 "x86_64_general_operand" "")))
5535    (clobber (reg:CC FLAGS_REG))]
5536   ""
5537   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5538
5539 (define_insn "*adddi3_1"
5540   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5541         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5542                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5543    (clobber (reg:CC FLAGS_REG))]
5544   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5545   "#")
5546
5547 (define_split
5548   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5549         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5550                  (match_operand:DI 2 "general_operand" "")))
5551    (clobber (reg:CC FLAGS_REG))]
5552   "!TARGET_64BIT && reload_completed"
5553   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5554                                           UNSPEC_ADD_CARRY))
5555               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5556    (parallel [(set (match_dup 3)
5557                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5558                                      (match_dup 4))
5559                             (match_dup 5)))
5560               (clobber (reg:CC FLAGS_REG))])]
5561   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5562
5563 (define_insn "adddi3_carry_rex64"
5564   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5565           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5566                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5567                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5568    (clobber (reg:CC FLAGS_REG))]
5569   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5570   "adc{q}\t{%2, %0|%0, %2}"
5571   [(set_attr "type" "alu")
5572    (set_attr "pent_pair" "pu")
5573    (set_attr "mode" "DI")])
5574
5575 (define_insn "*adddi3_cc_rex64"
5576   [(set (reg:CC FLAGS_REG)
5577         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5578                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5579                    UNSPEC_ADD_CARRY))
5580    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5581         (plus:DI (match_dup 1) (match_dup 2)))]
5582   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5583   "add{q}\t{%2, %0|%0, %2}"
5584   [(set_attr "type" "alu")
5585    (set_attr "mode" "DI")])
5586
5587 (define_insn "*<addsub><mode>3_cc_overflow"
5588   [(set (reg:CCC FLAGS_REG)
5589         (compare:CCC
5590             (plusminus:SWI
5591                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5592                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5593             (match_dup 1)))
5594    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5595         (plusminus:SWI (match_dup 1) (match_dup 2)))]
5596   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5597   "<addsub>{<imodesuffix>}\t{%2, %0|%0, %2}"
5598   [(set_attr "type" "alu")
5599    (set_attr "mode" "<MODE>")])
5600
5601 (define_insn "*add<mode>3_cconly_overflow"
5602   [(set (reg:CCC FLAGS_REG)
5603         (compare:CCC
5604                 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5605                           (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5606                 (match_dup 1)))
5607    (clobber (match_scratch:SWI 0 "=<r>"))]
5608   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5609   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5610   [(set_attr "type" "alu")
5611    (set_attr "mode" "<MODE>")])
5612
5613 (define_insn "*sub<mode>3_cconly_overflow"
5614   [(set (reg:CCC FLAGS_REG)
5615         (compare:CCC
5616              (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5617                         (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5618              (match_dup 0)))]
5619   ""
5620   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5621   [(set_attr "type" "icmp")
5622    (set_attr "mode" "<MODE>")])
5623
5624 (define_insn "*<addsub>si3_zext_cc_overflow"
5625   [(set (reg:CCC FLAGS_REG)
5626         (compare:CCC
5627             (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5628                           (match_operand:SI 2 "general_operand" "g"))
5629             (match_dup 1)))
5630    (set (match_operand:DI 0 "register_operand" "=r")
5631         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5632   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5633   "<addsub>{l}\t{%2, %k0|%k0, %2}"
5634   [(set_attr "type" "alu")
5635    (set_attr "mode" "SI")])
5636
5637 (define_insn "addqi3_carry"
5638   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5639           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5640                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5641                    (match_operand:QI 2 "general_operand" "qi,qm")))
5642    (clobber (reg:CC FLAGS_REG))]
5643   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5644   "adc{b}\t{%2, %0|%0, %2}"
5645   [(set_attr "type" "alu")
5646    (set_attr "pent_pair" "pu")
5647    (set_attr "mode" "QI")])
5648
5649 (define_insn "addhi3_carry"
5650   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5651           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5652                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5653                    (match_operand:HI 2 "general_operand" "ri,rm")))
5654    (clobber (reg:CC FLAGS_REG))]
5655   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5656   "adc{w}\t{%2, %0|%0, %2}"
5657   [(set_attr "type" "alu")
5658    (set_attr "pent_pair" "pu")
5659    (set_attr "mode" "HI")])
5660
5661 (define_insn "addsi3_carry"
5662   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5663           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5664                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5665                    (match_operand:SI 2 "general_operand" "ri,rm")))
5666    (clobber (reg:CC FLAGS_REG))]
5667   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5668   "adc{l}\t{%2, %0|%0, %2}"
5669   [(set_attr "type" "alu")
5670    (set_attr "pent_pair" "pu")
5671    (set_attr "mode" "SI")])
5672
5673 (define_insn "*addsi3_carry_zext"
5674   [(set (match_operand:DI 0 "register_operand" "=r")
5675           (zero_extend:DI
5676             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5677                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5678                      (match_operand:SI 2 "general_operand" "g"))))
5679    (clobber (reg:CC FLAGS_REG))]
5680   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5681   "adc{l}\t{%2, %k0|%k0, %2}"
5682   [(set_attr "type" "alu")
5683    (set_attr "pent_pair" "pu")
5684    (set_attr "mode" "SI")])
5685
5686 (define_insn "*addsi3_cc"
5687   [(set (reg:CC FLAGS_REG)
5688         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5689                     (match_operand:SI 2 "general_operand" "ri,rm")]
5690                    UNSPEC_ADD_CARRY))
5691    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5692         (plus:SI (match_dup 1) (match_dup 2)))]
5693   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5694   "add{l}\t{%2, %0|%0, %2}"
5695   [(set_attr "type" "alu")
5696    (set_attr "mode" "SI")])
5697
5698 (define_insn "addqi3_cc"
5699   [(set (reg:CC FLAGS_REG)
5700         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5701                     (match_operand:QI 2 "general_operand" "qi,qm")]
5702                    UNSPEC_ADD_CARRY))
5703    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5704         (plus:QI (match_dup 1) (match_dup 2)))]
5705   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5706   "add{b}\t{%2, %0|%0, %2}"
5707   [(set_attr "type" "alu")
5708    (set_attr "mode" "QI")])
5709
5710 (define_expand "addsi3"
5711   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5712                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5713                             (match_operand:SI 2 "general_operand" "")))
5714               (clobber (reg:CC FLAGS_REG))])]
5715   ""
5716   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5717
5718 (define_insn "*lea_1"
5719   [(set (match_operand:SI 0 "register_operand" "=r")
5720         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5721   "!TARGET_64BIT"
5722   "lea{l}\t{%a1, %0|%0, %a1}"
5723   [(set_attr "type" "lea")
5724    (set_attr "mode" "SI")])
5725
5726 (define_insn "*lea_1_rex64"
5727   [(set (match_operand:SI 0 "register_operand" "=r")
5728         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5729   "TARGET_64BIT"
5730   "lea{l}\t{%a1, %0|%0, %a1}"
5731   [(set_attr "type" "lea")
5732    (set_attr "mode" "SI")])
5733
5734 (define_insn "*lea_1_zext"
5735   [(set (match_operand:DI 0 "register_operand" "=r")
5736         (zero_extend:DI
5737          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5738   "TARGET_64BIT"
5739   "lea{l}\t{%a1, %k0|%k0, %a1}"
5740   [(set_attr "type" "lea")
5741    (set_attr "mode" "SI")])
5742
5743 (define_insn "*lea_2_rex64"
5744   [(set (match_operand:DI 0 "register_operand" "=r")
5745         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5746   "TARGET_64BIT"
5747   "lea{q}\t{%a1, %0|%0, %a1}"
5748   [(set_attr "type" "lea")
5749    (set_attr "mode" "DI")])
5750
5751 ;; The lea patterns for non-Pmodes needs to be matched by several
5752 ;; insns converted to real lea by splitters.
5753
5754 (define_insn_and_split "*lea_general_1"
5755   [(set (match_operand 0 "register_operand" "=r")
5756         (plus (plus (match_operand 1 "index_register_operand" "l")
5757                     (match_operand 2 "register_operand" "r"))
5758               (match_operand 3 "immediate_operand" "i")))]
5759   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5760     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5761    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5762    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5763    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5764    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5765        || GET_MODE (operands[3]) == VOIDmode)"
5766   "#"
5767   "&& reload_completed"
5768   [(const_int 0)]
5769 {
5770   rtx pat;
5771   operands[0] = gen_lowpart (SImode, operands[0]);
5772   operands[1] = gen_lowpart (Pmode, operands[1]);
5773   operands[2] = gen_lowpart (Pmode, operands[2]);
5774   operands[3] = gen_lowpart (Pmode, operands[3]);
5775   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5776                       operands[3]);
5777   if (Pmode != SImode)
5778     pat = gen_rtx_SUBREG (SImode, pat, 0);
5779   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5780   DONE;
5781 }
5782   [(set_attr "type" "lea")
5783    (set_attr "mode" "SI")])
5784
5785 (define_insn_and_split "*lea_general_1_zext"
5786   [(set (match_operand:DI 0 "register_operand" "=r")
5787         (zero_extend:DI
5788           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5789                             (match_operand:SI 2 "register_operand" "r"))
5790                    (match_operand:SI 3 "immediate_operand" "i"))))]
5791   "TARGET_64BIT"
5792   "#"
5793   "&& reload_completed"
5794   [(set (match_dup 0)
5795         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5796                                                      (match_dup 2))
5797                                             (match_dup 3)) 0)))]
5798 {
5799   operands[1] = gen_lowpart (Pmode, operands[1]);
5800   operands[2] = gen_lowpart (Pmode, operands[2]);
5801   operands[3] = gen_lowpart (Pmode, operands[3]);
5802 }
5803   [(set_attr "type" "lea")
5804    (set_attr "mode" "SI")])
5805
5806 (define_insn_and_split "*lea_general_2"
5807   [(set (match_operand 0 "register_operand" "=r")
5808         (plus (mult (match_operand 1 "index_register_operand" "l")
5809                     (match_operand 2 "const248_operand" "i"))
5810               (match_operand 3 "nonmemory_operand" "ri")))]
5811   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5812     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5813    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5814    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5815    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5816        || GET_MODE (operands[3]) == VOIDmode)"
5817   "#"
5818   "&& reload_completed"
5819   [(const_int 0)]
5820 {
5821   rtx pat;
5822   operands[0] = gen_lowpart (SImode, operands[0]);
5823   operands[1] = gen_lowpart (Pmode, operands[1]);
5824   operands[3] = gen_lowpart (Pmode, operands[3]);
5825   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5826                       operands[3]);
5827   if (Pmode != SImode)
5828     pat = gen_rtx_SUBREG (SImode, pat, 0);
5829   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5830   DONE;
5831 }
5832   [(set_attr "type" "lea")
5833    (set_attr "mode" "SI")])
5834
5835 (define_insn_and_split "*lea_general_2_zext"
5836   [(set (match_operand:DI 0 "register_operand" "=r")
5837         (zero_extend:DI
5838           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5839                             (match_operand:SI 2 "const248_operand" "n"))
5840                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5841   "TARGET_64BIT"
5842   "#"
5843   "&& reload_completed"
5844   [(set (match_dup 0)
5845         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5846                                                      (match_dup 2))
5847                                             (match_dup 3)) 0)))]
5848 {
5849   operands[1] = gen_lowpart (Pmode, operands[1]);
5850   operands[3] = gen_lowpart (Pmode, operands[3]);
5851 }
5852   [(set_attr "type" "lea")
5853    (set_attr "mode" "SI")])
5854
5855 (define_insn_and_split "*lea_general_3"
5856   [(set (match_operand 0 "register_operand" "=r")
5857         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5858                           (match_operand 2 "const248_operand" "i"))
5859                     (match_operand 3 "register_operand" "r"))
5860               (match_operand 4 "immediate_operand" "i")))]
5861   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5862     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5863    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5864    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5865    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5866   "#"
5867   "&& reload_completed"
5868   [(const_int 0)]
5869 {
5870   rtx pat;
5871   operands[0] = gen_lowpart (SImode, operands[0]);
5872   operands[1] = gen_lowpart (Pmode, operands[1]);
5873   operands[3] = gen_lowpart (Pmode, operands[3]);
5874   operands[4] = gen_lowpart (Pmode, operands[4]);
5875   pat = gen_rtx_PLUS (Pmode,
5876                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5877                                                          operands[2]),
5878                                     operands[3]),
5879                       operands[4]);
5880   if (Pmode != SImode)
5881     pat = gen_rtx_SUBREG (SImode, pat, 0);
5882   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5883   DONE;
5884 }
5885   [(set_attr "type" "lea")
5886    (set_attr "mode" "SI")])
5887
5888 (define_insn_and_split "*lea_general_3_zext"
5889   [(set (match_operand:DI 0 "register_operand" "=r")
5890         (zero_extend:DI
5891           (plus:SI (plus:SI (mult:SI
5892                               (match_operand:SI 1 "index_register_operand" "l")
5893                               (match_operand:SI 2 "const248_operand" "n"))
5894                             (match_operand:SI 3 "register_operand" "r"))
5895                    (match_operand:SI 4 "immediate_operand" "i"))))]
5896   "TARGET_64BIT"
5897   "#"
5898   "&& reload_completed"
5899   [(set (match_dup 0)
5900         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5901                                                               (match_dup 2))
5902                                                      (match_dup 3))
5903                                             (match_dup 4)) 0)))]
5904 {
5905   operands[1] = gen_lowpart (Pmode, operands[1]);
5906   operands[3] = gen_lowpart (Pmode, operands[3]);
5907   operands[4] = gen_lowpart (Pmode, operands[4]);
5908 }
5909   [(set_attr "type" "lea")
5910    (set_attr "mode" "SI")])
5911
5912 (define_insn "*adddi_1_rex64"
5913   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5914         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5915                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5916    (clobber (reg:CC FLAGS_REG))]
5917   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5918 {
5919   switch (get_attr_type (insn))
5920     {
5921     case TYPE_LEA:
5922       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5923       return "lea{q}\t{%a2, %0|%0, %a2}";
5924
5925     case TYPE_INCDEC:
5926       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5927       if (operands[2] == const1_rtx)
5928         return "inc{q}\t%0";
5929       else
5930         {
5931           gcc_assert (operands[2] == constm1_rtx);
5932           return "dec{q}\t%0";
5933         }
5934
5935     default:
5936       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5937
5938       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5939          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5940       if (CONST_INT_P (operands[2])
5941           /* Avoid overflows.  */
5942           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5943           && (INTVAL (operands[2]) == 128
5944               || (INTVAL (operands[2]) < 0
5945                   && INTVAL (operands[2]) != -128)))
5946         {
5947           operands[2] = GEN_INT (-INTVAL (operands[2]));
5948           return "sub{q}\t{%2, %0|%0, %2}";
5949         }
5950       return "add{q}\t{%2, %0|%0, %2}";
5951     }
5952 }
5953   [(set (attr "type")
5954      (cond [(eq_attr "alternative" "2")
5955               (const_string "lea")
5956             ; Current assemblers are broken and do not allow @GOTOFF in
5957             ; ought but a memory context.
5958             (match_operand:DI 2 "pic_symbolic_operand" "")
5959               (const_string "lea")
5960             (match_operand:DI 2 "incdec_operand" "")
5961               (const_string "incdec")
5962            ]
5963            (const_string "alu")))
5964    (set_attr "mode" "DI")])
5965
5966 ;; Convert lea to the lea pattern to avoid flags dependency.
5967 (define_split
5968   [(set (match_operand:DI 0 "register_operand" "")
5969         (plus:DI (match_operand:DI 1 "register_operand" "")
5970                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5971    (clobber (reg:CC FLAGS_REG))]
5972   "TARGET_64BIT && reload_completed
5973    && true_regnum (operands[0]) != true_regnum (operands[1])"
5974   [(set (match_dup 0)
5975         (plus:DI (match_dup 1)
5976                  (match_dup 2)))]
5977   "")
5978
5979 (define_insn "*adddi_2_rex64"
5980   [(set (reg FLAGS_REG)
5981         (compare
5982           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5983                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5984           (const_int 0)))
5985    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5986         (plus:DI (match_dup 1) (match_dup 2)))]
5987   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5988    && ix86_binary_operator_ok (PLUS, DImode, operands)
5989    /* Current assemblers are broken and do not allow @GOTOFF in
5990       ought but a memory context.  */
5991    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5992 {
5993   switch (get_attr_type (insn))
5994     {
5995     case TYPE_INCDEC:
5996       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5997       if (operands[2] == const1_rtx)
5998         return "inc{q}\t%0";
5999       else
6000         {
6001           gcc_assert (operands[2] == constm1_rtx);
6002           return "dec{q}\t%0";
6003         }
6004
6005     default:
6006       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6007       /* ???? We ought to handle there the 32bit case too
6008          - do we need new constraint?  */
6009       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6010          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6011       if (CONST_INT_P (operands[2])
6012           /* Avoid overflows.  */
6013           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6014           && (INTVAL (operands[2]) == 128
6015               || (INTVAL (operands[2]) < 0
6016                   && INTVAL (operands[2]) != -128)))
6017         {
6018           operands[2] = GEN_INT (-INTVAL (operands[2]));
6019           return "sub{q}\t{%2, %0|%0, %2}";
6020         }
6021       return "add{q}\t{%2, %0|%0, %2}";
6022     }
6023 }
6024   [(set (attr "type")
6025      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6026         (const_string "incdec")
6027         (const_string "alu")))
6028    (set_attr "mode" "DI")])
6029
6030 (define_insn "*adddi_3_rex64"
6031   [(set (reg FLAGS_REG)
6032         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6033                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
6034    (clobber (match_scratch:DI 0 "=r"))]
6035   "TARGET_64BIT
6036    && ix86_match_ccmode (insn, CCZmode)
6037    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6038    /* Current assemblers are broken and do not allow @GOTOFF in
6039       ought but a memory context.  */
6040    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6041 {
6042   switch (get_attr_type (insn))
6043     {
6044     case TYPE_INCDEC:
6045       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6046       if (operands[2] == const1_rtx)
6047         return "inc{q}\t%0";
6048       else
6049         {
6050           gcc_assert (operands[2] == constm1_rtx);
6051           return "dec{q}\t%0";
6052         }
6053
6054     default:
6055       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6056       /* ???? We ought to handle there the 32bit case too
6057          - do we need new constraint?  */
6058       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6059          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6060       if (CONST_INT_P (operands[2])
6061           /* Avoid overflows.  */
6062           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6063           && (INTVAL (operands[2]) == 128
6064               || (INTVAL (operands[2]) < 0
6065                   && INTVAL (operands[2]) != -128)))
6066         {
6067           operands[2] = GEN_INT (-INTVAL (operands[2]));
6068           return "sub{q}\t{%2, %0|%0, %2}";
6069         }
6070       return "add{q}\t{%2, %0|%0, %2}";
6071     }
6072 }
6073   [(set (attr "type")
6074      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6075         (const_string "incdec")
6076         (const_string "alu")))
6077    (set_attr "mode" "DI")])
6078
6079 ; For comparisons against 1, -1 and 128, we may generate better code
6080 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6081 ; is matched then.  We can't accept general immediate, because for
6082 ; case of overflows,  the result is messed up.
6083 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6084 ; when negated.
6085 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6086 ; only for comparisons not depending on it.
6087 (define_insn "*adddi_4_rex64"
6088   [(set (reg FLAGS_REG)
6089         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6090                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6091    (clobber (match_scratch:DI 0 "=rm"))]
6092   "TARGET_64BIT
6093    &&  ix86_match_ccmode (insn, CCGCmode)"
6094 {
6095   switch (get_attr_type (insn))
6096     {
6097     case TYPE_INCDEC:
6098       if (operands[2] == constm1_rtx)
6099         return "inc{q}\t%0";
6100       else
6101         {
6102           gcc_assert (operands[2] == const1_rtx);
6103           return "dec{q}\t%0";
6104         }
6105
6106     default:
6107       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6108       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6109          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6110       if ((INTVAL (operands[2]) == -128
6111            || (INTVAL (operands[2]) > 0
6112                && INTVAL (operands[2]) != 128))
6113           /* Avoid overflows.  */
6114           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6115         return "sub{q}\t{%2, %0|%0, %2}";
6116       operands[2] = GEN_INT (-INTVAL (operands[2]));
6117       return "add{q}\t{%2, %0|%0, %2}";
6118     }
6119 }
6120   [(set (attr "type")
6121      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6122         (const_string "incdec")
6123         (const_string "alu")))
6124    (set_attr "mode" "DI")])
6125
6126 (define_insn "*adddi_5_rex64"
6127   [(set (reg FLAGS_REG)
6128         (compare
6129           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6130                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
6131           (const_int 0)))
6132    (clobber (match_scratch:DI 0 "=r"))]
6133   "TARGET_64BIT
6134    && ix86_match_ccmode (insn, CCGOCmode)
6135    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6136    /* Current assemblers are broken and do not allow @GOTOFF in
6137       ought but a memory context.  */
6138    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6139 {
6140   switch (get_attr_type (insn))
6141     {
6142     case TYPE_INCDEC:
6143       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6144       if (operands[2] == const1_rtx)
6145         return "inc{q}\t%0";
6146       else
6147         {
6148           gcc_assert (operands[2] == constm1_rtx);
6149           return "dec{q}\t%0";
6150         }
6151
6152     default:
6153       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6154       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6155          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6156       if (CONST_INT_P (operands[2])
6157           /* Avoid overflows.  */
6158           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6159           && (INTVAL (operands[2]) == 128
6160               || (INTVAL (operands[2]) < 0
6161                   && INTVAL (operands[2]) != -128)))
6162         {
6163           operands[2] = GEN_INT (-INTVAL (operands[2]));
6164           return "sub{q}\t{%2, %0|%0, %2}";
6165         }
6166       return "add{q}\t{%2, %0|%0, %2}";
6167     }
6168 }
6169   [(set (attr "type")
6170      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6171         (const_string "incdec")
6172         (const_string "alu")))
6173    (set_attr "mode" "DI")])
6174
6175
6176 (define_insn "*addsi_1"
6177   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6178         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6179                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
6180    (clobber (reg:CC FLAGS_REG))]
6181   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6182 {
6183   switch (get_attr_type (insn))
6184     {
6185     case TYPE_LEA:
6186       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6187       return "lea{l}\t{%a2, %0|%0, %a2}";
6188
6189     case TYPE_INCDEC:
6190       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6191       if (operands[2] == const1_rtx)
6192         return "inc{l}\t%0";
6193       else
6194         {
6195           gcc_assert (operands[2] == constm1_rtx);
6196           return "dec{l}\t%0";
6197         }
6198
6199     default:
6200       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6201
6202       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6203          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6204       if (CONST_INT_P (operands[2])
6205           && (INTVAL (operands[2]) == 128
6206               || (INTVAL (operands[2]) < 0
6207                   && INTVAL (operands[2]) != -128)))
6208         {
6209           operands[2] = GEN_INT (-INTVAL (operands[2]));
6210           return "sub{l}\t{%2, %0|%0, %2}";
6211         }
6212       return "add{l}\t{%2, %0|%0, %2}";
6213     }
6214 }
6215   [(set (attr "type")
6216      (cond [(eq_attr "alternative" "2")
6217               (const_string "lea")
6218             ; Current assemblers are broken and do not allow @GOTOFF in
6219             ; ought but a memory context.
6220             (match_operand:SI 2 "pic_symbolic_operand" "")
6221               (const_string "lea")
6222             (match_operand:SI 2 "incdec_operand" "")
6223               (const_string "incdec")
6224            ]
6225            (const_string "alu")))
6226    (set_attr "mode" "SI")])
6227
6228 ;; Convert lea to the lea pattern to avoid flags dependency.
6229 (define_split
6230   [(set (match_operand 0 "register_operand" "")
6231         (plus (match_operand 1 "register_operand" "")
6232               (match_operand 2 "nonmemory_operand" "")))
6233    (clobber (reg:CC FLAGS_REG))]
6234   "reload_completed
6235    && true_regnum (operands[0]) != true_regnum (operands[1])"
6236   [(const_int 0)]
6237 {
6238   rtx pat;
6239   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6240      may confuse gen_lowpart.  */
6241   if (GET_MODE (operands[0]) != Pmode)
6242     {
6243       operands[1] = gen_lowpart (Pmode, operands[1]);
6244       operands[2] = gen_lowpart (Pmode, operands[2]);
6245     }
6246   operands[0] = gen_lowpart (SImode, operands[0]);
6247   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6248   if (Pmode != SImode)
6249     pat = gen_rtx_SUBREG (SImode, pat, 0);
6250   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6251   DONE;
6252 })
6253
6254 ;; It may seem that nonimmediate operand is proper one for operand 1.
6255 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6256 ;; we take care in ix86_binary_operator_ok to not allow two memory
6257 ;; operands so proper swapping will be done in reload.  This allow
6258 ;; patterns constructed from addsi_1 to match.
6259 (define_insn "addsi_1_zext"
6260   [(set (match_operand:DI 0 "register_operand" "=r,r")
6261         (zero_extend:DI
6262           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6263                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
6264    (clobber (reg:CC FLAGS_REG))]
6265   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6266 {
6267   switch (get_attr_type (insn))
6268     {
6269     case TYPE_LEA:
6270       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6271       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6272
6273     case TYPE_INCDEC:
6274       if (operands[2] == const1_rtx)
6275         return "inc{l}\t%k0";
6276       else
6277         {
6278           gcc_assert (operands[2] == constm1_rtx);
6279           return "dec{l}\t%k0";
6280         }
6281
6282     default:
6283       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6284          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6285       if (CONST_INT_P (operands[2])
6286           && (INTVAL (operands[2]) == 128
6287               || (INTVAL (operands[2]) < 0
6288                   && INTVAL (operands[2]) != -128)))
6289         {
6290           operands[2] = GEN_INT (-INTVAL (operands[2]));
6291           return "sub{l}\t{%2, %k0|%k0, %2}";
6292         }
6293       return "add{l}\t{%2, %k0|%k0, %2}";
6294     }
6295 }
6296   [(set (attr "type")
6297      (cond [(eq_attr "alternative" "1")
6298               (const_string "lea")
6299             ; Current assemblers are broken and do not allow @GOTOFF in
6300             ; ought but a memory context.
6301             (match_operand:SI 2 "pic_symbolic_operand" "")
6302               (const_string "lea")
6303             (match_operand:SI 2 "incdec_operand" "")
6304               (const_string "incdec")
6305            ]
6306            (const_string "alu")))
6307    (set_attr "mode" "SI")])
6308
6309 ;; Convert lea to the lea pattern to avoid flags dependency.
6310 (define_split
6311   [(set (match_operand:DI 0 "register_operand" "")
6312         (zero_extend:DI
6313           (plus:SI (match_operand:SI 1 "register_operand" "")
6314                    (match_operand:SI 2 "nonmemory_operand" ""))))
6315    (clobber (reg:CC FLAGS_REG))]
6316   "TARGET_64BIT && reload_completed
6317    && true_regnum (operands[0]) != true_regnum (operands[1])"
6318   [(set (match_dup 0)
6319         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6320 {
6321   operands[1] = gen_lowpart (Pmode, operands[1]);
6322   operands[2] = gen_lowpart (Pmode, operands[2]);
6323 })
6324
6325 (define_insn "*addsi_2"
6326   [(set (reg FLAGS_REG)
6327         (compare
6328           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6329                    (match_operand:SI 2 "general_operand" "rmni,rni"))
6330           (const_int 0)))
6331    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6332         (plus:SI (match_dup 1) (match_dup 2)))]
6333   "ix86_match_ccmode (insn, CCGOCmode)
6334    && ix86_binary_operator_ok (PLUS, SImode, operands)
6335    /* Current assemblers are broken and do not allow @GOTOFF in
6336       ought but a memory context.  */
6337    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6338 {
6339   switch (get_attr_type (insn))
6340     {
6341     case TYPE_INCDEC:
6342       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6343       if (operands[2] == const1_rtx)
6344         return "inc{l}\t%0";
6345       else
6346         {
6347           gcc_assert (operands[2] == constm1_rtx);
6348           return "dec{l}\t%0";
6349         }
6350
6351     default:
6352       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6353       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6354          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6355       if (CONST_INT_P (operands[2])
6356           && (INTVAL (operands[2]) == 128
6357               || (INTVAL (operands[2]) < 0
6358                   && INTVAL (operands[2]) != -128)))
6359         {
6360           operands[2] = GEN_INT (-INTVAL (operands[2]));
6361           return "sub{l}\t{%2, %0|%0, %2}";
6362         }
6363       return "add{l}\t{%2, %0|%0, %2}";
6364     }
6365 }
6366   [(set (attr "type")
6367      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6368         (const_string "incdec")
6369         (const_string "alu")))
6370    (set_attr "mode" "SI")])
6371
6372 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6373 (define_insn "*addsi_2_zext"
6374   [(set (reg FLAGS_REG)
6375         (compare
6376           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6377                    (match_operand:SI 2 "general_operand" "rmni"))
6378           (const_int 0)))
6379    (set (match_operand:DI 0 "register_operand" "=r")
6380         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6381   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6382    && ix86_binary_operator_ok (PLUS, SImode, operands)
6383    /* Current assemblers are broken and do not allow @GOTOFF in
6384       ought but a memory context.  */
6385    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6386 {
6387   switch (get_attr_type (insn))
6388     {
6389     case TYPE_INCDEC:
6390       if (operands[2] == const1_rtx)
6391         return "inc{l}\t%k0";
6392       else
6393         {
6394           gcc_assert (operands[2] == constm1_rtx);
6395           return "dec{l}\t%k0";
6396         }
6397
6398     default:
6399       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6400          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6401       if (CONST_INT_P (operands[2])
6402           && (INTVAL (operands[2]) == 128
6403               || (INTVAL (operands[2]) < 0
6404                   && INTVAL (operands[2]) != -128)))
6405         {
6406           operands[2] = GEN_INT (-INTVAL (operands[2]));
6407           return "sub{l}\t{%2, %k0|%k0, %2}";
6408         }
6409       return "add{l}\t{%2, %k0|%k0, %2}";
6410     }
6411 }
6412   [(set (attr "type")
6413      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6414         (const_string "incdec")
6415         (const_string "alu")))
6416    (set_attr "mode" "SI")])
6417
6418 (define_insn "*addsi_3"
6419   [(set (reg FLAGS_REG)
6420         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6421                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6422    (clobber (match_scratch:SI 0 "=r"))]
6423   "ix86_match_ccmode (insn, CCZmode)
6424    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6425    /* Current assemblers are broken and do not allow @GOTOFF in
6426       ought but a memory context.  */
6427    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6428 {
6429   switch (get_attr_type (insn))
6430     {
6431     case TYPE_INCDEC:
6432       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6433       if (operands[2] == const1_rtx)
6434         return "inc{l}\t%0";
6435       else
6436         {
6437           gcc_assert (operands[2] == constm1_rtx);
6438           return "dec{l}\t%0";
6439         }
6440
6441     default:
6442       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6443       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6444          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6445       if (CONST_INT_P (operands[2])
6446           && (INTVAL (operands[2]) == 128
6447               || (INTVAL (operands[2]) < 0
6448                   && INTVAL (operands[2]) != -128)))
6449         {
6450           operands[2] = GEN_INT (-INTVAL (operands[2]));
6451           return "sub{l}\t{%2, %0|%0, %2}";
6452         }
6453       return "add{l}\t{%2, %0|%0, %2}";
6454     }
6455 }
6456   [(set (attr "type")
6457      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6458         (const_string "incdec")
6459         (const_string "alu")))
6460    (set_attr "mode" "SI")])
6461
6462 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6463 (define_insn "*addsi_3_zext"
6464   [(set (reg FLAGS_REG)
6465         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6466                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6467    (set (match_operand:DI 0 "register_operand" "=r")
6468         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6469   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6470    && ix86_binary_operator_ok (PLUS, SImode, operands)
6471    /* Current assemblers are broken and do not allow @GOTOFF in
6472       ought but a memory context.  */
6473    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6474 {
6475   switch (get_attr_type (insn))
6476     {
6477     case TYPE_INCDEC:
6478       if (operands[2] == const1_rtx)
6479         return "inc{l}\t%k0";
6480       else
6481         {
6482           gcc_assert (operands[2] == constm1_rtx);
6483           return "dec{l}\t%k0";
6484         }
6485
6486     default:
6487       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6488          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6489       if (CONST_INT_P (operands[2])
6490           && (INTVAL (operands[2]) == 128
6491               || (INTVAL (operands[2]) < 0
6492                   && INTVAL (operands[2]) != -128)))
6493         {
6494           operands[2] = GEN_INT (-INTVAL (operands[2]));
6495           return "sub{l}\t{%2, %k0|%k0, %2}";
6496         }
6497       return "add{l}\t{%2, %k0|%k0, %2}";
6498     }
6499 }
6500   [(set (attr "type")
6501      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6502         (const_string "incdec")
6503         (const_string "alu")))
6504    (set_attr "mode" "SI")])
6505
6506 ; For comparisons against 1, -1 and 128, we may generate better code
6507 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6508 ; is matched then.  We can't accept general immediate, because for
6509 ; case of overflows,  the result is messed up.
6510 ; This pattern also don't hold of 0x80000000, since the value overflows
6511 ; when negated.
6512 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6513 ; only for comparisons not depending on it.
6514 (define_insn "*addsi_4"
6515   [(set (reg FLAGS_REG)
6516         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6517                  (match_operand:SI 2 "const_int_operand" "n")))
6518    (clobber (match_scratch:SI 0 "=rm"))]
6519   "ix86_match_ccmode (insn, CCGCmode)
6520    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6521 {
6522   switch (get_attr_type (insn))
6523     {
6524     case TYPE_INCDEC:
6525       if (operands[2] == constm1_rtx)
6526         return "inc{l}\t%0";
6527       else
6528         {
6529           gcc_assert (operands[2] == const1_rtx);
6530           return "dec{l}\t%0";
6531         }
6532
6533     default:
6534       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6535       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6536          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6537       if ((INTVAL (operands[2]) == -128
6538            || (INTVAL (operands[2]) > 0
6539                && INTVAL (operands[2]) != 128)))
6540         return "sub{l}\t{%2, %0|%0, %2}";
6541       operands[2] = GEN_INT (-INTVAL (operands[2]));
6542       return "add{l}\t{%2, %0|%0, %2}";
6543     }
6544 }
6545   [(set (attr "type")
6546      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6547         (const_string "incdec")
6548         (const_string "alu")))
6549    (set_attr "mode" "SI")])
6550
6551 (define_insn "*addsi_5"
6552   [(set (reg FLAGS_REG)
6553         (compare
6554           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6555                    (match_operand:SI 2 "general_operand" "rmni"))
6556           (const_int 0)))
6557    (clobber (match_scratch:SI 0 "=r"))]
6558   "ix86_match_ccmode (insn, CCGOCmode)
6559    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6560    /* Current assemblers are broken and do not allow @GOTOFF in
6561       ought but a memory context.  */
6562    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6563 {
6564   switch (get_attr_type (insn))
6565     {
6566     case TYPE_INCDEC:
6567       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6568       if (operands[2] == const1_rtx)
6569         return "inc{l}\t%0";
6570       else
6571         {
6572           gcc_assert (operands[2] == constm1_rtx);
6573           return "dec{l}\t%0";
6574         }
6575
6576     default:
6577       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6578       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6579          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6580       if (CONST_INT_P (operands[2])
6581           && (INTVAL (operands[2]) == 128
6582               || (INTVAL (operands[2]) < 0
6583                   && INTVAL (operands[2]) != -128)))
6584         {
6585           operands[2] = GEN_INT (-INTVAL (operands[2]));
6586           return "sub{l}\t{%2, %0|%0, %2}";
6587         }
6588       return "add{l}\t{%2, %0|%0, %2}";
6589     }
6590 }
6591   [(set (attr "type")
6592      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6593         (const_string "incdec")
6594         (const_string "alu")))
6595    (set_attr "mode" "SI")])
6596
6597 (define_expand "addhi3"
6598   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6599                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6600                             (match_operand:HI 2 "general_operand" "")))
6601               (clobber (reg:CC FLAGS_REG))])]
6602   "TARGET_HIMODE_MATH"
6603   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6604
6605 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6606 ;; type optimizations enabled by define-splits.  This is not important
6607 ;; for PII, and in fact harmful because of partial register stalls.
6608
6609 (define_insn "*addhi_1_lea"
6610   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6611         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6612                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6613    (clobber (reg:CC FLAGS_REG))]
6614   "!TARGET_PARTIAL_REG_STALL
6615    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6616 {
6617   switch (get_attr_type (insn))
6618     {
6619     case TYPE_LEA:
6620       return "#";
6621     case TYPE_INCDEC:
6622       if (operands[2] == const1_rtx)
6623         return "inc{w}\t%0";
6624       else
6625         {
6626           gcc_assert (operands[2] == constm1_rtx);
6627           return "dec{w}\t%0";
6628         }
6629
6630     default:
6631       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6632          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6633       if (CONST_INT_P (operands[2])
6634           && (INTVAL (operands[2]) == 128
6635               || (INTVAL (operands[2]) < 0
6636                   && INTVAL (operands[2]) != -128)))
6637         {
6638           operands[2] = GEN_INT (-INTVAL (operands[2]));
6639           return "sub{w}\t{%2, %0|%0, %2}";
6640         }
6641       return "add{w}\t{%2, %0|%0, %2}";
6642     }
6643 }
6644   [(set (attr "type")
6645      (if_then_else (eq_attr "alternative" "2")
6646         (const_string "lea")
6647         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6648            (const_string "incdec")
6649            (const_string "alu"))))
6650    (set_attr "mode" "HI,HI,SI")])
6651
6652 (define_insn "*addhi_1"
6653   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6654         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6655                  (match_operand:HI 2 "general_operand" "ri,rm")))
6656    (clobber (reg:CC FLAGS_REG))]
6657   "TARGET_PARTIAL_REG_STALL
6658    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6659 {
6660   switch (get_attr_type (insn))
6661     {
6662     case TYPE_INCDEC:
6663       if (operands[2] == const1_rtx)
6664         return "inc{w}\t%0";
6665       else
6666         {
6667           gcc_assert (operands[2] == constm1_rtx);
6668           return "dec{w}\t%0";
6669         }
6670
6671     default:
6672       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6673          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6674       if (CONST_INT_P (operands[2])
6675           && (INTVAL (operands[2]) == 128
6676               || (INTVAL (operands[2]) < 0
6677                   && INTVAL (operands[2]) != -128)))
6678         {
6679           operands[2] = GEN_INT (-INTVAL (operands[2]));
6680           return "sub{w}\t{%2, %0|%0, %2}";
6681         }
6682       return "add{w}\t{%2, %0|%0, %2}";
6683     }
6684 }
6685   [(set (attr "type")
6686      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6687         (const_string "incdec")
6688         (const_string "alu")))
6689    (set_attr "mode" "HI")])
6690
6691 (define_insn "*addhi_2"
6692   [(set (reg FLAGS_REG)
6693         (compare
6694           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6695                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6696           (const_int 0)))
6697    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6698         (plus:HI (match_dup 1) (match_dup 2)))]
6699   "ix86_match_ccmode (insn, CCGOCmode)
6700    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6701 {
6702   switch (get_attr_type (insn))
6703     {
6704     case TYPE_INCDEC:
6705       if (operands[2] == const1_rtx)
6706         return "inc{w}\t%0";
6707       else
6708         {
6709           gcc_assert (operands[2] == constm1_rtx);
6710           return "dec{w}\t%0";
6711         }
6712
6713     default:
6714       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6715          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6716       if (CONST_INT_P (operands[2])
6717           && (INTVAL (operands[2]) == 128
6718               || (INTVAL (operands[2]) < 0
6719                   && INTVAL (operands[2]) != -128)))
6720         {
6721           operands[2] = GEN_INT (-INTVAL (operands[2]));
6722           return "sub{w}\t{%2, %0|%0, %2}";
6723         }
6724       return "add{w}\t{%2, %0|%0, %2}";
6725     }
6726 }
6727   [(set (attr "type")
6728      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6729         (const_string "incdec")
6730         (const_string "alu")))
6731    (set_attr "mode" "HI")])
6732
6733 (define_insn "*addhi_3"
6734   [(set (reg FLAGS_REG)
6735         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6736                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6737    (clobber (match_scratch:HI 0 "=r"))]
6738   "ix86_match_ccmode (insn, CCZmode)
6739    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6740 {
6741   switch (get_attr_type (insn))
6742     {
6743     case TYPE_INCDEC:
6744       if (operands[2] == const1_rtx)
6745         return "inc{w}\t%0";
6746       else
6747         {
6748           gcc_assert (operands[2] == constm1_rtx);
6749           return "dec{w}\t%0";
6750         }
6751
6752     default:
6753       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6754          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6755       if (CONST_INT_P (operands[2])
6756           && (INTVAL (operands[2]) == 128
6757               || (INTVAL (operands[2]) < 0
6758                   && INTVAL (operands[2]) != -128)))
6759         {
6760           operands[2] = GEN_INT (-INTVAL (operands[2]));
6761           return "sub{w}\t{%2, %0|%0, %2}";
6762         }
6763       return "add{w}\t{%2, %0|%0, %2}";
6764     }
6765 }
6766   [(set (attr "type")
6767      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6768         (const_string "incdec")
6769         (const_string "alu")))
6770    (set_attr "mode" "HI")])
6771
6772 ; See comments above addsi_4 for details.
6773 (define_insn "*addhi_4"
6774   [(set (reg FLAGS_REG)
6775         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6776                  (match_operand:HI 2 "const_int_operand" "n")))
6777    (clobber (match_scratch:HI 0 "=rm"))]
6778   "ix86_match_ccmode (insn, CCGCmode)
6779    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6780 {
6781   switch (get_attr_type (insn))
6782     {
6783     case TYPE_INCDEC:
6784       if (operands[2] == constm1_rtx)
6785         return "inc{w}\t%0";
6786       else
6787         {
6788           gcc_assert (operands[2] == const1_rtx);
6789           return "dec{w}\t%0";
6790         }
6791
6792     default:
6793       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6794       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6795          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6796       if ((INTVAL (operands[2]) == -128
6797            || (INTVAL (operands[2]) > 0
6798                && INTVAL (operands[2]) != 128)))
6799         return "sub{w}\t{%2, %0|%0, %2}";
6800       operands[2] = GEN_INT (-INTVAL (operands[2]));
6801       return "add{w}\t{%2, %0|%0, %2}";
6802     }
6803 }
6804   [(set (attr "type")
6805      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6806         (const_string "incdec")
6807         (const_string "alu")))
6808    (set_attr "mode" "SI")])
6809
6810
6811 (define_insn "*addhi_5"
6812   [(set (reg FLAGS_REG)
6813         (compare
6814           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6815                    (match_operand:HI 2 "general_operand" "rmni"))
6816           (const_int 0)))
6817    (clobber (match_scratch:HI 0 "=r"))]
6818   "ix86_match_ccmode (insn, CCGOCmode)
6819    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6820 {
6821   switch (get_attr_type (insn))
6822     {
6823     case TYPE_INCDEC:
6824       if (operands[2] == const1_rtx)
6825         return "inc{w}\t%0";
6826       else
6827         {
6828           gcc_assert (operands[2] == constm1_rtx);
6829           return "dec{w}\t%0";
6830         }
6831
6832     default:
6833       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6834          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6835       if (CONST_INT_P (operands[2])
6836           && (INTVAL (operands[2]) == 128
6837               || (INTVAL (operands[2]) < 0
6838                   && INTVAL (operands[2]) != -128)))
6839         {
6840           operands[2] = GEN_INT (-INTVAL (operands[2]));
6841           return "sub{w}\t{%2, %0|%0, %2}";
6842         }
6843       return "add{w}\t{%2, %0|%0, %2}";
6844     }
6845 }
6846   [(set (attr "type")
6847      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6848         (const_string "incdec")
6849         (const_string "alu")))
6850    (set_attr "mode" "HI")])
6851
6852 (define_expand "addqi3"
6853   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6854                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6855                             (match_operand:QI 2 "general_operand" "")))
6856               (clobber (reg:CC FLAGS_REG))])]
6857   "TARGET_QIMODE_MATH"
6858   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6859
6860 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6861 (define_insn "*addqi_1_lea"
6862   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6863         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6864                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6865    (clobber (reg:CC FLAGS_REG))]
6866   "!TARGET_PARTIAL_REG_STALL
6867    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6868 {
6869   int widen = (which_alternative == 2);
6870   switch (get_attr_type (insn))
6871     {
6872     case TYPE_LEA:
6873       return "#";
6874     case TYPE_INCDEC:
6875       if (operands[2] == const1_rtx)
6876         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6877       else
6878         {
6879           gcc_assert (operands[2] == constm1_rtx);
6880           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6881         }
6882
6883     default:
6884       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6885          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6886       if (CONST_INT_P (operands[2])
6887           && (INTVAL (operands[2]) == 128
6888               || (INTVAL (operands[2]) < 0
6889                   && INTVAL (operands[2]) != -128)))
6890         {
6891           operands[2] = GEN_INT (-INTVAL (operands[2]));
6892           if (widen)
6893             return "sub{l}\t{%2, %k0|%k0, %2}";
6894           else
6895             return "sub{b}\t{%2, %0|%0, %2}";
6896         }
6897       if (widen)
6898         return "add{l}\t{%k2, %k0|%k0, %k2}";
6899       else
6900         return "add{b}\t{%2, %0|%0, %2}";
6901     }
6902 }
6903   [(set (attr "type")
6904      (if_then_else (eq_attr "alternative" "3")
6905         (const_string "lea")
6906         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6907            (const_string "incdec")
6908            (const_string "alu"))))
6909    (set_attr "mode" "QI,QI,SI,SI")])
6910
6911 (define_insn "*addqi_1"
6912   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6913         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6914                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6915    (clobber (reg:CC FLAGS_REG))]
6916   "TARGET_PARTIAL_REG_STALL
6917    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6918 {
6919   int widen = (which_alternative == 2);
6920   switch (get_attr_type (insn))
6921     {
6922     case TYPE_INCDEC:
6923       if (operands[2] == const1_rtx)
6924         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6925       else
6926         {
6927           gcc_assert (operands[2] == constm1_rtx);
6928           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6929         }
6930
6931     default:
6932       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6933          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6934       if (CONST_INT_P (operands[2])
6935           && (INTVAL (operands[2]) == 128
6936               || (INTVAL (operands[2]) < 0
6937                   && INTVAL (operands[2]) != -128)))
6938         {
6939           operands[2] = GEN_INT (-INTVAL (operands[2]));
6940           if (widen)
6941             return "sub{l}\t{%2, %k0|%k0, %2}";
6942           else
6943             return "sub{b}\t{%2, %0|%0, %2}";
6944         }
6945       if (widen)
6946         return "add{l}\t{%k2, %k0|%k0, %k2}";
6947       else
6948         return "add{b}\t{%2, %0|%0, %2}";
6949     }
6950 }
6951   [(set (attr "type")
6952      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6953         (const_string "incdec")
6954         (const_string "alu")))
6955    (set_attr "mode" "QI,QI,SI")])
6956
6957 (define_insn "*addqi_1_slp"
6958   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6959         (plus:QI (match_dup 0)
6960                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6961    (clobber (reg:CC FLAGS_REG))]
6962   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6963    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6964 {
6965   switch (get_attr_type (insn))
6966     {
6967     case TYPE_INCDEC:
6968       if (operands[1] == const1_rtx)
6969         return "inc{b}\t%0";
6970       else
6971         {
6972           gcc_assert (operands[1] == constm1_rtx);
6973           return "dec{b}\t%0";
6974         }
6975
6976     default:
6977       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6978       if (CONST_INT_P (operands[1])
6979           && INTVAL (operands[1]) < 0)
6980         {
6981           operands[1] = GEN_INT (-INTVAL (operands[1]));
6982           return "sub{b}\t{%1, %0|%0, %1}";
6983         }
6984       return "add{b}\t{%1, %0|%0, %1}";
6985     }
6986 }
6987   [(set (attr "type")
6988      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6989         (const_string "incdec")
6990         (const_string "alu1")))
6991    (set (attr "memory")
6992      (if_then_else (match_operand 1 "memory_operand" "")
6993         (const_string "load")
6994         (const_string "none")))
6995    (set_attr "mode" "QI")])
6996
6997 (define_insn "*addqi_2"
6998   [(set (reg FLAGS_REG)
6999         (compare
7000           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7001                    (match_operand:QI 2 "general_operand" "qmni,qni"))
7002           (const_int 0)))
7003    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7004         (plus:QI (match_dup 1) (match_dup 2)))]
7005   "ix86_match_ccmode (insn, CCGOCmode)
7006    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7007 {
7008   switch (get_attr_type (insn))
7009     {
7010     case TYPE_INCDEC:
7011       if (operands[2] == const1_rtx)
7012         return "inc{b}\t%0";
7013       else
7014         {
7015           gcc_assert (operands[2] == constm1_rtx
7016                       || (CONST_INT_P (operands[2])
7017                           && INTVAL (operands[2]) == 255));
7018           return "dec{b}\t%0";
7019         }
7020
7021     default:
7022       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7023       if (CONST_INT_P (operands[2])
7024           && INTVAL (operands[2]) < 0)
7025         {
7026           operands[2] = GEN_INT (-INTVAL (operands[2]));
7027           return "sub{b}\t{%2, %0|%0, %2}";
7028         }
7029       return "add{b}\t{%2, %0|%0, %2}";
7030     }
7031 }
7032   [(set (attr "type")
7033      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7034         (const_string "incdec")
7035         (const_string "alu")))
7036    (set_attr "mode" "QI")])
7037
7038 (define_insn "*addqi_3"
7039   [(set (reg FLAGS_REG)
7040         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
7041                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
7042    (clobber (match_scratch:QI 0 "=q"))]
7043   "ix86_match_ccmode (insn, CCZmode)
7044    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7045 {
7046   switch (get_attr_type (insn))
7047     {
7048     case TYPE_INCDEC:
7049       if (operands[2] == const1_rtx)
7050         return "inc{b}\t%0";
7051       else
7052         {
7053           gcc_assert (operands[2] == constm1_rtx
7054                       || (CONST_INT_P (operands[2])
7055                           && INTVAL (operands[2]) == 255));
7056           return "dec{b}\t%0";
7057         }
7058
7059     default:
7060       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7061       if (CONST_INT_P (operands[2])
7062           && INTVAL (operands[2]) < 0)
7063         {
7064           operands[2] = GEN_INT (-INTVAL (operands[2]));
7065           return "sub{b}\t{%2, %0|%0, %2}";
7066         }
7067       return "add{b}\t{%2, %0|%0, %2}";
7068     }
7069 }
7070   [(set (attr "type")
7071      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7072         (const_string "incdec")
7073         (const_string "alu")))
7074    (set_attr "mode" "QI")])
7075
7076 ; See comments above addsi_4 for details.
7077 (define_insn "*addqi_4"
7078   [(set (reg FLAGS_REG)
7079         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7080                  (match_operand:QI 2 "const_int_operand" "n")))
7081    (clobber (match_scratch:QI 0 "=qm"))]
7082   "ix86_match_ccmode (insn, CCGCmode)
7083    && (INTVAL (operands[2]) & 0xff) != 0x80"
7084 {
7085   switch (get_attr_type (insn))
7086     {
7087     case TYPE_INCDEC:
7088       if (operands[2] == constm1_rtx
7089           || (CONST_INT_P (operands[2])
7090               && INTVAL (operands[2]) == 255))
7091         return "inc{b}\t%0";
7092       else
7093         {
7094           gcc_assert (operands[2] == const1_rtx);
7095           return "dec{b}\t%0";
7096         }
7097
7098     default:
7099       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7100       if (INTVAL (operands[2]) < 0)
7101         {
7102           operands[2] = GEN_INT (-INTVAL (operands[2]));
7103           return "add{b}\t{%2, %0|%0, %2}";
7104         }
7105       return "sub{b}\t{%2, %0|%0, %2}";
7106     }
7107 }
7108   [(set (attr "type")
7109      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7110         (const_string "incdec")
7111         (const_string "alu")))
7112    (set_attr "mode" "QI")])
7113
7114
7115 (define_insn "*addqi_5"
7116   [(set (reg FLAGS_REG)
7117         (compare
7118           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7119                    (match_operand:QI 2 "general_operand" "qmni"))
7120           (const_int 0)))
7121    (clobber (match_scratch:QI 0 "=q"))]
7122   "ix86_match_ccmode (insn, CCGOCmode)
7123    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7124 {
7125   switch (get_attr_type (insn))
7126     {
7127     case TYPE_INCDEC:
7128       if (operands[2] == const1_rtx)
7129         return "inc{b}\t%0";
7130       else
7131         {
7132           gcc_assert (operands[2] == constm1_rtx
7133                       || (CONST_INT_P (operands[2])
7134                           && INTVAL (operands[2]) == 255));
7135           return "dec{b}\t%0";
7136         }
7137
7138     default:
7139       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7140       if (CONST_INT_P (operands[2])
7141           && INTVAL (operands[2]) < 0)
7142         {
7143           operands[2] = GEN_INT (-INTVAL (operands[2]));
7144           return "sub{b}\t{%2, %0|%0, %2}";
7145         }
7146       return "add{b}\t{%2, %0|%0, %2}";
7147     }
7148 }
7149   [(set (attr "type")
7150      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7151         (const_string "incdec")
7152         (const_string "alu")))
7153    (set_attr "mode" "QI")])
7154
7155
7156 (define_insn "addqi_ext_1"
7157   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7158                          (const_int 8)
7159                          (const_int 8))
7160         (plus:SI
7161           (zero_extract:SI
7162             (match_operand 1 "ext_register_operand" "0")
7163             (const_int 8)
7164             (const_int 8))
7165           (match_operand:QI 2 "general_operand" "Qmn")))
7166    (clobber (reg:CC FLAGS_REG))]
7167   "!TARGET_64BIT"
7168 {
7169   switch (get_attr_type (insn))
7170     {
7171     case TYPE_INCDEC:
7172       if (operands[2] == const1_rtx)
7173         return "inc{b}\t%h0";
7174       else
7175         {
7176           gcc_assert (operands[2] == constm1_rtx
7177                       || (CONST_INT_P (operands[2])
7178                           && INTVAL (operands[2]) == 255));
7179           return "dec{b}\t%h0";
7180         }
7181
7182     default:
7183       return "add{b}\t{%2, %h0|%h0, %2}";
7184     }
7185 }
7186   [(set (attr "type")
7187      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7188         (const_string "incdec")
7189         (const_string "alu")))
7190    (set_attr "mode" "QI")])
7191
7192 (define_insn "*addqi_ext_1_rex64"
7193   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7194                          (const_int 8)
7195                          (const_int 8))
7196         (plus:SI
7197           (zero_extract:SI
7198             (match_operand 1 "ext_register_operand" "0")
7199             (const_int 8)
7200             (const_int 8))
7201           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7202    (clobber (reg:CC FLAGS_REG))]
7203   "TARGET_64BIT"
7204 {
7205   switch (get_attr_type (insn))
7206     {
7207     case TYPE_INCDEC:
7208       if (operands[2] == const1_rtx)
7209         return "inc{b}\t%h0";
7210       else
7211         {
7212           gcc_assert (operands[2] == constm1_rtx
7213                       || (CONST_INT_P (operands[2])
7214                           && INTVAL (operands[2]) == 255));
7215           return "dec{b}\t%h0";
7216         }
7217
7218     default:
7219       return "add{b}\t{%2, %h0|%h0, %2}";
7220     }
7221 }
7222   [(set (attr "type")
7223      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7224         (const_string "incdec")
7225         (const_string "alu")))
7226    (set_attr "mode" "QI")])
7227
7228 (define_insn "*addqi_ext_2"
7229   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7230                          (const_int 8)
7231                          (const_int 8))
7232         (plus:SI
7233           (zero_extract:SI
7234             (match_operand 1 "ext_register_operand" "%0")
7235             (const_int 8)
7236             (const_int 8))
7237           (zero_extract:SI
7238             (match_operand 2 "ext_register_operand" "Q")
7239             (const_int 8)
7240             (const_int 8))))
7241    (clobber (reg:CC FLAGS_REG))]
7242   ""
7243   "add{b}\t{%h2, %h0|%h0, %h2}"
7244   [(set_attr "type" "alu")
7245    (set_attr "mode" "QI")])
7246
7247 ;; The patterns that match these are at the end of this file.
7248
7249 (define_expand "addxf3"
7250   [(set (match_operand:XF 0 "register_operand" "")
7251         (plus:XF (match_operand:XF 1 "register_operand" "")
7252                  (match_operand:XF 2 "register_operand" "")))]
7253   "TARGET_80387"
7254   "")
7255
7256 (define_expand "add<mode>3"
7257   [(set (match_operand:MODEF 0 "register_operand" "")
7258         (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7259                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7260   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7261   "")
7262 \f
7263 ;; Subtract instructions
7264
7265 ;; %%% splits for subditi3
7266
7267 (define_expand "subti3"
7268   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
7269                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7270                              (match_operand:TI 2 "x86_64_general_operand" "")))
7271               (clobber (reg:CC FLAGS_REG))])]
7272   "TARGET_64BIT"
7273   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7274
7275 (define_insn "*subti3_1"
7276   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7277         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7278                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7279    (clobber (reg:CC FLAGS_REG))]
7280   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7281   "#")
7282
7283 (define_split
7284   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7285         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7286                   (match_operand:TI 2 "x86_64_general_operand" "")))
7287    (clobber (reg:CC FLAGS_REG))]
7288   "TARGET_64BIT && reload_completed"
7289   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7290               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7291    (parallel [(set (match_dup 3)
7292                    (minus:DI (match_dup 4)
7293                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7294                                       (match_dup 5))))
7295               (clobber (reg:CC FLAGS_REG))])]
7296   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
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], 3, &operands[0], &operands[3]);")
7330
7331 (define_insn "subdi3_carry_rex64"
7332   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7333           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7334             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7335                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7336    (clobber (reg:CC FLAGS_REG))]
7337   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7338   "sbb{q}\t{%2, %0|%0, %2}"
7339   [(set_attr "type" "alu")
7340    (set_attr "pent_pair" "pu")
7341    (set_attr "mode" "DI")])
7342
7343 (define_insn "*subdi_1_rex64"
7344   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7345         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7346                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7347    (clobber (reg:CC FLAGS_REG))]
7348   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7349   "sub{q}\t{%2, %0|%0, %2}"
7350   [(set_attr "type" "alu")
7351    (set_attr "mode" "DI")])
7352
7353 (define_insn "*subdi_2_rex64"
7354   [(set (reg FLAGS_REG)
7355         (compare
7356           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7357                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7358           (const_int 0)))
7359    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7360         (minus:DI (match_dup 1) (match_dup 2)))]
7361   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7362    && ix86_binary_operator_ok (MINUS, DImode, operands)"
7363   "sub{q}\t{%2, %0|%0, %2}"
7364   [(set_attr "type" "alu")
7365    (set_attr "mode" "DI")])
7366
7367 (define_insn "*subdi_3_rex63"
7368   [(set (reg FLAGS_REG)
7369         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7370                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7371    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7372         (minus:DI (match_dup 1) (match_dup 2)))]
7373   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7374    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7375   "sub{q}\t{%2, %0|%0, %2}"
7376   [(set_attr "type" "alu")
7377    (set_attr "mode" "DI")])
7378
7379 (define_insn "subqi3_carry"
7380   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7381           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7382             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7383                (match_operand:QI 2 "general_operand" "qi,qm"))))
7384    (clobber (reg:CC FLAGS_REG))]
7385   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7386   "sbb{b}\t{%2, %0|%0, %2}"
7387   [(set_attr "type" "alu")
7388    (set_attr "pent_pair" "pu")
7389    (set_attr "mode" "QI")])
7390
7391 (define_insn "subhi3_carry"
7392   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7393           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7394             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7395                (match_operand:HI 2 "general_operand" "ri,rm"))))
7396    (clobber (reg:CC FLAGS_REG))]
7397   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7398   "sbb{w}\t{%2, %0|%0, %2}"
7399   [(set_attr "type" "alu")
7400    (set_attr "pent_pair" "pu")
7401    (set_attr "mode" "HI")])
7402
7403 (define_insn "subsi3_carry"
7404   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7405           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7406             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7407                (match_operand:SI 2 "general_operand" "ri,rm"))))
7408    (clobber (reg:CC FLAGS_REG))]
7409   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7410   "sbb{l}\t{%2, %0|%0, %2}"
7411   [(set_attr "type" "alu")
7412    (set_attr "pent_pair" "pu")
7413    (set_attr "mode" "SI")])
7414
7415 (define_insn "subsi3_carry_zext"
7416   [(set (match_operand:DI 0 "register_operand" "=r")
7417           (zero_extend:DI
7418             (minus:SI (match_operand:SI 1 "register_operand" "0")
7419               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7420                  (match_operand:SI 2 "general_operand" "g")))))
7421    (clobber (reg:CC FLAGS_REG))]
7422   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7423   "sbb{l}\t{%2, %k0|%k0, %2}"
7424   [(set_attr "type" "alu")
7425    (set_attr "pent_pair" "pu")
7426    (set_attr "mode" "SI")])
7427
7428 (define_expand "subsi3"
7429   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7430                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7431                              (match_operand:SI 2 "general_operand" "")))
7432               (clobber (reg:CC FLAGS_REG))])]
7433   ""
7434   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7435
7436 (define_insn "*subsi_1"
7437   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7438         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7439                   (match_operand:SI 2 "general_operand" "ri,rm")))
7440    (clobber (reg:CC FLAGS_REG))]
7441   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7442   "sub{l}\t{%2, %0|%0, %2}"
7443   [(set_attr "type" "alu")
7444    (set_attr "mode" "SI")])
7445
7446 (define_insn "*subsi_1_zext"
7447   [(set (match_operand:DI 0 "register_operand" "=r")
7448         (zero_extend:DI
7449           (minus:SI (match_operand:SI 1 "register_operand" "0")
7450                     (match_operand:SI 2 "general_operand" "g"))))
7451    (clobber (reg:CC FLAGS_REG))]
7452   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7453   "sub{l}\t{%2, %k0|%k0, %2}"
7454   [(set_attr "type" "alu")
7455    (set_attr "mode" "SI")])
7456
7457 (define_insn "*subsi_2"
7458   [(set (reg FLAGS_REG)
7459         (compare
7460           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7461                     (match_operand:SI 2 "general_operand" "ri,rm"))
7462           (const_int 0)))
7463    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7464         (minus:SI (match_dup 1) (match_dup 2)))]
7465   "ix86_match_ccmode (insn, CCGOCmode)
7466    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7467   "sub{l}\t{%2, %0|%0, %2}"
7468   [(set_attr "type" "alu")
7469    (set_attr "mode" "SI")])
7470
7471 (define_insn "*subsi_2_zext"
7472   [(set (reg FLAGS_REG)
7473         (compare
7474           (minus:SI (match_operand:SI 1 "register_operand" "0")
7475                     (match_operand:SI 2 "general_operand" "g"))
7476           (const_int 0)))
7477    (set (match_operand:DI 0 "register_operand" "=r")
7478         (zero_extend:DI
7479           (minus:SI (match_dup 1)
7480                     (match_dup 2))))]
7481   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7482    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7483   "sub{l}\t{%2, %k0|%k0, %2}"
7484   [(set_attr "type" "alu")
7485    (set_attr "mode" "SI")])
7486
7487 (define_insn "*subsi_3"
7488   [(set (reg FLAGS_REG)
7489         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7490                  (match_operand:SI 2 "general_operand" "ri,rm")))
7491    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7492         (minus:SI (match_dup 1) (match_dup 2)))]
7493   "ix86_match_ccmode (insn, CCmode)
7494    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7495   "sub{l}\t{%2, %0|%0, %2}"
7496   [(set_attr "type" "alu")
7497    (set_attr "mode" "SI")])
7498
7499 (define_insn "*subsi_3_zext"
7500   [(set (reg FLAGS_REG)
7501         (compare (match_operand:SI 1 "register_operand" "0")
7502                  (match_operand:SI 2 "general_operand" "g")))
7503    (set (match_operand:DI 0 "register_operand" "=r")
7504         (zero_extend:DI
7505           (minus:SI (match_dup 1)
7506                     (match_dup 2))))]
7507   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7508    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7509   "sub{l}\t{%2, %1|%1, %2}"
7510   [(set_attr "type" "alu")
7511    (set_attr "mode" "DI")])
7512
7513 (define_expand "subhi3"
7514   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7515                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7516                              (match_operand:HI 2 "general_operand" "")))
7517               (clobber (reg:CC FLAGS_REG))])]
7518   "TARGET_HIMODE_MATH"
7519   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7520
7521 (define_insn "*subhi_1"
7522   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7523         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7524                   (match_operand:HI 2 "general_operand" "ri,rm")))
7525    (clobber (reg:CC FLAGS_REG))]
7526   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7527   "sub{w}\t{%2, %0|%0, %2}"
7528   [(set_attr "type" "alu")
7529    (set_attr "mode" "HI")])
7530
7531 (define_insn "*subhi_2"
7532   [(set (reg FLAGS_REG)
7533         (compare
7534           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7535                     (match_operand:HI 2 "general_operand" "ri,rm"))
7536           (const_int 0)))
7537    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7538         (minus:HI (match_dup 1) (match_dup 2)))]
7539   "ix86_match_ccmode (insn, CCGOCmode)
7540    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7541   "sub{w}\t{%2, %0|%0, %2}"
7542   [(set_attr "type" "alu")
7543    (set_attr "mode" "HI")])
7544
7545 (define_insn "*subhi_3"
7546   [(set (reg FLAGS_REG)
7547         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7548                  (match_operand:HI 2 "general_operand" "ri,rm")))
7549    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7550         (minus:HI (match_dup 1) (match_dup 2)))]
7551   "ix86_match_ccmode (insn, CCmode)
7552    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7553   "sub{w}\t{%2, %0|%0, %2}"
7554   [(set_attr "type" "alu")
7555    (set_attr "mode" "HI")])
7556
7557 (define_expand "subqi3"
7558   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7559                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7560                              (match_operand:QI 2 "general_operand" "")))
7561               (clobber (reg:CC FLAGS_REG))])]
7562   "TARGET_QIMODE_MATH"
7563   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7564
7565 (define_insn "*subqi_1"
7566   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7567         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7568                   (match_operand:QI 2 "general_operand" "qn,qmn")))
7569    (clobber (reg:CC FLAGS_REG))]
7570   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7571   "sub{b}\t{%2, %0|%0, %2}"
7572   [(set_attr "type" "alu")
7573    (set_attr "mode" "QI")])
7574
7575 (define_insn "*subqi_1_slp"
7576   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7577         (minus:QI (match_dup 0)
7578                   (match_operand:QI 1 "general_operand" "qn,qmn")))
7579    (clobber (reg:CC FLAGS_REG))]
7580   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7581    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7582   "sub{b}\t{%1, %0|%0, %1}"
7583   [(set_attr "type" "alu1")
7584    (set_attr "mode" "QI")])
7585
7586 (define_insn "*subqi_2"
7587   [(set (reg FLAGS_REG)
7588         (compare
7589           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7590                     (match_operand:QI 2 "general_operand" "qi,qm"))
7591           (const_int 0)))
7592    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7593         (minus:HI (match_dup 1) (match_dup 2)))]
7594   "ix86_match_ccmode (insn, CCGOCmode)
7595    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7596   "sub{b}\t{%2, %0|%0, %2}"
7597   [(set_attr "type" "alu")
7598    (set_attr "mode" "QI")])
7599
7600 (define_insn "*subqi_3"
7601   [(set (reg FLAGS_REG)
7602         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7603                  (match_operand:QI 2 "general_operand" "qi,qm")))
7604    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7605         (minus:HI (match_dup 1) (match_dup 2)))]
7606   "ix86_match_ccmode (insn, CCmode)
7607    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7608   "sub{b}\t{%2, %0|%0, %2}"
7609   [(set_attr "type" "alu")
7610    (set_attr "mode" "QI")])
7611
7612 ;; The patterns that match these are at the end of this file.
7613
7614 (define_expand "subxf3"
7615   [(set (match_operand:XF 0 "register_operand" "")
7616         (minus:XF (match_operand:XF 1 "register_operand" "")
7617                   (match_operand:XF 2 "register_operand" "")))]
7618   "TARGET_80387"
7619   "")
7620
7621 (define_expand "sub<mode>3"
7622   [(set (match_operand:MODEF 0 "register_operand" "")
7623         (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7624                      (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7625   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7626   "")
7627 \f
7628 ;; Multiply instructions
7629
7630 (define_expand "muldi3"
7631   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7632                    (mult:DI (match_operand:DI 1 "register_operand" "")
7633                             (match_operand:DI 2 "x86_64_general_operand" "")))
7634               (clobber (reg:CC FLAGS_REG))])]
7635   "TARGET_64BIT"
7636   "")
7637
7638 ;; On AMDFAM10
7639 ;; IMUL reg64, reg64, imm8      Direct
7640 ;; IMUL reg64, mem64, imm8      VectorPath
7641 ;; IMUL reg64, reg64, imm32     Direct
7642 ;; IMUL reg64, mem64, imm32     VectorPath
7643 ;; IMUL reg64, reg64            Direct
7644 ;; IMUL reg64, mem64            Direct
7645
7646 (define_insn "*muldi3_1_rex64"
7647   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7648         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7649                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7650    (clobber (reg:CC FLAGS_REG))]
7651   "TARGET_64BIT
7652    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7653   "@
7654    imul{q}\t{%2, %1, %0|%0, %1, %2}
7655    imul{q}\t{%2, %1, %0|%0, %1, %2}
7656    imul{q}\t{%2, %0|%0, %2}"
7657   [(set_attr "type" "imul")
7658    (set_attr "prefix_0f" "0,0,1")
7659    (set (attr "athlon_decode")
7660         (cond [(eq_attr "cpu" "athlon")
7661                   (const_string "vector")
7662                (eq_attr "alternative" "1")
7663                   (const_string "vector")
7664                (and (eq_attr "alternative" "2")
7665                     (match_operand 1 "memory_operand" ""))
7666                   (const_string "vector")]
7667               (const_string "direct")))
7668    (set (attr "amdfam10_decode")
7669         (cond [(and (eq_attr "alternative" "0,1")
7670                     (match_operand 1 "memory_operand" ""))
7671                   (const_string "vector")]
7672               (const_string "direct")))
7673    (set_attr "mode" "DI")])
7674
7675 (define_expand "mulsi3"
7676   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7677                    (mult:SI (match_operand:SI 1 "register_operand" "")
7678                             (match_operand:SI 2 "general_operand" "")))
7679               (clobber (reg:CC FLAGS_REG))])]
7680   ""
7681   "")
7682
7683 ;; On AMDFAM10
7684 ;; IMUL reg32, reg32, imm8      Direct
7685 ;; IMUL reg32, mem32, imm8      VectorPath
7686 ;; IMUL reg32, reg32, imm32     Direct
7687 ;; IMUL reg32, mem32, imm32     VectorPath
7688 ;; IMUL reg32, reg32            Direct
7689 ;; IMUL reg32, mem32            Direct
7690
7691 (define_insn "*mulsi3_1"
7692   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7693         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7694                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7695    (clobber (reg:CC FLAGS_REG))]
7696   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7697   "@
7698    imul{l}\t{%2, %1, %0|%0, %1, %2}
7699    imul{l}\t{%2, %1, %0|%0, %1, %2}
7700    imul{l}\t{%2, %0|%0, %2}"
7701   [(set_attr "type" "imul")
7702    (set_attr "prefix_0f" "0,0,1")
7703    (set (attr "athlon_decode")
7704         (cond [(eq_attr "cpu" "athlon")
7705                   (const_string "vector")
7706                (eq_attr "alternative" "1")
7707                   (const_string "vector")
7708                (and (eq_attr "alternative" "2")
7709                     (match_operand 1 "memory_operand" ""))
7710                   (const_string "vector")]
7711               (const_string "direct")))
7712    (set (attr "amdfam10_decode")
7713         (cond [(and (eq_attr "alternative" "0,1")
7714                     (match_operand 1 "memory_operand" ""))
7715                   (const_string "vector")]
7716               (const_string "direct")))
7717    (set_attr "mode" "SI")])
7718
7719 (define_insn "*mulsi3_1_zext"
7720   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7721         (zero_extend:DI
7722           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7723                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7724    (clobber (reg:CC FLAGS_REG))]
7725   "TARGET_64BIT
7726    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7727   "@
7728    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7729    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7730    imul{l}\t{%2, %k0|%k0, %2}"
7731   [(set_attr "type" "imul")
7732    (set_attr "prefix_0f" "0,0,1")
7733    (set (attr "athlon_decode")
7734         (cond [(eq_attr "cpu" "athlon")
7735                   (const_string "vector")
7736                (eq_attr "alternative" "1")
7737                   (const_string "vector")
7738                (and (eq_attr "alternative" "2")
7739                     (match_operand 1 "memory_operand" ""))
7740                   (const_string "vector")]
7741               (const_string "direct")))
7742    (set (attr "amdfam10_decode")
7743         (cond [(and (eq_attr "alternative" "0,1")
7744                     (match_operand 1 "memory_operand" ""))
7745                   (const_string "vector")]
7746               (const_string "direct")))
7747    (set_attr "mode" "SI")])
7748
7749 (define_expand "mulhi3"
7750   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7751                    (mult:HI (match_operand:HI 1 "register_operand" "")
7752                             (match_operand:HI 2 "general_operand" "")))
7753               (clobber (reg:CC FLAGS_REG))])]
7754   "TARGET_HIMODE_MATH"
7755   "")
7756
7757 ;; On AMDFAM10
7758 ;; IMUL reg16, reg16, imm8      VectorPath
7759 ;; IMUL reg16, mem16, imm8      VectorPath
7760 ;; IMUL reg16, reg16, imm16     VectorPath
7761 ;; IMUL reg16, mem16, imm16     VectorPath
7762 ;; IMUL reg16, reg16            Direct
7763 ;; IMUL reg16, mem16            Direct
7764 (define_insn "*mulhi3_1"
7765   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7766         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7767                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7768    (clobber (reg:CC FLAGS_REG))]
7769   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7770   "@
7771    imul{w}\t{%2, %1, %0|%0, %1, %2}
7772    imul{w}\t{%2, %1, %0|%0, %1, %2}
7773    imul{w}\t{%2, %0|%0, %2}"
7774   [(set_attr "type" "imul")
7775    (set_attr "prefix_0f" "0,0,1")
7776    (set (attr "athlon_decode")
7777         (cond [(eq_attr "cpu" "athlon")
7778                   (const_string "vector")
7779                (eq_attr "alternative" "1,2")
7780                   (const_string "vector")]
7781               (const_string "direct")))
7782    (set (attr "amdfam10_decode")
7783         (cond [(eq_attr "alternative" "0,1")
7784                   (const_string "vector")]
7785               (const_string "direct")))
7786    (set_attr "mode" "HI")])
7787
7788 (define_expand "mulqi3"
7789   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7790                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7791                             (match_operand:QI 2 "register_operand" "")))
7792               (clobber (reg:CC FLAGS_REG))])]
7793   "TARGET_QIMODE_MATH"
7794   "")
7795
7796 ;;On AMDFAM10
7797 ;; MUL reg8     Direct
7798 ;; MUL mem8     Direct
7799
7800 (define_insn "*mulqi3_1"
7801   [(set (match_operand:QI 0 "register_operand" "=a")
7802         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7803                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7804    (clobber (reg:CC FLAGS_REG))]
7805   "TARGET_QIMODE_MATH
7806    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7807   "mul{b}\t%2"
7808   [(set_attr "type" "imul")
7809    (set_attr "length_immediate" "0")
7810    (set (attr "athlon_decode")
7811      (if_then_else (eq_attr "cpu" "athlon")
7812         (const_string "vector")
7813         (const_string "direct")))
7814    (set_attr "amdfam10_decode" "direct")
7815    (set_attr "mode" "QI")])
7816
7817 (define_expand "umulqihi3"
7818   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7819                    (mult:HI (zero_extend:HI
7820                               (match_operand:QI 1 "nonimmediate_operand" ""))
7821                             (zero_extend:HI
7822                               (match_operand:QI 2 "register_operand" ""))))
7823               (clobber (reg:CC FLAGS_REG))])]
7824   "TARGET_QIMODE_MATH"
7825   "")
7826
7827 (define_insn "*umulqihi3_1"
7828   [(set (match_operand:HI 0 "register_operand" "=a")
7829         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7830                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7831    (clobber (reg:CC FLAGS_REG))]
7832   "TARGET_QIMODE_MATH
7833    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7834   "mul{b}\t%2"
7835   [(set_attr "type" "imul")
7836    (set_attr "length_immediate" "0")
7837    (set (attr "athlon_decode")
7838      (if_then_else (eq_attr "cpu" "athlon")
7839         (const_string "vector")
7840         (const_string "direct")))
7841    (set_attr "amdfam10_decode" "direct")
7842    (set_attr "mode" "QI")])
7843
7844 (define_expand "mulqihi3"
7845   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7846                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7847                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7848               (clobber (reg:CC FLAGS_REG))])]
7849   "TARGET_QIMODE_MATH"
7850   "")
7851
7852 (define_insn "*mulqihi3_insn"
7853   [(set (match_operand:HI 0 "register_operand" "=a")
7854         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7855                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7856    (clobber (reg:CC FLAGS_REG))]
7857   "TARGET_QIMODE_MATH
7858    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7859   "imul{b}\t%2"
7860   [(set_attr "type" "imul")
7861    (set_attr "length_immediate" "0")
7862    (set (attr "athlon_decode")
7863      (if_then_else (eq_attr "cpu" "athlon")
7864         (const_string "vector")
7865         (const_string "direct")))
7866    (set_attr "amdfam10_decode" "direct")
7867    (set_attr "mode" "QI")])
7868
7869 (define_expand "umulditi3"
7870   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7871                    (mult:TI (zero_extend:TI
7872                               (match_operand:DI 1 "nonimmediate_operand" ""))
7873                             (zero_extend:TI
7874                               (match_operand:DI 2 "register_operand" ""))))
7875               (clobber (reg:CC FLAGS_REG))])]
7876   "TARGET_64BIT"
7877   "")
7878
7879 (define_insn "*umulditi3_insn"
7880   [(set (match_operand:TI 0 "register_operand" "=A")
7881         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7882                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7883    (clobber (reg:CC FLAGS_REG))]
7884   "TARGET_64BIT
7885    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7886   "mul{q}\t%2"
7887   [(set_attr "type" "imul")
7888    (set_attr "length_immediate" "0")
7889    (set (attr "athlon_decode")
7890      (if_then_else (eq_attr "cpu" "athlon")
7891         (const_string "vector")
7892         (const_string "double")))
7893    (set_attr "amdfam10_decode" "double")
7894    (set_attr "mode" "DI")])
7895
7896 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7897 (define_expand "umulsidi3"
7898   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7899                    (mult:DI (zero_extend:DI
7900                               (match_operand:SI 1 "nonimmediate_operand" ""))
7901                             (zero_extend:DI
7902                               (match_operand:SI 2 "register_operand" ""))))
7903               (clobber (reg:CC FLAGS_REG))])]
7904   "!TARGET_64BIT"
7905   "")
7906
7907 (define_insn "*umulsidi3_insn"
7908   [(set (match_operand:DI 0 "register_operand" "=A")
7909         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7910                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7911    (clobber (reg:CC FLAGS_REG))]
7912   "!TARGET_64BIT
7913    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7914   "mul{l}\t%2"
7915   [(set_attr "type" "imul")
7916    (set_attr "length_immediate" "0")
7917    (set (attr "athlon_decode")
7918      (if_then_else (eq_attr "cpu" "athlon")
7919         (const_string "vector")
7920         (const_string "double")))
7921    (set_attr "amdfam10_decode" "double")
7922    (set_attr "mode" "SI")])
7923
7924 (define_expand "mulditi3"
7925   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7926                    (mult:TI (sign_extend:TI
7927                               (match_operand:DI 1 "nonimmediate_operand" ""))
7928                             (sign_extend:TI
7929                               (match_operand:DI 2 "register_operand" ""))))
7930               (clobber (reg:CC FLAGS_REG))])]
7931   "TARGET_64BIT"
7932   "")
7933
7934 (define_insn "*mulditi3_insn"
7935   [(set (match_operand:TI 0 "register_operand" "=A")
7936         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7937                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7938    (clobber (reg:CC FLAGS_REG))]
7939   "TARGET_64BIT
7940    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7941   "imul{q}\t%2"
7942   [(set_attr "type" "imul")
7943    (set_attr "length_immediate" "0")
7944    (set (attr "athlon_decode")
7945      (if_then_else (eq_attr "cpu" "athlon")
7946         (const_string "vector")
7947         (const_string "double")))
7948    (set_attr "amdfam10_decode" "double")
7949    (set_attr "mode" "DI")])
7950
7951 (define_expand "mulsidi3"
7952   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7953                    (mult:DI (sign_extend:DI
7954                               (match_operand:SI 1 "nonimmediate_operand" ""))
7955                             (sign_extend:DI
7956                               (match_operand:SI 2 "register_operand" ""))))
7957               (clobber (reg:CC FLAGS_REG))])]
7958   "!TARGET_64BIT"
7959   "")
7960
7961 (define_insn "*mulsidi3_insn"
7962   [(set (match_operand:DI 0 "register_operand" "=A")
7963         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7964                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7965    (clobber (reg:CC FLAGS_REG))]
7966   "!TARGET_64BIT
7967    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7968   "imul{l}\t%2"
7969   [(set_attr "type" "imul")
7970    (set_attr "length_immediate" "0")
7971    (set (attr "athlon_decode")
7972      (if_then_else (eq_attr "cpu" "athlon")
7973         (const_string "vector")
7974         (const_string "double")))
7975    (set_attr "amdfam10_decode" "double")
7976    (set_attr "mode" "SI")])
7977
7978 (define_expand "umuldi3_highpart"
7979   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7980                    (truncate:DI
7981                      (lshiftrt:TI
7982                        (mult:TI (zero_extend:TI
7983                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7984                                 (zero_extend:TI
7985                                   (match_operand:DI 2 "register_operand" "")))
7986                        (const_int 64))))
7987               (clobber (match_scratch:DI 3 ""))
7988               (clobber (reg:CC FLAGS_REG))])]
7989   "TARGET_64BIT"
7990   "")
7991
7992 (define_insn "*umuldi3_highpart_rex64"
7993   [(set (match_operand:DI 0 "register_operand" "=d")
7994         (truncate:DI
7995           (lshiftrt:TI
7996             (mult:TI (zero_extend:TI
7997                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7998                      (zero_extend:TI
7999                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8000             (const_int 64))))
8001    (clobber (match_scratch:DI 3 "=1"))
8002    (clobber (reg:CC FLAGS_REG))]
8003   "TARGET_64BIT
8004    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8005   "mul{q}\t%2"
8006   [(set_attr "type" "imul")
8007    (set_attr "length_immediate" "0")
8008    (set (attr "athlon_decode")
8009      (if_then_else (eq_attr "cpu" "athlon")
8010         (const_string "vector")
8011         (const_string "double")))
8012    (set_attr "amdfam10_decode" "double")
8013    (set_attr "mode" "DI")])
8014
8015 (define_expand "umulsi3_highpart"
8016   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8017                    (truncate:SI
8018                      (lshiftrt:DI
8019                        (mult:DI (zero_extend:DI
8020                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8021                                 (zero_extend:DI
8022                                   (match_operand:SI 2 "register_operand" "")))
8023                        (const_int 32))))
8024               (clobber (match_scratch:SI 3 ""))
8025               (clobber (reg:CC FLAGS_REG))])]
8026   ""
8027   "")
8028
8029 (define_insn "*umulsi3_highpart_insn"
8030   [(set (match_operand:SI 0 "register_operand" "=d")
8031         (truncate:SI
8032           (lshiftrt:DI
8033             (mult:DI (zero_extend:DI
8034                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8035                      (zero_extend:DI
8036                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8037             (const_int 32))))
8038    (clobber (match_scratch:SI 3 "=1"))
8039    (clobber (reg:CC FLAGS_REG))]
8040   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8041   "mul{l}\t%2"
8042   [(set_attr "type" "imul")
8043    (set_attr "length_immediate" "0")
8044    (set (attr "athlon_decode")
8045      (if_then_else (eq_attr "cpu" "athlon")
8046         (const_string "vector")
8047         (const_string "double")))
8048    (set_attr "amdfam10_decode" "double")
8049    (set_attr "mode" "SI")])
8050
8051 (define_insn "*umulsi3_highpart_zext"
8052   [(set (match_operand:DI 0 "register_operand" "=d")
8053         (zero_extend:DI (truncate:SI
8054           (lshiftrt:DI
8055             (mult:DI (zero_extend:DI
8056                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8057                      (zero_extend:DI
8058                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8059             (const_int 32)))))
8060    (clobber (match_scratch:SI 3 "=1"))
8061    (clobber (reg:CC FLAGS_REG))]
8062   "TARGET_64BIT
8063    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8064   "mul{l}\t%2"
8065   [(set_attr "type" "imul")
8066    (set_attr "length_immediate" "0")
8067    (set (attr "athlon_decode")
8068      (if_then_else (eq_attr "cpu" "athlon")
8069         (const_string "vector")
8070         (const_string "double")))
8071    (set_attr "amdfam10_decode" "double")
8072    (set_attr "mode" "SI")])
8073
8074 (define_expand "smuldi3_highpart"
8075   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8076                    (truncate:DI
8077                      (lshiftrt:TI
8078                        (mult:TI (sign_extend:TI
8079                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8080                                 (sign_extend:TI
8081                                   (match_operand:DI 2 "register_operand" "")))
8082                        (const_int 64))))
8083               (clobber (match_scratch:DI 3 ""))
8084               (clobber (reg:CC FLAGS_REG))])]
8085   "TARGET_64BIT"
8086   "")
8087
8088 (define_insn "*smuldi3_highpart_rex64"
8089   [(set (match_operand:DI 0 "register_operand" "=d")
8090         (truncate:DI
8091           (lshiftrt:TI
8092             (mult:TI (sign_extend:TI
8093                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8094                      (sign_extend:TI
8095                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8096             (const_int 64))))
8097    (clobber (match_scratch:DI 3 "=1"))
8098    (clobber (reg:CC FLAGS_REG))]
8099   "TARGET_64BIT
8100    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8101   "imul{q}\t%2"
8102   [(set_attr "type" "imul")
8103    (set (attr "athlon_decode")
8104      (if_then_else (eq_attr "cpu" "athlon")
8105         (const_string "vector")
8106         (const_string "double")))
8107    (set_attr "amdfam10_decode" "double")
8108    (set_attr "mode" "DI")])
8109
8110 (define_expand "smulsi3_highpart"
8111   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8112                    (truncate:SI
8113                      (lshiftrt:DI
8114                        (mult:DI (sign_extend:DI
8115                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8116                                 (sign_extend:DI
8117                                   (match_operand:SI 2 "register_operand" "")))
8118                        (const_int 32))))
8119               (clobber (match_scratch:SI 3 ""))
8120               (clobber (reg:CC FLAGS_REG))])]
8121   ""
8122   "")
8123
8124 (define_insn "*smulsi3_highpart_insn"
8125   [(set (match_operand:SI 0 "register_operand" "=d")
8126         (truncate:SI
8127           (lshiftrt:DI
8128             (mult:DI (sign_extend:DI
8129                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8130                      (sign_extend:DI
8131                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8132             (const_int 32))))
8133    (clobber (match_scratch:SI 3 "=1"))
8134    (clobber (reg:CC FLAGS_REG))]
8135   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8136   "imul{l}\t%2"
8137   [(set_attr "type" "imul")
8138    (set (attr "athlon_decode")
8139      (if_then_else (eq_attr "cpu" "athlon")
8140         (const_string "vector")
8141         (const_string "double")))
8142    (set_attr "amdfam10_decode" "double")
8143    (set_attr "mode" "SI")])
8144
8145 (define_insn "*smulsi3_highpart_zext"
8146   [(set (match_operand:DI 0 "register_operand" "=d")
8147         (zero_extend:DI (truncate:SI
8148           (lshiftrt:DI
8149             (mult:DI (sign_extend:DI
8150                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8151                      (sign_extend:DI
8152                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8153             (const_int 32)))))
8154    (clobber (match_scratch:SI 3 "=1"))
8155    (clobber (reg:CC FLAGS_REG))]
8156   "TARGET_64BIT
8157    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8158   "imul{l}\t%2"
8159   [(set_attr "type" "imul")
8160    (set (attr "athlon_decode")
8161      (if_then_else (eq_attr "cpu" "athlon")
8162         (const_string "vector")
8163         (const_string "double")))
8164    (set_attr "amdfam10_decode" "double")
8165    (set_attr "mode" "SI")])
8166
8167 ;; The patterns that match these are at the end of this file.
8168
8169 (define_expand "mulxf3"
8170   [(set (match_operand:XF 0 "register_operand" "")
8171         (mult:XF (match_operand:XF 1 "register_operand" "")
8172                  (match_operand:XF 2 "register_operand" "")))]
8173   "TARGET_80387"
8174   "")
8175
8176 (define_expand "mul<mode>3"
8177   [(set (match_operand:MODEF 0 "register_operand" "")
8178         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8179                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8180   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8181   "")
8182
8183 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8184
8185 \f
8186 ;; Divide instructions
8187
8188 (define_insn "divqi3"
8189   [(set (match_operand:QI 0 "register_operand" "=a")
8190         (div:QI (match_operand:HI 1 "register_operand" "0")
8191                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8192    (clobber (reg:CC FLAGS_REG))]
8193   "TARGET_QIMODE_MATH"
8194   "idiv{b}\t%2"
8195   [(set_attr "type" "idiv")
8196    (set_attr "mode" "QI")])
8197
8198 (define_insn "udivqi3"
8199   [(set (match_operand:QI 0 "register_operand" "=a")
8200         (udiv:QI (match_operand:HI 1 "register_operand" "0")
8201                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8202    (clobber (reg:CC FLAGS_REG))]
8203   "TARGET_QIMODE_MATH"
8204   "div{b}\t%2"
8205   [(set_attr "type" "idiv")
8206    (set_attr "mode" "QI")])
8207
8208 ;; The patterns that match these are at the end of this file.
8209
8210 (define_expand "divxf3"
8211   [(set (match_operand:XF 0 "register_operand" "")
8212         (div:XF (match_operand:XF 1 "register_operand" "")
8213                 (match_operand:XF 2 "register_operand" "")))]
8214   "TARGET_80387"
8215   "")
8216
8217 (define_expand "divdf3"
8218   [(set (match_operand:DF 0 "register_operand" "")
8219         (div:DF (match_operand:DF 1 "register_operand" "")
8220                 (match_operand:DF 2 "nonimmediate_operand" "")))]
8221    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8222    "")
8223
8224 (define_expand "divsf3"
8225   [(set (match_operand:SF 0 "register_operand" "")
8226         (div:SF (match_operand:SF 1 "register_operand" "")
8227                 (match_operand:SF 2 "nonimmediate_operand" "")))]
8228   "TARGET_80387 || TARGET_SSE_MATH"
8229 {
8230   if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8231       && flag_finite_math_only && !flag_trapping_math
8232       && flag_unsafe_math_optimizations)
8233     {
8234       ix86_emit_swdivsf (operands[0], operands[1],
8235                          operands[2], SFmode);
8236       DONE;
8237     }
8238 })
8239 \f
8240 ;; Remainder instructions.
8241
8242 (define_expand "divmoddi4"
8243   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8244                    (div:DI (match_operand:DI 1 "register_operand" "")
8245                            (match_operand:DI 2 "nonimmediate_operand" "")))
8246               (set (match_operand:DI 3 "register_operand" "")
8247                    (mod:DI (match_dup 1) (match_dup 2)))
8248               (clobber (reg:CC FLAGS_REG))])]
8249   "TARGET_64BIT"
8250   "")
8251
8252 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8253 ;; Penalize eax case slightly because it results in worse scheduling
8254 ;; of code.
8255 (define_insn "*divmoddi4_nocltd_rex64"
8256   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8257         (div:DI (match_operand:DI 2 "register_operand" "1,0")
8258                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8259    (set (match_operand:DI 1 "register_operand" "=&d,&d")
8260         (mod:DI (match_dup 2) (match_dup 3)))
8261    (clobber (reg:CC FLAGS_REG))]
8262   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8263   "#"
8264   [(set_attr "type" "multi")])
8265
8266 (define_insn "*divmoddi4_cltd_rex64"
8267   [(set (match_operand:DI 0 "register_operand" "=a")
8268         (div:DI (match_operand:DI 2 "register_operand" "a")
8269                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8270    (set (match_operand:DI 1 "register_operand" "=&d")
8271         (mod:DI (match_dup 2) (match_dup 3)))
8272    (clobber (reg:CC FLAGS_REG))]
8273   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8274   "#"
8275   [(set_attr "type" "multi")])
8276
8277 (define_insn "*divmoddi_noext_rex64"
8278   [(set (match_operand:DI 0 "register_operand" "=a")
8279         (div:DI (match_operand:DI 1 "register_operand" "0")
8280                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8281    (set (match_operand:DI 3 "register_operand" "=d")
8282         (mod:DI (match_dup 1) (match_dup 2)))
8283    (use (match_operand:DI 4 "register_operand" "3"))
8284    (clobber (reg:CC FLAGS_REG))]
8285   "TARGET_64BIT"
8286   "idiv{q}\t%2"
8287   [(set_attr "type" "idiv")
8288    (set_attr "mode" "DI")])
8289
8290 (define_split
8291   [(set (match_operand:DI 0 "register_operand" "")
8292         (div:DI (match_operand:DI 1 "register_operand" "")
8293                 (match_operand:DI 2 "nonimmediate_operand" "")))
8294    (set (match_operand:DI 3 "register_operand" "")
8295         (mod:DI (match_dup 1) (match_dup 2)))
8296    (clobber (reg:CC FLAGS_REG))]
8297   "TARGET_64BIT && reload_completed"
8298   [(parallel [(set (match_dup 3)
8299                    (ashiftrt:DI (match_dup 4) (const_int 63)))
8300               (clobber (reg:CC FLAGS_REG))])
8301    (parallel [(set (match_dup 0)
8302                    (div:DI (reg:DI 0) (match_dup 2)))
8303               (set (match_dup 3)
8304                    (mod:DI (reg:DI 0) (match_dup 2)))
8305               (use (match_dup 3))
8306               (clobber (reg:CC FLAGS_REG))])]
8307 {
8308   /* Avoid use of cltd in favor of a mov+shift.  */
8309   if (!TARGET_USE_CLTD && !optimize_size)
8310     {
8311       if (true_regnum (operands[1]))
8312         emit_move_insn (operands[0], operands[1]);
8313       else
8314         emit_move_insn (operands[3], operands[1]);
8315       operands[4] = operands[3];
8316     }
8317   else
8318     {
8319       gcc_assert (!true_regnum (operands[1]));
8320       operands[4] = operands[1];
8321     }
8322 })
8323
8324
8325 (define_expand "divmodsi4"
8326   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8327                    (div:SI (match_operand:SI 1 "register_operand" "")
8328                            (match_operand:SI 2 "nonimmediate_operand" "")))
8329               (set (match_operand:SI 3 "register_operand" "")
8330                    (mod:SI (match_dup 1) (match_dup 2)))
8331               (clobber (reg:CC FLAGS_REG))])]
8332   ""
8333   "")
8334
8335 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8336 ;; Penalize eax case slightly because it results in worse scheduling
8337 ;; of code.
8338 (define_insn "*divmodsi4_nocltd"
8339   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8340         (div:SI (match_operand:SI 2 "register_operand" "1,0")
8341                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8342    (set (match_operand:SI 1 "register_operand" "=&d,&d")
8343         (mod:SI (match_dup 2) (match_dup 3)))
8344    (clobber (reg:CC FLAGS_REG))]
8345   "!optimize_size && !TARGET_USE_CLTD"
8346   "#"
8347   [(set_attr "type" "multi")])
8348
8349 (define_insn "*divmodsi4_cltd"
8350   [(set (match_operand:SI 0 "register_operand" "=a")
8351         (div:SI (match_operand:SI 2 "register_operand" "a")
8352                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8353    (set (match_operand:SI 1 "register_operand" "=&d")
8354         (mod:SI (match_dup 2) (match_dup 3)))
8355    (clobber (reg:CC FLAGS_REG))]
8356   "optimize_size || TARGET_USE_CLTD"
8357   "#"
8358   [(set_attr "type" "multi")])
8359
8360 (define_insn "*divmodsi_noext"
8361   [(set (match_operand:SI 0 "register_operand" "=a")
8362         (div:SI (match_operand:SI 1 "register_operand" "0")
8363                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8364    (set (match_operand:SI 3 "register_operand" "=d")
8365         (mod:SI (match_dup 1) (match_dup 2)))
8366    (use (match_operand:SI 4 "register_operand" "3"))
8367    (clobber (reg:CC FLAGS_REG))]
8368   ""
8369   "idiv{l}\t%2"
8370   [(set_attr "type" "idiv")
8371    (set_attr "mode" "SI")])
8372
8373 (define_split
8374   [(set (match_operand:SI 0 "register_operand" "")
8375         (div:SI (match_operand:SI 1 "register_operand" "")
8376                 (match_operand:SI 2 "nonimmediate_operand" "")))
8377    (set (match_operand:SI 3 "register_operand" "")
8378         (mod:SI (match_dup 1) (match_dup 2)))
8379    (clobber (reg:CC FLAGS_REG))]
8380   "reload_completed"
8381   [(parallel [(set (match_dup 3)
8382                    (ashiftrt:SI (match_dup 4) (const_int 31)))
8383               (clobber (reg:CC FLAGS_REG))])
8384    (parallel [(set (match_dup 0)
8385                    (div:SI (reg:SI 0) (match_dup 2)))
8386               (set (match_dup 3)
8387                    (mod:SI (reg:SI 0) (match_dup 2)))
8388               (use (match_dup 3))
8389               (clobber (reg:CC FLAGS_REG))])]
8390 {
8391   /* Avoid use of cltd in favor of a mov+shift.  */
8392   if (!TARGET_USE_CLTD && !optimize_size)
8393     {
8394       if (true_regnum (operands[1]))
8395         emit_move_insn (operands[0], operands[1]);
8396       else
8397         emit_move_insn (operands[3], operands[1]);
8398       operands[4] = operands[3];
8399     }
8400   else
8401     {
8402       gcc_assert (!true_regnum (operands[1]));
8403       operands[4] = operands[1];
8404     }
8405 })
8406 ;; %%% Split me.
8407 (define_insn "divmodhi4"
8408   [(set (match_operand:HI 0 "register_operand" "=a")
8409         (div:HI (match_operand:HI 1 "register_operand" "0")
8410                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8411    (set (match_operand:HI 3 "register_operand" "=&d")
8412         (mod:HI (match_dup 1) (match_dup 2)))
8413    (clobber (reg:CC FLAGS_REG))]
8414   "TARGET_HIMODE_MATH"
8415   "cwtd\;idiv{w}\t%2"
8416   [(set_attr "type" "multi")
8417    (set_attr "length_immediate" "0")
8418    (set_attr "mode" "SI")])
8419
8420 (define_insn "udivmoddi4"
8421   [(set (match_operand:DI 0 "register_operand" "=a")
8422         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8423                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8424    (set (match_operand:DI 3 "register_operand" "=&d")
8425         (umod:DI (match_dup 1) (match_dup 2)))
8426    (clobber (reg:CC FLAGS_REG))]
8427   "TARGET_64BIT"
8428   "xor{q}\t%3, %3\;div{q}\t%2"
8429   [(set_attr "type" "multi")
8430    (set_attr "length_immediate" "0")
8431    (set_attr "mode" "DI")])
8432
8433 (define_insn "*udivmoddi4_noext"
8434   [(set (match_operand:DI 0 "register_operand" "=a")
8435         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8436                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8437    (set (match_operand:DI 3 "register_operand" "=d")
8438         (umod:DI (match_dup 1) (match_dup 2)))
8439    (use (match_dup 3))
8440    (clobber (reg:CC FLAGS_REG))]
8441   "TARGET_64BIT"
8442   "div{q}\t%2"
8443   [(set_attr "type" "idiv")
8444    (set_attr "mode" "DI")])
8445
8446 (define_split
8447   [(set (match_operand:DI 0 "register_operand" "")
8448         (udiv:DI (match_operand:DI 1 "register_operand" "")
8449                  (match_operand:DI 2 "nonimmediate_operand" "")))
8450    (set (match_operand:DI 3 "register_operand" "")
8451         (umod:DI (match_dup 1) (match_dup 2)))
8452    (clobber (reg:CC FLAGS_REG))]
8453   "TARGET_64BIT && reload_completed"
8454   [(set (match_dup 3) (const_int 0))
8455    (parallel [(set (match_dup 0)
8456                    (udiv:DI (match_dup 1) (match_dup 2)))
8457               (set (match_dup 3)
8458                    (umod:DI (match_dup 1) (match_dup 2)))
8459               (use (match_dup 3))
8460               (clobber (reg:CC FLAGS_REG))])]
8461   "")
8462
8463 (define_insn "udivmodsi4"
8464   [(set (match_operand:SI 0 "register_operand" "=a")
8465         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8466                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8467    (set (match_operand:SI 3 "register_operand" "=&d")
8468         (umod:SI (match_dup 1) (match_dup 2)))
8469    (clobber (reg:CC FLAGS_REG))]
8470   ""
8471   "xor{l}\t%3, %3\;div{l}\t%2"
8472   [(set_attr "type" "multi")
8473    (set_attr "length_immediate" "0")
8474    (set_attr "mode" "SI")])
8475
8476 (define_insn "*udivmodsi4_noext"
8477   [(set (match_operand:SI 0 "register_operand" "=a")
8478         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8479                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8480    (set (match_operand:SI 3 "register_operand" "=d")
8481         (umod:SI (match_dup 1) (match_dup 2)))
8482    (use (match_dup 3))
8483    (clobber (reg:CC FLAGS_REG))]
8484   ""
8485   "div{l}\t%2"
8486   [(set_attr "type" "idiv")
8487    (set_attr "mode" "SI")])
8488
8489 (define_split
8490   [(set (match_operand:SI 0 "register_operand" "")
8491         (udiv:SI (match_operand:SI 1 "register_operand" "")
8492                  (match_operand:SI 2 "nonimmediate_operand" "")))
8493    (set (match_operand:SI 3 "register_operand" "")
8494         (umod:SI (match_dup 1) (match_dup 2)))
8495    (clobber (reg:CC FLAGS_REG))]
8496   "reload_completed"
8497   [(set (match_dup 3) (const_int 0))
8498    (parallel [(set (match_dup 0)
8499                    (udiv:SI (match_dup 1) (match_dup 2)))
8500               (set (match_dup 3)
8501                    (umod:SI (match_dup 1) (match_dup 2)))
8502               (use (match_dup 3))
8503               (clobber (reg:CC FLAGS_REG))])]
8504   "")
8505
8506 (define_expand "udivmodhi4"
8507   [(set (match_dup 4) (const_int 0))
8508    (parallel [(set (match_operand:HI 0 "register_operand" "")
8509                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8510                             (match_operand:HI 2 "nonimmediate_operand" "")))
8511               (set (match_operand:HI 3 "register_operand" "")
8512                    (umod:HI (match_dup 1) (match_dup 2)))
8513               (use (match_dup 4))
8514               (clobber (reg:CC FLAGS_REG))])]
8515   "TARGET_HIMODE_MATH"
8516   "operands[4] = gen_reg_rtx (HImode);")
8517
8518 (define_insn "*udivmodhi_noext"
8519   [(set (match_operand:HI 0 "register_operand" "=a")
8520         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8521                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8522    (set (match_operand:HI 3 "register_operand" "=d")
8523         (umod:HI (match_dup 1) (match_dup 2)))
8524    (use (match_operand:HI 4 "register_operand" "3"))
8525    (clobber (reg:CC FLAGS_REG))]
8526   ""
8527   "div{w}\t%2"
8528   [(set_attr "type" "idiv")
8529    (set_attr "mode" "HI")])
8530
8531 ;; We cannot use div/idiv for double division, because it causes
8532 ;; "division by zero" on the overflow and that's not what we expect
8533 ;; from truncate.  Because true (non truncating) double division is
8534 ;; never generated, we can't create this insn anyway.
8535 ;
8536 ;(define_insn ""
8537 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8538 ;       (truncate:SI
8539 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8540 ;                  (zero_extend:DI
8541 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8542 ;   (set (match_operand:SI 3 "register_operand" "=d")
8543 ;       (truncate:SI
8544 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8545 ;   (clobber (reg:CC FLAGS_REG))]
8546 ;  ""
8547 ;  "div{l}\t{%2, %0|%0, %2}"
8548 ;  [(set_attr "type" "idiv")])
8549 \f
8550 ;;- Logical AND instructions
8551
8552 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8553 ;; Note that this excludes ah.
8554
8555 (define_insn "*testdi_1_rex64"
8556   [(set (reg FLAGS_REG)
8557         (compare
8558           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8559                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8560           (const_int 0)))]
8561   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8562    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8563   "@
8564    test{l}\t{%k1, %k0|%k0, %k1}
8565    test{l}\t{%k1, %k0|%k0, %k1}
8566    test{q}\t{%1, %0|%0, %1}
8567    test{q}\t{%1, %0|%0, %1}
8568    test{q}\t{%1, %0|%0, %1}"
8569   [(set_attr "type" "test")
8570    (set_attr "modrm" "0,1,0,1,1")
8571    (set_attr "mode" "SI,SI,DI,DI,DI")
8572    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8573
8574 (define_insn "testsi_1"
8575   [(set (reg FLAGS_REG)
8576         (compare
8577           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8578                   (match_operand:SI 1 "general_operand" "in,in,rin"))
8579           (const_int 0)))]
8580   "ix86_match_ccmode (insn, CCNOmode)
8581    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8582   "test{l}\t{%1, %0|%0, %1}"
8583   [(set_attr "type" "test")
8584    (set_attr "modrm" "0,1,1")
8585    (set_attr "mode" "SI")
8586    (set_attr "pent_pair" "uv,np,uv")])
8587
8588 (define_expand "testsi_ccno_1"
8589   [(set (reg:CCNO FLAGS_REG)
8590         (compare:CCNO
8591           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8592                   (match_operand:SI 1 "nonmemory_operand" ""))
8593           (const_int 0)))]
8594   ""
8595   "")
8596
8597 (define_insn "*testhi_1"
8598   [(set (reg FLAGS_REG)
8599         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8600                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8601                  (const_int 0)))]
8602   "ix86_match_ccmode (insn, CCNOmode)
8603    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8604   "test{w}\t{%1, %0|%0, %1}"
8605   [(set_attr "type" "test")
8606    (set_attr "modrm" "0,1,1")
8607    (set_attr "mode" "HI")
8608    (set_attr "pent_pair" "uv,np,uv")])
8609
8610 (define_expand "testqi_ccz_1"
8611   [(set (reg:CCZ FLAGS_REG)
8612         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8613                              (match_operand:QI 1 "nonmemory_operand" ""))
8614                  (const_int 0)))]
8615   ""
8616   "")
8617
8618 (define_insn "*testqi_1_maybe_si"
8619   [(set (reg FLAGS_REG)
8620         (compare
8621           (and:QI
8622             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8623             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8624           (const_int 0)))]
8625    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8626     && ix86_match_ccmode (insn,
8627                          CONST_INT_P (operands[1])
8628                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8629 {
8630   if (which_alternative == 3)
8631     {
8632       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8633         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8634       return "test{l}\t{%1, %k0|%k0, %1}";
8635     }
8636   return "test{b}\t{%1, %0|%0, %1}";
8637 }
8638   [(set_attr "type" "test")
8639    (set_attr "modrm" "0,1,1,1")
8640    (set_attr "mode" "QI,QI,QI,SI")
8641    (set_attr "pent_pair" "uv,np,uv,np")])
8642
8643 (define_insn "*testqi_1"
8644   [(set (reg FLAGS_REG)
8645         (compare
8646           (and:QI
8647             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8648             (match_operand:QI 1 "general_operand" "n,n,qn"))
8649           (const_int 0)))]
8650   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8651    && ix86_match_ccmode (insn, CCNOmode)"
8652   "test{b}\t{%1, %0|%0, %1}"
8653   [(set_attr "type" "test")
8654    (set_attr "modrm" "0,1,1")
8655    (set_attr "mode" "QI")
8656    (set_attr "pent_pair" "uv,np,uv")])
8657
8658 (define_expand "testqi_ext_ccno_0"
8659   [(set (reg:CCNO FLAGS_REG)
8660         (compare:CCNO
8661           (and:SI
8662             (zero_extract:SI
8663               (match_operand 0 "ext_register_operand" "")
8664               (const_int 8)
8665               (const_int 8))
8666             (match_operand 1 "const_int_operand" ""))
8667           (const_int 0)))]
8668   ""
8669   "")
8670
8671 (define_insn "*testqi_ext_0"
8672   [(set (reg FLAGS_REG)
8673         (compare
8674           (and:SI
8675             (zero_extract:SI
8676               (match_operand 0 "ext_register_operand" "Q")
8677               (const_int 8)
8678               (const_int 8))
8679             (match_operand 1 "const_int_operand" "n"))
8680           (const_int 0)))]
8681   "ix86_match_ccmode (insn, CCNOmode)"
8682   "test{b}\t{%1, %h0|%h0, %1}"
8683   [(set_attr "type" "test")
8684    (set_attr "mode" "QI")
8685    (set_attr "length_immediate" "1")
8686    (set_attr "pent_pair" "np")])
8687
8688 (define_insn "*testqi_ext_1"
8689   [(set (reg FLAGS_REG)
8690         (compare
8691           (and:SI
8692             (zero_extract:SI
8693               (match_operand 0 "ext_register_operand" "Q")
8694               (const_int 8)
8695               (const_int 8))
8696             (zero_extend:SI
8697               (match_operand:QI 1 "general_operand" "Qm")))
8698           (const_int 0)))]
8699   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8700    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8701   "test{b}\t{%1, %h0|%h0, %1}"
8702   [(set_attr "type" "test")
8703    (set_attr "mode" "QI")])
8704
8705 (define_insn "*testqi_ext_1_rex64"
8706   [(set (reg FLAGS_REG)
8707         (compare
8708           (and:SI
8709             (zero_extract:SI
8710               (match_operand 0 "ext_register_operand" "Q")
8711               (const_int 8)
8712               (const_int 8))
8713             (zero_extend:SI
8714               (match_operand:QI 1 "register_operand" "Q")))
8715           (const_int 0)))]
8716   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8717   "test{b}\t{%1, %h0|%h0, %1}"
8718   [(set_attr "type" "test")
8719    (set_attr "mode" "QI")])
8720
8721 (define_insn "*testqi_ext_2"
8722   [(set (reg FLAGS_REG)
8723         (compare
8724           (and:SI
8725             (zero_extract:SI
8726               (match_operand 0 "ext_register_operand" "Q")
8727               (const_int 8)
8728               (const_int 8))
8729             (zero_extract:SI
8730               (match_operand 1 "ext_register_operand" "Q")
8731               (const_int 8)
8732               (const_int 8)))
8733           (const_int 0)))]
8734   "ix86_match_ccmode (insn, CCNOmode)"
8735   "test{b}\t{%h1, %h0|%h0, %h1}"
8736   [(set_attr "type" "test")
8737    (set_attr "mode" "QI")])
8738
8739 ;; Combine likes to form bit extractions for some tests.  Humor it.
8740 (define_insn "*testqi_ext_3"
8741   [(set (reg FLAGS_REG)
8742         (compare (zero_extract:SI
8743                    (match_operand 0 "nonimmediate_operand" "rm")
8744                    (match_operand:SI 1 "const_int_operand" "")
8745                    (match_operand:SI 2 "const_int_operand" ""))
8746                  (const_int 0)))]
8747   "ix86_match_ccmode (insn, CCNOmode)
8748    && INTVAL (operands[1]) > 0
8749    && INTVAL (operands[2]) >= 0
8750    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8751    && (GET_MODE (operands[0]) == SImode
8752        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8753        || GET_MODE (operands[0]) == HImode
8754        || GET_MODE (operands[0]) == QImode)"
8755   "#")
8756
8757 (define_insn "*testqi_ext_3_rex64"
8758   [(set (reg FLAGS_REG)
8759         (compare (zero_extract:DI
8760                    (match_operand 0 "nonimmediate_operand" "rm")
8761                    (match_operand:DI 1 "const_int_operand" "")
8762                    (match_operand:DI 2 "const_int_operand" ""))
8763                  (const_int 0)))]
8764   "TARGET_64BIT
8765    && ix86_match_ccmode (insn, CCNOmode)
8766    && INTVAL (operands[1]) > 0
8767    && INTVAL (operands[2]) >= 0
8768    /* Ensure that resulting mask is zero or sign extended operand.  */
8769    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8770        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8771            && INTVAL (operands[1]) > 32))
8772    && (GET_MODE (operands[0]) == SImode
8773        || GET_MODE (operands[0]) == DImode
8774        || GET_MODE (operands[0]) == HImode
8775        || GET_MODE (operands[0]) == QImode)"
8776   "#")
8777
8778 (define_split
8779   [(set (match_operand 0 "flags_reg_operand" "")
8780         (match_operator 1 "compare_operator"
8781           [(zero_extract
8782              (match_operand 2 "nonimmediate_operand" "")
8783              (match_operand 3 "const_int_operand" "")
8784              (match_operand 4 "const_int_operand" ""))
8785            (const_int 0)]))]
8786   "ix86_match_ccmode (insn, CCNOmode)"
8787   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8788 {
8789   rtx val = operands[2];
8790   HOST_WIDE_INT len = INTVAL (operands[3]);
8791   HOST_WIDE_INT pos = INTVAL (operands[4]);
8792   HOST_WIDE_INT mask;
8793   enum machine_mode mode, submode;
8794
8795   mode = GET_MODE (val);
8796   if (MEM_P (val))
8797     {
8798       /* ??? Combine likes to put non-volatile mem extractions in QImode
8799          no matter the size of the test.  So find a mode that works.  */
8800       if (! MEM_VOLATILE_P (val))
8801         {
8802           mode = smallest_mode_for_size (pos + len, MODE_INT);
8803           val = adjust_address (val, mode, 0);
8804         }
8805     }
8806   else if (GET_CODE (val) == SUBREG
8807            && (submode = GET_MODE (SUBREG_REG (val)),
8808                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8809            && pos + len <= GET_MODE_BITSIZE (submode))
8810     {
8811       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8812       mode = submode;
8813       val = SUBREG_REG (val);
8814     }
8815   else if (mode == HImode && pos + len <= 8)
8816     {
8817       /* Small HImode tests can be converted to QImode.  */
8818       mode = QImode;
8819       val = gen_lowpart (QImode, val);
8820     }
8821
8822   if (len == HOST_BITS_PER_WIDE_INT)
8823     mask = -1;
8824   else
8825     mask = ((HOST_WIDE_INT)1 << len) - 1;
8826   mask <<= pos;
8827
8828   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8829 })
8830
8831 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8832 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8833 ;; this is relatively important trick.
8834 ;; Do the conversion only post-reload to avoid limiting of the register class
8835 ;; to QI regs.
8836 (define_split
8837   [(set (match_operand 0 "flags_reg_operand" "")
8838         (match_operator 1 "compare_operator"
8839           [(and (match_operand 2 "register_operand" "")
8840                 (match_operand 3 "const_int_operand" ""))
8841            (const_int 0)]))]
8842    "reload_completed
8843     && QI_REG_P (operands[2])
8844     && GET_MODE (operands[2]) != QImode
8845     && ((ix86_match_ccmode (insn, CCZmode)
8846          && !(INTVAL (operands[3]) & ~(255 << 8)))
8847         || (ix86_match_ccmode (insn, CCNOmode)
8848             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8849   [(set (match_dup 0)
8850         (match_op_dup 1
8851           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8852                    (match_dup 3))
8853            (const_int 0)]))]
8854   "operands[2] = gen_lowpart (SImode, operands[2]);
8855    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8856
8857 (define_split
8858   [(set (match_operand 0 "flags_reg_operand" "")
8859         (match_operator 1 "compare_operator"
8860           [(and (match_operand 2 "nonimmediate_operand" "")
8861                 (match_operand 3 "const_int_operand" ""))
8862            (const_int 0)]))]
8863    "reload_completed
8864     && GET_MODE (operands[2]) != QImode
8865     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8866     && ((ix86_match_ccmode (insn, CCZmode)
8867          && !(INTVAL (operands[3]) & ~255))
8868         || (ix86_match_ccmode (insn, CCNOmode)
8869             && !(INTVAL (operands[3]) & ~127)))"
8870   [(set (match_dup 0)
8871         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8872                          (const_int 0)]))]
8873   "operands[2] = gen_lowpart (QImode, operands[2]);
8874    operands[3] = gen_lowpart (QImode, operands[3]);")
8875
8876
8877 ;; %%% This used to optimize known byte-wide and operations to memory,
8878 ;; and sometimes to QImode registers.  If this is considered useful,
8879 ;; it should be done with splitters.
8880
8881 (define_expand "anddi3"
8882   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8883         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8884                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8885    (clobber (reg:CC FLAGS_REG))]
8886   "TARGET_64BIT"
8887   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8888
8889 (define_insn "*anddi_1_rex64"
8890   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8891         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8892                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8893    (clobber (reg:CC FLAGS_REG))]
8894   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8895 {
8896   switch (get_attr_type (insn))
8897     {
8898     case TYPE_IMOVX:
8899       {
8900         enum machine_mode mode;
8901
8902         gcc_assert (CONST_INT_P (operands[2]));
8903         if (INTVAL (operands[2]) == 0xff)
8904           mode = QImode;
8905         else
8906           {
8907             gcc_assert (INTVAL (operands[2]) == 0xffff);
8908             mode = HImode;
8909           }
8910
8911         operands[1] = gen_lowpart (mode, operands[1]);
8912         if (mode == QImode)
8913           return "movz{bq|x}\t{%1,%0|%0, %1}";
8914         else
8915           return "movz{wq|x}\t{%1,%0|%0, %1}";
8916       }
8917
8918     default:
8919       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8920       if (get_attr_mode (insn) == MODE_SI)
8921         return "and{l}\t{%k2, %k0|%k0, %k2}";
8922       else
8923         return "and{q}\t{%2, %0|%0, %2}";
8924     }
8925 }
8926   [(set_attr "type" "alu,alu,alu,imovx")
8927    (set_attr "length_immediate" "*,*,*,0")
8928    (set_attr "mode" "SI,DI,DI,DI")])
8929
8930 (define_insn "*anddi_2"
8931   [(set (reg FLAGS_REG)
8932         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8933                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8934                  (const_int 0)))
8935    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8936         (and:DI (match_dup 1) (match_dup 2)))]
8937   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8938    && ix86_binary_operator_ok (AND, DImode, operands)"
8939   "@
8940    and{l}\t{%k2, %k0|%k0, %k2}
8941    and{q}\t{%2, %0|%0, %2}
8942    and{q}\t{%2, %0|%0, %2}"
8943   [(set_attr "type" "alu")
8944    (set_attr "mode" "SI,DI,DI")])
8945
8946 (define_expand "andsi3"
8947   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8948         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8949                 (match_operand:SI 2 "general_operand" "")))
8950    (clobber (reg:CC FLAGS_REG))]
8951   ""
8952   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8953
8954 (define_insn "*andsi_1"
8955   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8956         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8957                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8958    (clobber (reg:CC FLAGS_REG))]
8959   "ix86_binary_operator_ok (AND, SImode, operands)"
8960 {
8961   switch (get_attr_type (insn))
8962     {
8963     case TYPE_IMOVX:
8964       {
8965         enum machine_mode mode;
8966
8967         gcc_assert (CONST_INT_P (operands[2]));
8968         if (INTVAL (operands[2]) == 0xff)
8969           mode = QImode;
8970         else
8971           {
8972             gcc_assert (INTVAL (operands[2]) == 0xffff);
8973             mode = HImode;
8974           }
8975
8976         operands[1] = gen_lowpart (mode, operands[1]);
8977         if (mode == QImode)
8978           return "movz{bl|x}\t{%1,%0|%0, %1}";
8979         else
8980           return "movz{wl|x}\t{%1,%0|%0, %1}";
8981       }
8982
8983     default:
8984       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8985       return "and{l}\t{%2, %0|%0, %2}";
8986     }
8987 }
8988   [(set_attr "type" "alu,alu,imovx")
8989    (set_attr "length_immediate" "*,*,0")
8990    (set_attr "mode" "SI")])
8991
8992 (define_split
8993   [(set (match_operand 0 "register_operand" "")
8994         (and (match_dup 0)
8995              (const_int -65536)))
8996    (clobber (reg:CC FLAGS_REG))]
8997   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8998   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8999   "operands[1] = gen_lowpart (HImode, operands[0]);")
9000
9001 (define_split
9002   [(set (match_operand 0 "ext_register_operand" "")
9003         (and (match_dup 0)
9004              (const_int -256)))
9005    (clobber (reg:CC FLAGS_REG))]
9006   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9007   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9008   "operands[1] = gen_lowpart (QImode, operands[0]);")
9009
9010 (define_split
9011   [(set (match_operand 0 "ext_register_operand" "")
9012         (and (match_dup 0)
9013              (const_int -65281)))
9014    (clobber (reg:CC FLAGS_REG))]
9015   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9016   [(parallel [(set (zero_extract:SI (match_dup 0)
9017                                     (const_int 8)
9018                                     (const_int 8))
9019                    (xor:SI
9020                      (zero_extract:SI (match_dup 0)
9021                                       (const_int 8)
9022                                       (const_int 8))
9023                      (zero_extract:SI (match_dup 0)
9024                                       (const_int 8)
9025                                       (const_int 8))))
9026               (clobber (reg:CC FLAGS_REG))])]
9027   "operands[0] = gen_lowpart (SImode, operands[0]);")
9028
9029 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9030 (define_insn "*andsi_1_zext"
9031   [(set (match_operand:DI 0 "register_operand" "=r")
9032         (zero_extend:DI
9033           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9034                   (match_operand:SI 2 "general_operand" "g"))))
9035    (clobber (reg:CC FLAGS_REG))]
9036   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9037   "and{l}\t{%2, %k0|%k0, %2}"
9038   [(set_attr "type" "alu")
9039    (set_attr "mode" "SI")])
9040
9041 (define_insn "*andsi_2"
9042   [(set (reg FLAGS_REG)
9043         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9044                          (match_operand:SI 2 "general_operand" "g,ri"))
9045                  (const_int 0)))
9046    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9047         (and:SI (match_dup 1) (match_dup 2)))]
9048   "ix86_match_ccmode (insn, CCNOmode)
9049    && ix86_binary_operator_ok (AND, SImode, operands)"
9050   "and{l}\t{%2, %0|%0, %2}"
9051   [(set_attr "type" "alu")
9052    (set_attr "mode" "SI")])
9053
9054 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9055 (define_insn "*andsi_2_zext"
9056   [(set (reg FLAGS_REG)
9057         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9058                          (match_operand:SI 2 "general_operand" "g"))
9059                  (const_int 0)))
9060    (set (match_operand:DI 0 "register_operand" "=r")
9061         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9062   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9063    && ix86_binary_operator_ok (AND, SImode, operands)"
9064   "and{l}\t{%2, %k0|%k0, %2}"
9065   [(set_attr "type" "alu")
9066    (set_attr "mode" "SI")])
9067
9068 (define_expand "andhi3"
9069   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9070         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9071                 (match_operand:HI 2 "general_operand" "")))
9072    (clobber (reg:CC FLAGS_REG))]
9073   "TARGET_HIMODE_MATH"
9074   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9075
9076 (define_insn "*andhi_1"
9077   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9078         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9079                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
9080    (clobber (reg:CC FLAGS_REG))]
9081   "ix86_binary_operator_ok (AND, HImode, operands)"
9082 {
9083   switch (get_attr_type (insn))
9084     {
9085     case TYPE_IMOVX:
9086       gcc_assert (CONST_INT_P (operands[2]));
9087       gcc_assert (INTVAL (operands[2]) == 0xff);
9088       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9089
9090     default:
9091       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9092
9093       return "and{w}\t{%2, %0|%0, %2}";
9094     }
9095 }
9096   [(set_attr "type" "alu,alu,imovx")
9097    (set_attr "length_immediate" "*,*,0")
9098    (set_attr "mode" "HI,HI,SI")])
9099
9100 (define_insn "*andhi_2"
9101   [(set (reg FLAGS_REG)
9102         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9103                          (match_operand:HI 2 "general_operand" "g,ri"))
9104                  (const_int 0)))
9105    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9106         (and:HI (match_dup 1) (match_dup 2)))]
9107   "ix86_match_ccmode (insn, CCNOmode)
9108    && ix86_binary_operator_ok (AND, HImode, operands)"
9109   "and{w}\t{%2, %0|%0, %2}"
9110   [(set_attr "type" "alu")
9111    (set_attr "mode" "HI")])
9112
9113 (define_expand "andqi3"
9114   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9115         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9116                 (match_operand:QI 2 "general_operand" "")))
9117    (clobber (reg:CC FLAGS_REG))]
9118   "TARGET_QIMODE_MATH"
9119   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9120
9121 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9122 (define_insn "*andqi_1"
9123   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9124         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9125                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
9126    (clobber (reg:CC FLAGS_REG))]
9127   "ix86_binary_operator_ok (AND, QImode, operands)"
9128   "@
9129    and{b}\t{%2, %0|%0, %2}
9130    and{b}\t{%2, %0|%0, %2}
9131    and{l}\t{%k2, %k0|%k0, %k2}"
9132   [(set_attr "type" "alu")
9133    (set_attr "mode" "QI,QI,SI")])
9134
9135 (define_insn "*andqi_1_slp"
9136   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9137         (and:QI (match_dup 0)
9138                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9139    (clobber (reg:CC FLAGS_REG))]
9140   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9141    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9142   "and{b}\t{%1, %0|%0, %1}"
9143   [(set_attr "type" "alu1")
9144    (set_attr "mode" "QI")])
9145
9146 (define_insn "*andqi_2_maybe_si"
9147   [(set (reg FLAGS_REG)
9148         (compare (and:QI
9149                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9150                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
9151                  (const_int 0)))
9152    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9153         (and:QI (match_dup 1) (match_dup 2)))]
9154   "ix86_binary_operator_ok (AND, QImode, operands)
9155    && ix86_match_ccmode (insn,
9156                          CONST_INT_P (operands[2])
9157                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9158 {
9159   if (which_alternative == 2)
9160     {
9161       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9162         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9163       return "and{l}\t{%2, %k0|%k0, %2}";
9164     }
9165   return "and{b}\t{%2, %0|%0, %2}";
9166 }
9167   [(set_attr "type" "alu")
9168    (set_attr "mode" "QI,QI,SI")])
9169
9170 (define_insn "*andqi_2"
9171   [(set (reg FLAGS_REG)
9172         (compare (and:QI
9173                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9174                    (match_operand:QI 2 "general_operand" "qim,qi"))
9175                  (const_int 0)))
9176    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9177         (and:QI (match_dup 1) (match_dup 2)))]
9178   "ix86_match_ccmode (insn, CCNOmode)
9179    && ix86_binary_operator_ok (AND, QImode, operands)"
9180   "and{b}\t{%2, %0|%0, %2}"
9181   [(set_attr "type" "alu")
9182    (set_attr "mode" "QI")])
9183
9184 (define_insn "*andqi_2_slp"
9185   [(set (reg FLAGS_REG)
9186         (compare (and:QI
9187                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9188                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
9189                  (const_int 0)))
9190    (set (strict_low_part (match_dup 0))
9191         (and:QI (match_dup 0) (match_dup 1)))]
9192   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9193    && ix86_match_ccmode (insn, CCNOmode)
9194    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9195   "and{b}\t{%1, %0|%0, %1}"
9196   [(set_attr "type" "alu1")
9197    (set_attr "mode" "QI")])
9198
9199 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9200 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
9201 ;; for a QImode operand, which of course failed.
9202
9203 (define_insn "andqi_ext_0"
9204   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9205                          (const_int 8)
9206                          (const_int 8))
9207         (and:SI
9208           (zero_extract:SI
9209             (match_operand 1 "ext_register_operand" "0")
9210             (const_int 8)
9211             (const_int 8))
9212           (match_operand 2 "const_int_operand" "n")))
9213    (clobber (reg:CC FLAGS_REG))]
9214   ""
9215   "and{b}\t{%2, %h0|%h0, %2}"
9216   [(set_attr "type" "alu")
9217    (set_attr "length_immediate" "1")
9218    (set_attr "mode" "QI")])
9219
9220 ;; Generated by peephole translating test to and.  This shows up
9221 ;; often in fp comparisons.
9222
9223 (define_insn "*andqi_ext_0_cc"
9224   [(set (reg FLAGS_REG)
9225         (compare
9226           (and:SI
9227             (zero_extract:SI
9228               (match_operand 1 "ext_register_operand" "0")
9229               (const_int 8)
9230               (const_int 8))
9231             (match_operand 2 "const_int_operand" "n"))
9232           (const_int 0)))
9233    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9234                          (const_int 8)
9235                          (const_int 8))
9236         (and:SI
9237           (zero_extract:SI
9238             (match_dup 1)
9239             (const_int 8)
9240             (const_int 8))
9241           (match_dup 2)))]
9242   "ix86_match_ccmode (insn, CCNOmode)"
9243   "and{b}\t{%2, %h0|%h0, %2}"
9244   [(set_attr "type" "alu")
9245    (set_attr "length_immediate" "1")
9246    (set_attr "mode" "QI")])
9247
9248 (define_insn "*andqi_ext_1"
9249   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9250                          (const_int 8)
9251                          (const_int 8))
9252         (and:SI
9253           (zero_extract:SI
9254             (match_operand 1 "ext_register_operand" "0")
9255             (const_int 8)
9256             (const_int 8))
9257           (zero_extend:SI
9258             (match_operand:QI 2 "general_operand" "Qm"))))
9259    (clobber (reg:CC FLAGS_REG))]
9260   "!TARGET_64BIT"
9261   "and{b}\t{%2, %h0|%h0, %2}"
9262   [(set_attr "type" "alu")
9263    (set_attr "length_immediate" "0")
9264    (set_attr "mode" "QI")])
9265
9266 (define_insn "*andqi_ext_1_rex64"
9267   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9268                          (const_int 8)
9269                          (const_int 8))
9270         (and:SI
9271           (zero_extract:SI
9272             (match_operand 1 "ext_register_operand" "0")
9273             (const_int 8)
9274             (const_int 8))
9275           (zero_extend:SI
9276             (match_operand 2 "ext_register_operand" "Q"))))
9277    (clobber (reg:CC FLAGS_REG))]
9278   "TARGET_64BIT"
9279   "and{b}\t{%2, %h0|%h0, %2}"
9280   [(set_attr "type" "alu")
9281    (set_attr "length_immediate" "0")
9282    (set_attr "mode" "QI")])
9283
9284 (define_insn "*andqi_ext_2"
9285   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9286                          (const_int 8)
9287                          (const_int 8))
9288         (and:SI
9289           (zero_extract:SI
9290             (match_operand 1 "ext_register_operand" "%0")
9291             (const_int 8)
9292             (const_int 8))
9293           (zero_extract:SI
9294             (match_operand 2 "ext_register_operand" "Q")
9295             (const_int 8)
9296             (const_int 8))))
9297    (clobber (reg:CC FLAGS_REG))]
9298   ""
9299   "and{b}\t{%h2, %h0|%h0, %h2}"
9300   [(set_attr "type" "alu")
9301    (set_attr "length_immediate" "0")
9302    (set_attr "mode" "QI")])
9303
9304 ;; Convert wide AND instructions with immediate operand to shorter QImode
9305 ;; equivalents when possible.
9306 ;; Don't do the splitting with memory operands, since it introduces risk
9307 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9308 ;; for size, but that can (should?) be handled by generic code instead.
9309 (define_split
9310   [(set (match_operand 0 "register_operand" "")
9311         (and (match_operand 1 "register_operand" "")
9312              (match_operand 2 "const_int_operand" "")))
9313    (clobber (reg:CC FLAGS_REG))]
9314    "reload_completed
9315     && QI_REG_P (operands[0])
9316     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9317     && !(~INTVAL (operands[2]) & ~(255 << 8))
9318     && GET_MODE (operands[0]) != QImode"
9319   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9320                    (and:SI (zero_extract:SI (match_dup 1)
9321                                             (const_int 8) (const_int 8))
9322                            (match_dup 2)))
9323               (clobber (reg:CC FLAGS_REG))])]
9324   "operands[0] = gen_lowpart (SImode, operands[0]);
9325    operands[1] = gen_lowpart (SImode, operands[1]);
9326    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9327
9328 ;; Since AND can be encoded with sign extended immediate, this is only
9329 ;; profitable when 7th bit is not set.
9330 (define_split
9331   [(set (match_operand 0 "register_operand" "")
9332         (and (match_operand 1 "general_operand" "")
9333              (match_operand 2 "const_int_operand" "")))
9334    (clobber (reg:CC FLAGS_REG))]
9335    "reload_completed
9336     && ANY_QI_REG_P (operands[0])
9337     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9338     && !(~INTVAL (operands[2]) & ~255)
9339     && !(INTVAL (operands[2]) & 128)
9340     && GET_MODE (operands[0]) != QImode"
9341   [(parallel [(set (strict_low_part (match_dup 0))
9342                    (and:QI (match_dup 1)
9343                            (match_dup 2)))
9344               (clobber (reg:CC FLAGS_REG))])]
9345   "operands[0] = gen_lowpart (QImode, operands[0]);
9346    operands[1] = gen_lowpart (QImode, operands[1]);
9347    operands[2] = gen_lowpart (QImode, operands[2]);")
9348 \f
9349 ;; Logical inclusive OR instructions
9350
9351 ;; %%% This used to optimize known byte-wide and operations to memory.
9352 ;; If this is considered useful, it should be done with splitters.
9353
9354 (define_expand "iordi3"
9355   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9356         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9357                 (match_operand:DI 2 "x86_64_general_operand" "")))
9358    (clobber (reg:CC FLAGS_REG))]
9359   "TARGET_64BIT"
9360   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9361
9362 (define_insn "*iordi_1_rex64"
9363   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9364         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9365                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9366    (clobber (reg:CC FLAGS_REG))]
9367   "TARGET_64BIT
9368    && ix86_binary_operator_ok (IOR, DImode, operands)"
9369   "or{q}\t{%2, %0|%0, %2}"
9370   [(set_attr "type" "alu")
9371    (set_attr "mode" "DI")])
9372
9373 (define_insn "*iordi_2_rex64"
9374   [(set (reg FLAGS_REG)
9375         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9376                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9377                  (const_int 0)))
9378    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9379         (ior:DI (match_dup 1) (match_dup 2)))]
9380   "TARGET_64BIT
9381    && ix86_match_ccmode (insn, CCNOmode)
9382    && ix86_binary_operator_ok (IOR, DImode, operands)"
9383   "or{q}\t{%2, %0|%0, %2}"
9384   [(set_attr "type" "alu")
9385    (set_attr "mode" "DI")])
9386
9387 (define_insn "*iordi_3_rex64"
9388   [(set (reg FLAGS_REG)
9389         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9390                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9391                  (const_int 0)))
9392    (clobber (match_scratch:DI 0 "=r"))]
9393   "TARGET_64BIT
9394    && ix86_match_ccmode (insn, CCNOmode)
9395    && ix86_binary_operator_ok (IOR, DImode, operands)"
9396   "or{q}\t{%2, %0|%0, %2}"
9397   [(set_attr "type" "alu")
9398    (set_attr "mode" "DI")])
9399
9400
9401 (define_expand "iorsi3"
9402   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9403         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9404                 (match_operand:SI 2 "general_operand" "")))
9405    (clobber (reg:CC FLAGS_REG))]
9406   ""
9407   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9408
9409 (define_insn "*iorsi_1"
9410   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9411         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9412                 (match_operand:SI 2 "general_operand" "ri,g")))
9413    (clobber (reg:CC FLAGS_REG))]
9414   "ix86_binary_operator_ok (IOR, SImode, operands)"
9415   "or{l}\t{%2, %0|%0, %2}"
9416   [(set_attr "type" "alu")
9417    (set_attr "mode" "SI")])
9418
9419 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9420 (define_insn "*iorsi_1_zext"
9421   [(set (match_operand:DI 0 "register_operand" "=r")
9422         (zero_extend:DI
9423           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9424                   (match_operand:SI 2 "general_operand" "g"))))
9425    (clobber (reg:CC FLAGS_REG))]
9426   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9427   "or{l}\t{%2, %k0|%k0, %2}"
9428   [(set_attr "type" "alu")
9429    (set_attr "mode" "SI")])
9430
9431 (define_insn "*iorsi_1_zext_imm"
9432   [(set (match_operand:DI 0 "register_operand" "=r")
9433         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9434                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9435    (clobber (reg:CC FLAGS_REG))]
9436   "TARGET_64BIT"
9437   "or{l}\t{%2, %k0|%k0, %2}"
9438   [(set_attr "type" "alu")
9439    (set_attr "mode" "SI")])
9440
9441 (define_insn "*iorsi_2"
9442   [(set (reg FLAGS_REG)
9443         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9444                          (match_operand:SI 2 "general_operand" "g,ri"))
9445                  (const_int 0)))
9446    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9447         (ior:SI (match_dup 1) (match_dup 2)))]
9448   "ix86_match_ccmode (insn, CCNOmode)
9449    && ix86_binary_operator_ok (IOR, SImode, operands)"
9450   "or{l}\t{%2, %0|%0, %2}"
9451   [(set_attr "type" "alu")
9452    (set_attr "mode" "SI")])
9453
9454 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9455 ;; ??? Special case for immediate operand is missing - it is tricky.
9456 (define_insn "*iorsi_2_zext"
9457   [(set (reg FLAGS_REG)
9458         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9459                          (match_operand:SI 2 "general_operand" "g"))
9460                  (const_int 0)))
9461    (set (match_operand:DI 0 "register_operand" "=r")
9462         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9463   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9464    && ix86_binary_operator_ok (IOR, SImode, operands)"
9465   "or{l}\t{%2, %k0|%k0, %2}"
9466   [(set_attr "type" "alu")
9467    (set_attr "mode" "SI")])
9468
9469 (define_insn "*iorsi_2_zext_imm"
9470   [(set (reg FLAGS_REG)
9471         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9472                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9473                  (const_int 0)))
9474    (set (match_operand:DI 0 "register_operand" "=r")
9475         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9476   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9477    && ix86_binary_operator_ok (IOR, SImode, operands)"
9478   "or{l}\t{%2, %k0|%k0, %2}"
9479   [(set_attr "type" "alu")
9480    (set_attr "mode" "SI")])
9481
9482 (define_insn "*iorsi_3"
9483   [(set (reg FLAGS_REG)
9484         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9485                          (match_operand:SI 2 "general_operand" "g"))
9486                  (const_int 0)))
9487    (clobber (match_scratch:SI 0 "=r"))]
9488   "ix86_match_ccmode (insn, CCNOmode)
9489    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9490   "or{l}\t{%2, %0|%0, %2}"
9491   [(set_attr "type" "alu")
9492    (set_attr "mode" "SI")])
9493
9494 (define_expand "iorhi3"
9495   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9496         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9497                 (match_operand:HI 2 "general_operand" "")))
9498    (clobber (reg:CC FLAGS_REG))]
9499   "TARGET_HIMODE_MATH"
9500   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9501
9502 (define_insn "*iorhi_1"
9503   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9504         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9505                 (match_operand:HI 2 "general_operand" "g,ri")))
9506    (clobber (reg:CC FLAGS_REG))]
9507   "ix86_binary_operator_ok (IOR, HImode, operands)"
9508   "or{w}\t{%2, %0|%0, %2}"
9509   [(set_attr "type" "alu")
9510    (set_attr "mode" "HI")])
9511
9512 (define_insn "*iorhi_2"
9513   [(set (reg FLAGS_REG)
9514         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9515                          (match_operand:HI 2 "general_operand" "g,ri"))
9516                  (const_int 0)))
9517    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9518         (ior:HI (match_dup 1) (match_dup 2)))]
9519   "ix86_match_ccmode (insn, CCNOmode)
9520    && ix86_binary_operator_ok (IOR, HImode, operands)"
9521   "or{w}\t{%2, %0|%0, %2}"
9522   [(set_attr "type" "alu")
9523    (set_attr "mode" "HI")])
9524
9525 (define_insn "*iorhi_3"
9526   [(set (reg FLAGS_REG)
9527         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9528                          (match_operand:HI 2 "general_operand" "g"))
9529                  (const_int 0)))
9530    (clobber (match_scratch:HI 0 "=r"))]
9531   "ix86_match_ccmode (insn, CCNOmode)
9532    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9533   "or{w}\t{%2, %0|%0, %2}"
9534   [(set_attr "type" "alu")
9535    (set_attr "mode" "HI")])
9536
9537 (define_expand "iorqi3"
9538   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9539         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9540                 (match_operand:QI 2 "general_operand" "")))
9541    (clobber (reg:CC FLAGS_REG))]
9542   "TARGET_QIMODE_MATH"
9543   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9544
9545 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9546 (define_insn "*iorqi_1"
9547   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9548         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9549                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9550    (clobber (reg:CC FLAGS_REG))]
9551   "ix86_binary_operator_ok (IOR, QImode, operands)"
9552   "@
9553    or{b}\t{%2, %0|%0, %2}
9554    or{b}\t{%2, %0|%0, %2}
9555    or{l}\t{%k2, %k0|%k0, %k2}"
9556   [(set_attr "type" "alu")
9557    (set_attr "mode" "QI,QI,SI")])
9558
9559 (define_insn "*iorqi_1_slp"
9560   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9561         (ior:QI (match_dup 0)
9562                 (match_operand:QI 1 "general_operand" "qmi,qi")))
9563    (clobber (reg:CC FLAGS_REG))]
9564   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9565    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9566   "or{b}\t{%1, %0|%0, %1}"
9567   [(set_attr "type" "alu1")
9568    (set_attr "mode" "QI")])
9569
9570 (define_insn "*iorqi_2"
9571   [(set (reg FLAGS_REG)
9572         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9573                          (match_operand:QI 2 "general_operand" "qim,qi"))
9574                  (const_int 0)))
9575    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9576         (ior:QI (match_dup 1) (match_dup 2)))]
9577   "ix86_match_ccmode (insn, CCNOmode)
9578    && ix86_binary_operator_ok (IOR, QImode, operands)"
9579   "or{b}\t{%2, %0|%0, %2}"
9580   [(set_attr "type" "alu")
9581    (set_attr "mode" "QI")])
9582
9583 (define_insn "*iorqi_2_slp"
9584   [(set (reg FLAGS_REG)
9585         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9586                          (match_operand:QI 1 "general_operand" "qim,qi"))
9587                  (const_int 0)))
9588    (set (strict_low_part (match_dup 0))
9589         (ior:QI (match_dup 0) (match_dup 1)))]
9590   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9591    && ix86_match_ccmode (insn, CCNOmode)
9592    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9593   "or{b}\t{%1, %0|%0, %1}"
9594   [(set_attr "type" "alu1")
9595    (set_attr "mode" "QI")])
9596
9597 (define_insn "*iorqi_3"
9598   [(set (reg FLAGS_REG)
9599         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9600                          (match_operand:QI 2 "general_operand" "qim"))
9601                  (const_int 0)))
9602    (clobber (match_scratch:QI 0 "=q"))]
9603   "ix86_match_ccmode (insn, CCNOmode)
9604    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9605   "or{b}\t{%2, %0|%0, %2}"
9606   [(set_attr "type" "alu")
9607    (set_attr "mode" "QI")])
9608
9609 (define_insn "iorqi_ext_0"
9610   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9611                          (const_int 8)
9612                          (const_int 8))
9613         (ior:SI
9614           (zero_extract:SI
9615             (match_operand 1 "ext_register_operand" "0")
9616             (const_int 8)
9617             (const_int 8))
9618           (match_operand 2 "const_int_operand" "n")))
9619    (clobber (reg:CC FLAGS_REG))]
9620   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9621   "or{b}\t{%2, %h0|%h0, %2}"
9622   [(set_attr "type" "alu")
9623    (set_attr "length_immediate" "1")
9624    (set_attr "mode" "QI")])
9625
9626 (define_insn "*iorqi_ext_1"
9627   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9628                          (const_int 8)
9629                          (const_int 8))
9630         (ior:SI
9631           (zero_extract:SI
9632             (match_operand 1 "ext_register_operand" "0")
9633             (const_int 8)
9634             (const_int 8))
9635           (zero_extend:SI
9636             (match_operand:QI 2 "general_operand" "Qm"))))
9637    (clobber (reg:CC FLAGS_REG))]
9638   "!TARGET_64BIT
9639    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9640   "or{b}\t{%2, %h0|%h0, %2}"
9641   [(set_attr "type" "alu")
9642    (set_attr "length_immediate" "0")
9643    (set_attr "mode" "QI")])
9644
9645 (define_insn "*iorqi_ext_1_rex64"
9646   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9647                          (const_int 8)
9648                          (const_int 8))
9649         (ior:SI
9650           (zero_extract:SI
9651             (match_operand 1 "ext_register_operand" "0")
9652             (const_int 8)
9653             (const_int 8))
9654           (zero_extend:SI
9655             (match_operand 2 "ext_register_operand" "Q"))))
9656    (clobber (reg:CC FLAGS_REG))]
9657   "TARGET_64BIT
9658    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9659   "or{b}\t{%2, %h0|%h0, %2}"
9660   [(set_attr "type" "alu")
9661    (set_attr "length_immediate" "0")
9662    (set_attr "mode" "QI")])
9663
9664 (define_insn "*iorqi_ext_2"
9665   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9666                          (const_int 8)
9667                          (const_int 8))
9668         (ior:SI
9669           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9670                            (const_int 8)
9671                            (const_int 8))
9672           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9673                            (const_int 8)
9674                            (const_int 8))))
9675    (clobber (reg:CC FLAGS_REG))]
9676   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9677   "ior{b}\t{%h2, %h0|%h0, %h2}"
9678   [(set_attr "type" "alu")
9679    (set_attr "length_immediate" "0")
9680    (set_attr "mode" "QI")])
9681
9682 (define_split
9683   [(set (match_operand 0 "register_operand" "")
9684         (ior (match_operand 1 "register_operand" "")
9685              (match_operand 2 "const_int_operand" "")))
9686    (clobber (reg:CC FLAGS_REG))]
9687    "reload_completed
9688     && QI_REG_P (operands[0])
9689     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9690     && !(INTVAL (operands[2]) & ~(255 << 8))
9691     && GET_MODE (operands[0]) != QImode"
9692   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9693                    (ior:SI (zero_extract:SI (match_dup 1)
9694                                             (const_int 8) (const_int 8))
9695                            (match_dup 2)))
9696               (clobber (reg:CC FLAGS_REG))])]
9697   "operands[0] = gen_lowpart (SImode, operands[0]);
9698    operands[1] = gen_lowpart (SImode, operands[1]);
9699    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9700
9701 ;; Since OR can be encoded with sign extended immediate, this is only
9702 ;; profitable when 7th bit is set.
9703 (define_split
9704   [(set (match_operand 0 "register_operand" "")
9705         (ior (match_operand 1 "general_operand" "")
9706              (match_operand 2 "const_int_operand" "")))
9707    (clobber (reg:CC FLAGS_REG))]
9708    "reload_completed
9709     && ANY_QI_REG_P (operands[0])
9710     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9711     && !(INTVAL (operands[2]) & ~255)
9712     && (INTVAL (operands[2]) & 128)
9713     && GET_MODE (operands[0]) != QImode"
9714   [(parallel [(set (strict_low_part (match_dup 0))
9715                    (ior:QI (match_dup 1)
9716                            (match_dup 2)))
9717               (clobber (reg:CC FLAGS_REG))])]
9718   "operands[0] = gen_lowpart (QImode, operands[0]);
9719    operands[1] = gen_lowpart (QImode, operands[1]);
9720    operands[2] = gen_lowpart (QImode, operands[2]);")
9721 \f
9722 ;; Logical XOR instructions
9723
9724 ;; %%% This used to optimize known byte-wide and operations to memory.
9725 ;; If this is considered useful, it should be done with splitters.
9726
9727 (define_expand "xordi3"
9728   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9729         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9730                 (match_operand:DI 2 "x86_64_general_operand" "")))
9731    (clobber (reg:CC FLAGS_REG))]
9732   "TARGET_64BIT"
9733   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9734
9735 (define_insn "*xordi_1_rex64"
9736   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9737         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9738                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9739    (clobber (reg:CC FLAGS_REG))]
9740   "TARGET_64BIT
9741    && ix86_binary_operator_ok (XOR, DImode, operands)"
9742   "@
9743    xor{q}\t{%2, %0|%0, %2}
9744    xor{q}\t{%2, %0|%0, %2}"
9745   [(set_attr "type" "alu")
9746    (set_attr "mode" "DI,DI")])
9747
9748 (define_insn "*xordi_2_rex64"
9749   [(set (reg FLAGS_REG)
9750         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9751                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9752                  (const_int 0)))
9753    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9754         (xor:DI (match_dup 1) (match_dup 2)))]
9755   "TARGET_64BIT
9756    && ix86_match_ccmode (insn, CCNOmode)
9757    && ix86_binary_operator_ok (XOR, DImode, operands)"
9758   "@
9759    xor{q}\t{%2, %0|%0, %2}
9760    xor{q}\t{%2, %0|%0, %2}"
9761   [(set_attr "type" "alu")
9762    (set_attr "mode" "DI,DI")])
9763
9764 (define_insn "*xordi_3_rex64"
9765   [(set (reg FLAGS_REG)
9766         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9767                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9768                  (const_int 0)))
9769    (clobber (match_scratch:DI 0 "=r"))]
9770   "TARGET_64BIT
9771    && ix86_match_ccmode (insn, CCNOmode)
9772    && ix86_binary_operator_ok (XOR, DImode, operands)"
9773   "xor{q}\t{%2, %0|%0, %2}"
9774   [(set_attr "type" "alu")
9775    (set_attr "mode" "DI")])
9776
9777 (define_expand "xorsi3"
9778   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9779         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9780                 (match_operand:SI 2 "general_operand" "")))
9781    (clobber (reg:CC FLAGS_REG))]
9782   ""
9783   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9784
9785 (define_insn "*xorsi_1"
9786   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9787         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9788                 (match_operand:SI 2 "general_operand" "ri,rm")))
9789    (clobber (reg:CC FLAGS_REG))]
9790   "ix86_binary_operator_ok (XOR, SImode, operands)"
9791   "xor{l}\t{%2, %0|%0, %2}"
9792   [(set_attr "type" "alu")
9793    (set_attr "mode" "SI")])
9794
9795 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9796 ;; Add speccase for immediates
9797 (define_insn "*xorsi_1_zext"
9798   [(set (match_operand:DI 0 "register_operand" "=r")
9799         (zero_extend:DI
9800           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9801                   (match_operand:SI 2 "general_operand" "g"))))
9802    (clobber (reg:CC FLAGS_REG))]
9803   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9804   "xor{l}\t{%2, %k0|%k0, %2}"
9805   [(set_attr "type" "alu")
9806    (set_attr "mode" "SI")])
9807
9808 (define_insn "*xorsi_1_zext_imm"
9809   [(set (match_operand:DI 0 "register_operand" "=r")
9810         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9811                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9812    (clobber (reg:CC FLAGS_REG))]
9813   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9814   "xor{l}\t{%2, %k0|%k0, %2}"
9815   [(set_attr "type" "alu")
9816    (set_attr "mode" "SI")])
9817
9818 (define_insn "*xorsi_2"
9819   [(set (reg FLAGS_REG)
9820         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9821                          (match_operand:SI 2 "general_operand" "g,ri"))
9822                  (const_int 0)))
9823    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9824         (xor:SI (match_dup 1) (match_dup 2)))]
9825   "ix86_match_ccmode (insn, CCNOmode)
9826    && ix86_binary_operator_ok (XOR, SImode, operands)"
9827   "xor{l}\t{%2, %0|%0, %2}"
9828   [(set_attr "type" "alu")
9829    (set_attr "mode" "SI")])
9830
9831 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9832 ;; ??? Special case for immediate operand is missing - it is tricky.
9833 (define_insn "*xorsi_2_zext"
9834   [(set (reg FLAGS_REG)
9835         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9836                          (match_operand:SI 2 "general_operand" "g"))
9837                  (const_int 0)))
9838    (set (match_operand:DI 0 "register_operand" "=r")
9839         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9840   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9841    && ix86_binary_operator_ok (XOR, SImode, operands)"
9842   "xor{l}\t{%2, %k0|%k0, %2}"
9843   [(set_attr "type" "alu")
9844    (set_attr "mode" "SI")])
9845
9846 (define_insn "*xorsi_2_zext_imm"
9847   [(set (reg FLAGS_REG)
9848         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9849                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9850                  (const_int 0)))
9851    (set (match_operand:DI 0 "register_operand" "=r")
9852         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9853   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9854    && ix86_binary_operator_ok (XOR, SImode, operands)"
9855   "xor{l}\t{%2, %k0|%k0, %2}"
9856   [(set_attr "type" "alu")
9857    (set_attr "mode" "SI")])
9858
9859 (define_insn "*xorsi_3"
9860   [(set (reg FLAGS_REG)
9861         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9862                          (match_operand:SI 2 "general_operand" "g"))
9863                  (const_int 0)))
9864    (clobber (match_scratch:SI 0 "=r"))]
9865   "ix86_match_ccmode (insn, CCNOmode)
9866    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9867   "xor{l}\t{%2, %0|%0, %2}"
9868   [(set_attr "type" "alu")
9869    (set_attr "mode" "SI")])
9870
9871 (define_expand "xorhi3"
9872   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9873         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9874                 (match_operand:HI 2 "general_operand" "")))
9875    (clobber (reg:CC FLAGS_REG))]
9876   "TARGET_HIMODE_MATH"
9877   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9878
9879 (define_insn "*xorhi_1"
9880   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9881         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9882                 (match_operand:HI 2 "general_operand" "g,ri")))
9883    (clobber (reg:CC FLAGS_REG))]
9884   "ix86_binary_operator_ok (XOR, HImode, operands)"
9885   "xor{w}\t{%2, %0|%0, %2}"
9886   [(set_attr "type" "alu")
9887    (set_attr "mode" "HI")])
9888
9889 (define_insn "*xorhi_2"
9890   [(set (reg FLAGS_REG)
9891         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9892                          (match_operand:HI 2 "general_operand" "g,ri"))
9893                  (const_int 0)))
9894    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9895         (xor:HI (match_dup 1) (match_dup 2)))]
9896   "ix86_match_ccmode (insn, CCNOmode)
9897    && ix86_binary_operator_ok (XOR, HImode, operands)"
9898   "xor{w}\t{%2, %0|%0, %2}"
9899   [(set_attr "type" "alu")
9900    (set_attr "mode" "HI")])
9901
9902 (define_insn "*xorhi_3"
9903   [(set (reg FLAGS_REG)
9904         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9905                          (match_operand:HI 2 "general_operand" "g"))
9906                  (const_int 0)))
9907    (clobber (match_scratch:HI 0 "=r"))]
9908   "ix86_match_ccmode (insn, CCNOmode)
9909    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9910   "xor{w}\t{%2, %0|%0, %2}"
9911   [(set_attr "type" "alu")
9912    (set_attr "mode" "HI")])
9913
9914 (define_expand "xorqi3"
9915   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9916         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9917                 (match_operand:QI 2 "general_operand" "")))
9918    (clobber (reg:CC FLAGS_REG))]
9919   "TARGET_QIMODE_MATH"
9920   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9921
9922 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9923 (define_insn "*xorqi_1"
9924   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9925         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9926                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9927    (clobber (reg:CC FLAGS_REG))]
9928   "ix86_binary_operator_ok (XOR, QImode, operands)"
9929   "@
9930    xor{b}\t{%2, %0|%0, %2}
9931    xor{b}\t{%2, %0|%0, %2}
9932    xor{l}\t{%k2, %k0|%k0, %k2}"
9933   [(set_attr "type" "alu")
9934    (set_attr "mode" "QI,QI,SI")])
9935
9936 (define_insn "*xorqi_1_slp"
9937   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9938         (xor:QI (match_dup 0)
9939                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9940    (clobber (reg:CC FLAGS_REG))]
9941   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9942    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9943   "xor{b}\t{%1, %0|%0, %1}"
9944   [(set_attr "type" "alu1")
9945    (set_attr "mode" "QI")])
9946
9947 (define_insn "xorqi_ext_0"
9948   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9949                          (const_int 8)
9950                          (const_int 8))
9951         (xor:SI
9952           (zero_extract:SI
9953             (match_operand 1 "ext_register_operand" "0")
9954             (const_int 8)
9955             (const_int 8))
9956           (match_operand 2 "const_int_operand" "n")))
9957    (clobber (reg:CC FLAGS_REG))]
9958   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9959   "xor{b}\t{%2, %h0|%h0, %2}"
9960   [(set_attr "type" "alu")
9961    (set_attr "length_immediate" "1")
9962    (set_attr "mode" "QI")])
9963
9964 (define_insn "*xorqi_ext_1"
9965   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9966                          (const_int 8)
9967                          (const_int 8))
9968         (xor:SI
9969           (zero_extract:SI
9970             (match_operand 1 "ext_register_operand" "0")
9971             (const_int 8)
9972             (const_int 8))
9973           (zero_extend:SI
9974             (match_operand:QI 2 "general_operand" "Qm"))))
9975    (clobber (reg:CC FLAGS_REG))]
9976   "!TARGET_64BIT
9977    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9978   "xor{b}\t{%2, %h0|%h0, %2}"
9979   [(set_attr "type" "alu")
9980    (set_attr "length_immediate" "0")
9981    (set_attr "mode" "QI")])
9982
9983 (define_insn "*xorqi_ext_1_rex64"
9984   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9985                          (const_int 8)
9986                          (const_int 8))
9987         (xor:SI
9988           (zero_extract:SI
9989             (match_operand 1 "ext_register_operand" "0")
9990             (const_int 8)
9991             (const_int 8))
9992           (zero_extend:SI
9993             (match_operand 2 "ext_register_operand" "Q"))))
9994    (clobber (reg:CC FLAGS_REG))]
9995   "TARGET_64BIT
9996    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9997   "xor{b}\t{%2, %h0|%h0, %2}"
9998   [(set_attr "type" "alu")
9999    (set_attr "length_immediate" "0")
10000    (set_attr "mode" "QI")])
10001
10002 (define_insn "*xorqi_ext_2"
10003   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10004                          (const_int 8)
10005                          (const_int 8))
10006         (xor:SI
10007           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10008                            (const_int 8)
10009                            (const_int 8))
10010           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10011                            (const_int 8)
10012                            (const_int 8))))
10013    (clobber (reg:CC FLAGS_REG))]
10014   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
10015   "xor{b}\t{%h2, %h0|%h0, %h2}"
10016   [(set_attr "type" "alu")
10017    (set_attr "length_immediate" "0")
10018    (set_attr "mode" "QI")])
10019
10020 (define_insn "*xorqi_cc_1"
10021   [(set (reg FLAGS_REG)
10022         (compare
10023           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10024                   (match_operand:QI 2 "general_operand" "qim,qi"))
10025           (const_int 0)))
10026    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10027         (xor:QI (match_dup 1) (match_dup 2)))]
10028   "ix86_match_ccmode (insn, CCNOmode)
10029    && ix86_binary_operator_ok (XOR, QImode, operands)"
10030   "xor{b}\t{%2, %0|%0, %2}"
10031   [(set_attr "type" "alu")
10032    (set_attr "mode" "QI")])
10033
10034 (define_insn "*xorqi_2_slp"
10035   [(set (reg FLAGS_REG)
10036         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10037                          (match_operand:QI 1 "general_operand" "qim,qi"))
10038                  (const_int 0)))
10039    (set (strict_low_part (match_dup 0))
10040         (xor:QI (match_dup 0) (match_dup 1)))]
10041   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
10042    && ix86_match_ccmode (insn, CCNOmode)
10043    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10044   "xor{b}\t{%1, %0|%0, %1}"
10045   [(set_attr "type" "alu1")
10046    (set_attr "mode" "QI")])
10047
10048 (define_insn "*xorqi_cc_2"
10049   [(set (reg FLAGS_REG)
10050         (compare
10051           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10052                   (match_operand:QI 2 "general_operand" "qim"))
10053           (const_int 0)))
10054    (clobber (match_scratch:QI 0 "=q"))]
10055   "ix86_match_ccmode (insn, CCNOmode)
10056    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10057   "xor{b}\t{%2, %0|%0, %2}"
10058   [(set_attr "type" "alu")
10059    (set_attr "mode" "QI")])
10060
10061 (define_insn "*xorqi_cc_ext_1"
10062   [(set (reg FLAGS_REG)
10063         (compare
10064           (xor:SI
10065             (zero_extract:SI
10066               (match_operand 1 "ext_register_operand" "0")
10067               (const_int 8)
10068               (const_int 8))
10069             (match_operand:QI 2 "general_operand" "qmn"))
10070           (const_int 0)))
10071    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10072                          (const_int 8)
10073                          (const_int 8))
10074         (xor:SI
10075           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10076           (match_dup 2)))]
10077   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10078   "xor{b}\t{%2, %h0|%h0, %2}"
10079   [(set_attr "type" "alu")
10080    (set_attr "mode" "QI")])
10081
10082 (define_insn "*xorqi_cc_ext_1_rex64"
10083   [(set (reg FLAGS_REG)
10084         (compare
10085           (xor:SI
10086             (zero_extract:SI
10087               (match_operand 1 "ext_register_operand" "0")
10088               (const_int 8)
10089               (const_int 8))
10090             (match_operand:QI 2 "nonmemory_operand" "Qn"))
10091           (const_int 0)))
10092    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10093                          (const_int 8)
10094                          (const_int 8))
10095         (xor:SI
10096           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10097           (match_dup 2)))]
10098   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10099   "xor{b}\t{%2, %h0|%h0, %2}"
10100   [(set_attr "type" "alu")
10101    (set_attr "mode" "QI")])
10102
10103 (define_expand "xorqi_cc_ext_1"
10104   [(parallel [
10105      (set (reg:CCNO FLAGS_REG)
10106           (compare:CCNO
10107             (xor:SI
10108               (zero_extract:SI
10109                 (match_operand 1 "ext_register_operand" "")
10110                 (const_int 8)
10111                 (const_int 8))
10112               (match_operand:QI 2 "general_operand" ""))
10113             (const_int 0)))
10114      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10115                            (const_int 8)
10116                            (const_int 8))
10117           (xor:SI
10118             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10119             (match_dup 2)))])]
10120   ""
10121   "")
10122
10123 (define_split
10124   [(set (match_operand 0 "register_operand" "")
10125         (xor (match_operand 1 "register_operand" "")
10126              (match_operand 2 "const_int_operand" "")))
10127    (clobber (reg:CC FLAGS_REG))]
10128    "reload_completed
10129     && QI_REG_P (operands[0])
10130     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10131     && !(INTVAL (operands[2]) & ~(255 << 8))
10132     && GET_MODE (operands[0]) != QImode"
10133   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10134                    (xor:SI (zero_extract:SI (match_dup 1)
10135                                             (const_int 8) (const_int 8))
10136                            (match_dup 2)))
10137               (clobber (reg:CC FLAGS_REG))])]
10138   "operands[0] = gen_lowpart (SImode, operands[0]);
10139    operands[1] = gen_lowpart (SImode, operands[1]);
10140    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10141
10142 ;; Since XOR can be encoded with sign extended immediate, this is only
10143 ;; profitable when 7th bit is set.
10144 (define_split
10145   [(set (match_operand 0 "register_operand" "")
10146         (xor (match_operand 1 "general_operand" "")
10147              (match_operand 2 "const_int_operand" "")))
10148    (clobber (reg:CC FLAGS_REG))]
10149    "reload_completed
10150     && ANY_QI_REG_P (operands[0])
10151     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10152     && !(INTVAL (operands[2]) & ~255)
10153     && (INTVAL (operands[2]) & 128)
10154     && GET_MODE (operands[0]) != QImode"
10155   [(parallel [(set (strict_low_part (match_dup 0))
10156                    (xor:QI (match_dup 1)
10157                            (match_dup 2)))
10158               (clobber (reg:CC FLAGS_REG))])]
10159   "operands[0] = gen_lowpart (QImode, operands[0]);
10160    operands[1] = gen_lowpart (QImode, operands[1]);
10161    operands[2] = gen_lowpart (QImode, operands[2]);")
10162 \f
10163 ;; Negation instructions
10164
10165 (define_expand "negti2"
10166   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
10167                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10168               (clobber (reg:CC FLAGS_REG))])]
10169   "TARGET_64BIT"
10170   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10171
10172 (define_insn "*negti2_1"
10173   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10174         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10175    (clobber (reg:CC FLAGS_REG))]
10176   "TARGET_64BIT
10177    && ix86_unary_operator_ok (NEG, TImode, operands)"
10178   "#")
10179
10180 (define_split
10181   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10182         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10183    (clobber (reg:CC FLAGS_REG))]
10184   "TARGET_64BIT && reload_completed"
10185   [(parallel
10186     [(set (reg:CCZ FLAGS_REG)
10187           (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10188      (set (match_dup 0) (neg:DI (match_dup 1)))])
10189    (parallel
10190     [(set (match_dup 2)
10191           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10192                             (match_dup 3))
10193                    (const_int 0)))
10194      (clobber (reg:CC FLAGS_REG))])
10195    (parallel
10196     [(set (match_dup 2)
10197           (neg:DI (match_dup 2)))
10198      (clobber (reg:CC FLAGS_REG))])]
10199   "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10200
10201 (define_expand "negdi2"
10202   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
10203                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
10204               (clobber (reg:CC FLAGS_REG))])]
10205   ""
10206   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10207
10208 (define_insn "*negdi2_1"
10209   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10210         (neg:DI (match_operand:DI 1 "general_operand" "0")))
10211    (clobber (reg:CC FLAGS_REG))]
10212   "!TARGET_64BIT
10213    && ix86_unary_operator_ok (NEG, DImode, operands)"
10214   "#")
10215
10216 (define_split
10217   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10218         (neg:DI (match_operand:DI 1 "general_operand" "")))
10219    (clobber (reg:CC FLAGS_REG))]
10220   "!TARGET_64BIT && reload_completed"
10221   [(parallel
10222     [(set (reg:CCZ FLAGS_REG)
10223           (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10224      (set (match_dup 0) (neg:SI (match_dup 1)))])
10225    (parallel
10226     [(set (match_dup 2)
10227           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10228                             (match_dup 3))
10229                    (const_int 0)))
10230      (clobber (reg:CC FLAGS_REG))])
10231    (parallel
10232     [(set (match_dup 2)
10233           (neg:SI (match_dup 2)))
10234      (clobber (reg:CC FLAGS_REG))])]
10235   "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10236
10237 (define_insn "*negdi2_1_rex64"
10238   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10239         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10240    (clobber (reg:CC FLAGS_REG))]
10241   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10242   "neg{q}\t%0"
10243   [(set_attr "type" "negnot")
10244    (set_attr "mode" "DI")])
10245
10246 ;; The problem with neg is that it does not perform (compare x 0),
10247 ;; it really performs (compare 0 x), which leaves us with the zero
10248 ;; flag being the only useful item.
10249
10250 (define_insn "*negdi2_cmpz_rex64"
10251   [(set (reg:CCZ FLAGS_REG)
10252         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10253                      (const_int 0)))
10254    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10255         (neg:DI (match_dup 1)))]
10256   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10257   "neg{q}\t%0"
10258   [(set_attr "type" "negnot")
10259    (set_attr "mode" "DI")])
10260
10261
10262 (define_expand "negsi2"
10263   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
10264                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
10265               (clobber (reg:CC FLAGS_REG))])]
10266   ""
10267   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10268
10269 (define_insn "*negsi2_1"
10270   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10271         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10272    (clobber (reg:CC FLAGS_REG))]
10273   "ix86_unary_operator_ok (NEG, SImode, operands)"
10274   "neg{l}\t%0"
10275   [(set_attr "type" "negnot")
10276    (set_attr "mode" "SI")])
10277
10278 ;; Combine is quite creative about this pattern.
10279 (define_insn "*negsi2_1_zext"
10280   [(set (match_operand:DI 0 "register_operand" "=r")
10281         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10282                                         (const_int 32)))
10283                      (const_int 32)))
10284    (clobber (reg:CC FLAGS_REG))]
10285   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10286   "neg{l}\t%k0"
10287   [(set_attr "type" "negnot")
10288    (set_attr "mode" "SI")])
10289
10290 ;; The problem with neg is that it does not perform (compare x 0),
10291 ;; it really performs (compare 0 x), which leaves us with the zero
10292 ;; flag being the only useful item.
10293
10294 (define_insn "*negsi2_cmpz"
10295   [(set (reg:CCZ FLAGS_REG)
10296         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10297                      (const_int 0)))
10298    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10299         (neg:SI (match_dup 1)))]
10300   "ix86_unary_operator_ok (NEG, SImode, operands)"
10301   "neg{l}\t%0"
10302   [(set_attr "type" "negnot")
10303    (set_attr "mode" "SI")])
10304
10305 (define_insn "*negsi2_cmpz_zext"
10306   [(set (reg:CCZ FLAGS_REG)
10307         (compare:CCZ (lshiftrt:DI
10308                        (neg:DI (ashift:DI
10309                                  (match_operand:DI 1 "register_operand" "0")
10310                                  (const_int 32)))
10311                        (const_int 32))
10312                      (const_int 0)))
10313    (set (match_operand:DI 0 "register_operand" "=r")
10314         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10315                                         (const_int 32)))
10316                      (const_int 32)))]
10317   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10318   "neg{l}\t%k0"
10319   [(set_attr "type" "negnot")
10320    (set_attr "mode" "SI")])
10321
10322 (define_expand "neghi2"
10323   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
10324                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10325               (clobber (reg:CC FLAGS_REG))])]
10326   "TARGET_HIMODE_MATH"
10327   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10328
10329 (define_insn "*neghi2_1"
10330   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10331         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10332    (clobber (reg:CC FLAGS_REG))]
10333   "ix86_unary_operator_ok (NEG, HImode, operands)"
10334   "neg{w}\t%0"
10335   [(set_attr "type" "negnot")
10336    (set_attr "mode" "HI")])
10337
10338 (define_insn "*neghi2_cmpz"
10339   [(set (reg:CCZ FLAGS_REG)
10340         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10341                      (const_int 0)))
10342    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10343         (neg:HI (match_dup 1)))]
10344   "ix86_unary_operator_ok (NEG, HImode, operands)"
10345   "neg{w}\t%0"
10346   [(set_attr "type" "negnot")
10347    (set_attr "mode" "HI")])
10348
10349 (define_expand "negqi2"
10350   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10351                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10352               (clobber (reg:CC FLAGS_REG))])]
10353   "TARGET_QIMODE_MATH"
10354   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10355
10356 (define_insn "*negqi2_1"
10357   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10358         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10359    (clobber (reg:CC FLAGS_REG))]
10360   "ix86_unary_operator_ok (NEG, QImode, operands)"
10361   "neg{b}\t%0"
10362   [(set_attr "type" "negnot")
10363    (set_attr "mode" "QI")])
10364
10365 (define_insn "*negqi2_cmpz"
10366   [(set (reg:CCZ FLAGS_REG)
10367         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10368                      (const_int 0)))
10369    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10370         (neg:QI (match_dup 1)))]
10371   "ix86_unary_operator_ok (NEG, QImode, operands)"
10372   "neg{b}\t%0"
10373   [(set_attr "type" "negnot")
10374    (set_attr "mode" "QI")])
10375
10376 ;; Changing of sign for FP values is doable using integer unit too.
10377
10378 (define_expand "<code><mode>2"
10379   [(set (match_operand:X87MODEF 0 "register_operand" "")
10380         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10381   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10382   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10383
10384 (define_insn "*absneg<mode>2_mixed"
10385   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10386         (match_operator:MODEF 3 "absneg_operator"
10387           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10388    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10389    (clobber (reg:CC FLAGS_REG))]
10390   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10391   "#")
10392
10393 (define_insn "*absneg<mode>2_sse"
10394   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10395         (match_operator:MODEF 3 "absneg_operator"
10396           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10397    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10398    (clobber (reg:CC FLAGS_REG))]
10399   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10400   "#")
10401
10402 (define_insn "*absneg<mode>2_i387"
10403   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10404         (match_operator:X87MODEF 3 "absneg_operator"
10405           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10406    (use (match_operand 2 "" ""))
10407    (clobber (reg:CC FLAGS_REG))]
10408   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10409   "#")
10410
10411 (define_expand "<code>tf2"
10412   [(set (match_operand:TF 0 "register_operand" "")
10413         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10414   "TARGET_64BIT"
10415   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10416
10417 (define_insn "*absnegtf2_sse"
10418   [(set (match_operand:TF 0 "register_operand" "=x,x")
10419         (match_operator:TF 3 "absneg_operator"
10420           [(match_operand:TF 1 "register_operand" "0,x")]))
10421    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10422    (clobber (reg:CC FLAGS_REG))]
10423   "TARGET_64BIT"
10424   "#")
10425
10426 ;; Splitters for fp abs and neg.
10427
10428 (define_split
10429   [(set (match_operand 0 "fp_register_operand" "")
10430         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10431    (use (match_operand 2 "" ""))
10432    (clobber (reg:CC FLAGS_REG))]
10433   "reload_completed"
10434   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10435
10436 (define_split
10437   [(set (match_operand 0 "register_operand" "")
10438         (match_operator 3 "absneg_operator"
10439           [(match_operand 1 "register_operand" "")]))
10440    (use (match_operand 2 "nonimmediate_operand" ""))
10441    (clobber (reg:CC FLAGS_REG))]
10442   "reload_completed && SSE_REG_P (operands[0])"
10443   [(set (match_dup 0) (match_dup 3))]
10444 {
10445   enum machine_mode mode = GET_MODE (operands[0]);
10446   enum machine_mode vmode = GET_MODE (operands[2]);
10447   rtx tmp;
10448
10449   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10450   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10451   if (operands_match_p (operands[0], operands[2]))
10452     {
10453       tmp = operands[1];
10454       operands[1] = operands[2];
10455       operands[2] = tmp;
10456     }
10457   if (GET_CODE (operands[3]) == ABS)
10458     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10459   else
10460     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10461   operands[3] = tmp;
10462 })
10463
10464 (define_split
10465   [(set (match_operand:SF 0 "register_operand" "")
10466         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10467    (use (match_operand:V4SF 2 "" ""))
10468    (clobber (reg:CC FLAGS_REG))]
10469   "reload_completed"
10470   [(parallel [(set (match_dup 0) (match_dup 1))
10471               (clobber (reg:CC FLAGS_REG))])]
10472 {
10473   rtx tmp;
10474   operands[0] = gen_lowpart (SImode, operands[0]);
10475   if (GET_CODE (operands[1]) == ABS)
10476     {
10477       tmp = gen_int_mode (0x7fffffff, SImode);
10478       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10479     }
10480   else
10481     {
10482       tmp = gen_int_mode (0x80000000, SImode);
10483       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10484     }
10485   operands[1] = tmp;
10486 })
10487
10488 (define_split
10489   [(set (match_operand:DF 0 "register_operand" "")
10490         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10491    (use (match_operand 2 "" ""))
10492    (clobber (reg:CC FLAGS_REG))]
10493   "reload_completed"
10494   [(parallel [(set (match_dup 0) (match_dup 1))
10495               (clobber (reg:CC FLAGS_REG))])]
10496 {
10497   rtx tmp;
10498   if (TARGET_64BIT)
10499     {
10500       tmp = gen_lowpart (DImode, operands[0]);
10501       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10502       operands[0] = tmp;
10503
10504       if (GET_CODE (operands[1]) == ABS)
10505         tmp = const0_rtx;
10506       else
10507         tmp = gen_rtx_NOT (DImode, tmp);
10508     }
10509   else
10510     {
10511       operands[0] = gen_highpart (SImode, operands[0]);
10512       if (GET_CODE (operands[1]) == ABS)
10513         {
10514           tmp = gen_int_mode (0x7fffffff, SImode);
10515           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10516         }
10517       else
10518         {
10519           tmp = gen_int_mode (0x80000000, SImode);
10520           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10521         }
10522     }
10523   operands[1] = tmp;
10524 })
10525
10526 (define_split
10527   [(set (match_operand:XF 0 "register_operand" "")
10528         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10529    (use (match_operand 2 "" ""))
10530    (clobber (reg:CC FLAGS_REG))]
10531   "reload_completed"
10532   [(parallel [(set (match_dup 0) (match_dup 1))
10533               (clobber (reg:CC FLAGS_REG))])]
10534 {
10535   rtx tmp;
10536   operands[0] = gen_rtx_REG (SImode,
10537                              true_regnum (operands[0])
10538                              + (TARGET_64BIT ? 1 : 2));
10539   if (GET_CODE (operands[1]) == ABS)
10540     {
10541       tmp = GEN_INT (0x7fff);
10542       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10543     }
10544   else
10545     {
10546       tmp = GEN_INT (0x8000);
10547       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10548     }
10549   operands[1] = tmp;
10550 })
10551
10552 ;; Conditionalize these after reload. If they match before reload, we
10553 ;; lose the clobber and ability to use integer instructions.
10554
10555 (define_insn "*<code><mode>2_1"
10556   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10557         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10558   "TARGET_80387
10559    && (reload_completed
10560        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10561   "f<absnegprefix>"
10562   [(set_attr "type" "fsgn")
10563    (set_attr "mode" "<MODE>")])
10564
10565 (define_insn "*<code>extendsfdf2"
10566   [(set (match_operand:DF 0 "register_operand" "=f")
10567         (absneg:DF (float_extend:DF
10568                      (match_operand:SF 1 "register_operand" "0"))))]
10569   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10570   "f<absnegprefix>"
10571   [(set_attr "type" "fsgn")
10572    (set_attr "mode" "DF")])
10573
10574 (define_insn "*<code>extendsfxf2"
10575   [(set (match_operand:XF 0 "register_operand" "=f")
10576         (absneg:XF (float_extend:XF
10577                      (match_operand:SF 1 "register_operand" "0"))))]
10578   "TARGET_80387"
10579   "f<absnegprefix>"
10580   [(set_attr "type" "fsgn")
10581    (set_attr "mode" "XF")])
10582
10583 (define_insn "*<code>extenddfxf2"
10584   [(set (match_operand:XF 0 "register_operand" "=f")
10585         (absneg:XF (float_extend:XF
10586                       (match_operand:DF 1 "register_operand" "0"))))]
10587   "TARGET_80387"
10588   "f<absnegprefix>"
10589   [(set_attr "type" "fsgn")
10590    (set_attr "mode" "XF")])
10591
10592 ;; Copysign instructions
10593
10594 (define_mode_iterator CSGNMODE [SF DF TF])
10595 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10596
10597 (define_expand "copysign<mode>3"
10598   [(match_operand:CSGNMODE 0 "register_operand" "")
10599    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10600    (match_operand:CSGNMODE 2 "register_operand" "")]
10601   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10602    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10603 {
10604   ix86_expand_copysign (operands);
10605   DONE;
10606 })
10607
10608 (define_insn_and_split "copysign<mode>3_const"
10609   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10610         (unspec:CSGNMODE
10611           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10612            (match_operand:CSGNMODE 2 "register_operand" "0")
10613            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10614           UNSPEC_COPYSIGN))]
10615   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10616    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10617   "#"
10618   "&& reload_completed"
10619   [(const_int 0)]
10620 {
10621   ix86_split_copysign_const (operands);
10622   DONE;
10623 })
10624
10625 (define_insn "copysign<mode>3_var"
10626   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10627         (unspec:CSGNMODE
10628           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10629            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10630            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10631            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10632           UNSPEC_COPYSIGN))
10633    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10634   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10635    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10636   "#")
10637
10638 (define_split
10639   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10640         (unspec:CSGNMODE
10641           [(match_operand:CSGNMODE 2 "register_operand" "")
10642            (match_operand:CSGNMODE 3 "register_operand" "")
10643            (match_operand:<CSGNVMODE> 4 "" "")
10644            (match_operand:<CSGNVMODE> 5 "" "")]
10645           UNSPEC_COPYSIGN))
10646    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10647   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10648     || (TARGET_64BIT && (<MODE>mode == TFmode)))
10649    && reload_completed"
10650   [(const_int 0)]
10651 {
10652   ix86_split_copysign_var (operands);
10653   DONE;
10654 })
10655 \f
10656 ;; One complement instructions
10657
10658 (define_expand "one_cmpldi2"
10659   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10660         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10661   "TARGET_64BIT"
10662   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10663
10664 (define_insn "*one_cmpldi2_1_rex64"
10665   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10666         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10667   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10668   "not{q}\t%0"
10669   [(set_attr "type" "negnot")
10670    (set_attr "mode" "DI")])
10671
10672 (define_insn "*one_cmpldi2_2_rex64"
10673   [(set (reg FLAGS_REG)
10674         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10675                  (const_int 0)))
10676    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10677         (not:DI (match_dup 1)))]
10678   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10679    && ix86_unary_operator_ok (NOT, DImode, operands)"
10680   "#"
10681   [(set_attr "type" "alu1")
10682    (set_attr "mode" "DI")])
10683
10684 (define_split
10685   [(set (match_operand 0 "flags_reg_operand" "")
10686         (match_operator 2 "compare_operator"
10687           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10688            (const_int 0)]))
10689    (set (match_operand:DI 1 "nonimmediate_operand" "")
10690         (not:DI (match_dup 3)))]
10691   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10692   [(parallel [(set (match_dup 0)
10693                    (match_op_dup 2
10694                      [(xor:DI (match_dup 3) (const_int -1))
10695                       (const_int 0)]))
10696               (set (match_dup 1)
10697                    (xor:DI (match_dup 3) (const_int -1)))])]
10698   "")
10699
10700 (define_expand "one_cmplsi2"
10701   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10702         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10703   ""
10704   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10705
10706 (define_insn "*one_cmplsi2_1"
10707   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10708         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10709   "ix86_unary_operator_ok (NOT, SImode, operands)"
10710   "not{l}\t%0"
10711   [(set_attr "type" "negnot")
10712    (set_attr "mode" "SI")])
10713
10714 ;; ??? Currently never generated - xor is used instead.
10715 (define_insn "*one_cmplsi2_1_zext"
10716   [(set (match_operand:DI 0 "register_operand" "=r")
10717         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10718   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10719   "not{l}\t%k0"
10720   [(set_attr "type" "negnot")
10721    (set_attr "mode" "SI")])
10722
10723 (define_insn "*one_cmplsi2_2"
10724   [(set (reg FLAGS_REG)
10725         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10726                  (const_int 0)))
10727    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10728         (not:SI (match_dup 1)))]
10729   "ix86_match_ccmode (insn, CCNOmode)
10730    && ix86_unary_operator_ok (NOT, SImode, operands)"
10731   "#"
10732   [(set_attr "type" "alu1")
10733    (set_attr "mode" "SI")])
10734
10735 (define_split
10736   [(set (match_operand 0 "flags_reg_operand" "")
10737         (match_operator 2 "compare_operator"
10738           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10739            (const_int 0)]))
10740    (set (match_operand:SI 1 "nonimmediate_operand" "")
10741         (not:SI (match_dup 3)))]
10742   "ix86_match_ccmode (insn, CCNOmode)"
10743   [(parallel [(set (match_dup 0)
10744                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10745                                     (const_int 0)]))
10746               (set (match_dup 1)
10747                    (xor:SI (match_dup 3) (const_int -1)))])]
10748   "")
10749
10750 ;; ??? Currently never generated - xor is used instead.
10751 (define_insn "*one_cmplsi2_2_zext"
10752   [(set (reg FLAGS_REG)
10753         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10754                  (const_int 0)))
10755    (set (match_operand:DI 0 "register_operand" "=r")
10756         (zero_extend:DI (not:SI (match_dup 1))))]
10757   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10758    && ix86_unary_operator_ok (NOT, SImode, operands)"
10759   "#"
10760   [(set_attr "type" "alu1")
10761    (set_attr "mode" "SI")])
10762
10763 (define_split
10764   [(set (match_operand 0 "flags_reg_operand" "")
10765         (match_operator 2 "compare_operator"
10766           [(not:SI (match_operand:SI 3 "register_operand" ""))
10767            (const_int 0)]))
10768    (set (match_operand:DI 1 "register_operand" "")
10769         (zero_extend:DI (not:SI (match_dup 3))))]
10770   "ix86_match_ccmode (insn, CCNOmode)"
10771   [(parallel [(set (match_dup 0)
10772                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10773                                     (const_int 0)]))
10774               (set (match_dup 1)
10775                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10776   "")
10777
10778 (define_expand "one_cmplhi2"
10779   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10780         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10781   "TARGET_HIMODE_MATH"
10782   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10783
10784 (define_insn "*one_cmplhi2_1"
10785   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10786         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10787   "ix86_unary_operator_ok (NOT, HImode, operands)"
10788   "not{w}\t%0"
10789   [(set_attr "type" "negnot")
10790    (set_attr "mode" "HI")])
10791
10792 (define_insn "*one_cmplhi2_2"
10793   [(set (reg FLAGS_REG)
10794         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10795                  (const_int 0)))
10796    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10797         (not:HI (match_dup 1)))]
10798   "ix86_match_ccmode (insn, CCNOmode)
10799    && ix86_unary_operator_ok (NEG, HImode, operands)"
10800   "#"
10801   [(set_attr "type" "alu1")
10802    (set_attr "mode" "HI")])
10803
10804 (define_split
10805   [(set (match_operand 0 "flags_reg_operand" "")
10806         (match_operator 2 "compare_operator"
10807           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10808            (const_int 0)]))
10809    (set (match_operand:HI 1 "nonimmediate_operand" "")
10810         (not:HI (match_dup 3)))]
10811   "ix86_match_ccmode (insn, CCNOmode)"
10812   [(parallel [(set (match_dup 0)
10813                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10814                                     (const_int 0)]))
10815               (set (match_dup 1)
10816                    (xor:HI (match_dup 3) (const_int -1)))])]
10817   "")
10818
10819 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10820 (define_expand "one_cmplqi2"
10821   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10822         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10823   "TARGET_QIMODE_MATH"
10824   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10825
10826 (define_insn "*one_cmplqi2_1"
10827   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10828         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10829   "ix86_unary_operator_ok (NOT, QImode, operands)"
10830   "@
10831    not{b}\t%0
10832    not{l}\t%k0"
10833   [(set_attr "type" "negnot")
10834    (set_attr "mode" "QI,SI")])
10835
10836 (define_insn "*one_cmplqi2_2"
10837   [(set (reg FLAGS_REG)
10838         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10839                  (const_int 0)))
10840    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10841         (not:QI (match_dup 1)))]
10842   "ix86_match_ccmode (insn, CCNOmode)
10843    && ix86_unary_operator_ok (NOT, QImode, operands)"
10844   "#"
10845   [(set_attr "type" "alu1")
10846    (set_attr "mode" "QI")])
10847
10848 (define_split
10849   [(set (match_operand 0 "flags_reg_operand" "")
10850         (match_operator 2 "compare_operator"
10851           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10852            (const_int 0)]))
10853    (set (match_operand:QI 1 "nonimmediate_operand" "")
10854         (not:QI (match_dup 3)))]
10855   "ix86_match_ccmode (insn, CCNOmode)"
10856   [(parallel [(set (match_dup 0)
10857                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10858                                     (const_int 0)]))
10859               (set (match_dup 1)
10860                    (xor:QI (match_dup 3) (const_int -1)))])]
10861   "")
10862 \f
10863 ;; Arithmetic shift instructions
10864
10865 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10866 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10867 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10868 ;; from the assembler input.
10869 ;;
10870 ;; This instruction shifts the target reg/mem as usual, but instead of
10871 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10872 ;; is a left shift double, bits are taken from the high order bits of
10873 ;; reg, else if the insn is a shift right double, bits are taken from the
10874 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10875 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10876 ;;
10877 ;; Since sh[lr]d does not change the `reg' operand, that is done
10878 ;; separately, making all shifts emit pairs of shift double and normal
10879 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10880 ;; support a 63 bit shift, each shift where the count is in a reg expands
10881 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10882 ;;
10883 ;; If the shift count is a constant, we need never emit more than one
10884 ;; shift pair, instead using moves and sign extension for counts greater
10885 ;; than 31.
10886
10887 (define_expand "ashlti3"
10888   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10889                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10890                               (match_operand:QI 2 "nonmemory_operand" "")))
10891               (clobber (reg:CC FLAGS_REG))])]
10892   "TARGET_64BIT"
10893 {
10894   if (! immediate_operand (operands[2], QImode))
10895     {
10896       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10897       DONE;
10898     }
10899   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10900   DONE;
10901 })
10902
10903 (define_insn "ashlti3_1"
10904   [(set (match_operand:TI 0 "register_operand" "=r")
10905         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10906                    (match_operand:QI 2 "register_operand" "c")))
10907    (clobber (match_scratch:DI 3 "=&r"))
10908    (clobber (reg:CC FLAGS_REG))]
10909   "TARGET_64BIT"
10910   "#"
10911   [(set_attr "type" "multi")])
10912
10913 ;; This pattern must be defined before *ashlti3_2 to prevent
10914 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10915
10916 (define_insn "sse2_ashlti3"
10917   [(set (match_operand:TI 0 "register_operand" "=x")
10918         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10919                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10920   "TARGET_SSE2"
10921 {
10922   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10923   return "pslldq\t{%2, %0|%0, %2}";
10924 }
10925   [(set_attr "type" "sseishft")
10926    (set_attr "prefix_data16" "1")
10927    (set_attr "mode" "TI")])
10928
10929 (define_insn "*ashlti3_2"
10930   [(set (match_operand:TI 0 "register_operand" "=r")
10931         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10932                    (match_operand:QI 2 "immediate_operand" "O")))
10933    (clobber (reg:CC FLAGS_REG))]
10934   "TARGET_64BIT"
10935   "#"
10936   [(set_attr "type" "multi")])
10937
10938 (define_split
10939   [(set (match_operand:TI 0 "register_operand" "")
10940         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10941                    (match_operand:QI 2 "register_operand" "")))
10942    (clobber (match_scratch:DI 3 ""))
10943    (clobber (reg:CC FLAGS_REG))]
10944   "TARGET_64BIT && reload_completed"
10945   [(const_int 0)]
10946   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10947
10948 (define_split
10949   [(set (match_operand:TI 0 "register_operand" "")
10950         (ashift:TI (match_operand:TI 1 "register_operand" "")
10951                    (match_operand:QI 2 "immediate_operand" "")))
10952    (clobber (reg:CC FLAGS_REG))]
10953   "TARGET_64BIT && reload_completed"
10954   [(const_int 0)]
10955   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10956
10957 (define_insn "x86_64_shld"
10958   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10959         (ior:DI (ashift:DI (match_dup 0)
10960                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10961                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10962                   (minus:QI (const_int 64) (match_dup 2)))))
10963    (clobber (reg:CC FLAGS_REG))]
10964   "TARGET_64BIT"
10965   "@
10966    shld{q}\t{%2, %1, %0|%0, %1, %2}
10967    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10968   [(set_attr "type" "ishift")
10969    (set_attr "prefix_0f" "1")
10970    (set_attr "mode" "DI")
10971    (set_attr "athlon_decode" "vector")
10972    (set_attr "amdfam10_decode" "vector")])
10973
10974 (define_expand "x86_64_shift_adj"
10975   [(set (reg:CCZ FLAGS_REG)
10976         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10977                              (const_int 64))
10978                      (const_int 0)))
10979    (set (match_operand:DI 0 "register_operand" "")
10980         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10981                          (match_operand:DI 1 "register_operand" "")
10982                          (match_dup 0)))
10983    (set (match_dup 1)
10984         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10985                          (match_operand:DI 3 "register_operand" "r")
10986                          (match_dup 1)))]
10987   "TARGET_64BIT"
10988   "")
10989
10990 (define_expand "ashldi3"
10991   [(set (match_operand:DI 0 "shiftdi_operand" "")
10992         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10993                    (match_operand:QI 2 "nonmemory_operand" "")))]
10994   ""
10995   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10996
10997 (define_insn "*ashldi3_1_rex64"
10998   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10999         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11000                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11001    (clobber (reg:CC FLAGS_REG))]
11002   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11003 {
11004   switch (get_attr_type (insn))
11005     {
11006     case TYPE_ALU:
11007       gcc_assert (operands[2] == const1_rtx);
11008       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11009       return "add{q}\t%0, %0";
11010
11011     case TYPE_LEA:
11012       gcc_assert (CONST_INT_P (operands[2]));
11013       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11014       operands[1] = gen_rtx_MULT (DImode, operands[1],
11015                                   GEN_INT (1 << INTVAL (operands[2])));
11016       return "lea{q}\t{%a1, %0|%0, %a1}";
11017
11018     default:
11019       if (REG_P (operands[2]))
11020         return "sal{q}\t{%b2, %0|%0, %b2}";
11021       else if (operands[2] == const1_rtx
11022                && (TARGET_SHIFT1 || optimize_size))
11023         return "sal{q}\t%0";
11024       else
11025         return "sal{q}\t{%2, %0|%0, %2}";
11026     }
11027 }
11028   [(set (attr "type")
11029      (cond [(eq_attr "alternative" "1")
11030               (const_string "lea")
11031             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11032                           (const_int 0))
11033                       (match_operand 0 "register_operand" ""))
11034                  (match_operand 2 "const1_operand" ""))
11035               (const_string "alu")
11036            ]
11037            (const_string "ishift")))
11038    (set_attr "mode" "DI")])
11039
11040 ;; Convert lea to the lea pattern to avoid flags dependency.
11041 (define_split
11042   [(set (match_operand:DI 0 "register_operand" "")
11043         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11044                    (match_operand:QI 2 "immediate_operand" "")))
11045    (clobber (reg:CC FLAGS_REG))]
11046   "TARGET_64BIT && reload_completed
11047    && true_regnum (operands[0]) != true_regnum (operands[1])"
11048   [(set (match_dup 0)
11049         (mult:DI (match_dup 1)
11050                  (match_dup 2)))]
11051   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11052
11053 ;; This pattern can't accept a variable shift count, since shifts by
11054 ;; zero don't affect the flags.  We assume that shifts by constant
11055 ;; zero are optimized away.
11056 (define_insn "*ashldi3_cmp_rex64"
11057   [(set (reg FLAGS_REG)
11058         (compare
11059           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11060                      (match_operand:QI 2 "immediate_operand" "e"))
11061           (const_int 0)))
11062    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11063         (ashift:DI (match_dup 1) (match_dup 2)))]
11064   "TARGET_64BIT
11065    && (optimize_size
11066        || !TARGET_PARTIAL_FLAG_REG_STALL
11067        || (operands[2] == const1_rtx
11068            && (TARGET_SHIFT1
11069                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11070    && ix86_match_ccmode (insn, CCGOCmode)
11071    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11072 {
11073   switch (get_attr_type (insn))
11074     {
11075     case TYPE_ALU:
11076       gcc_assert (operands[2] == const1_rtx);
11077       return "add{q}\t%0, %0";
11078
11079     default:
11080       if (REG_P (operands[2]))
11081         return "sal{q}\t{%b2, %0|%0, %b2}";
11082       else if (operands[2] == const1_rtx
11083                && (TARGET_SHIFT1 || optimize_size))
11084         return "sal{q}\t%0";
11085       else
11086         return "sal{q}\t{%2, %0|%0, %2}";
11087     }
11088 }
11089   [(set (attr "type")
11090      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11091                           (const_int 0))
11092                       (match_operand 0 "register_operand" ""))
11093                  (match_operand 2 "const1_operand" ""))
11094               (const_string "alu")
11095            ]
11096            (const_string "ishift")))
11097    (set_attr "mode" "DI")])
11098
11099 (define_insn "*ashldi3_cconly_rex64"
11100   [(set (reg FLAGS_REG)
11101         (compare
11102           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11103                      (match_operand:QI 2 "immediate_operand" "e"))
11104           (const_int 0)))
11105    (clobber (match_scratch:DI 0 "=r"))]
11106   "TARGET_64BIT
11107    && (optimize_size
11108        || !TARGET_PARTIAL_FLAG_REG_STALL
11109        || (operands[2] == const1_rtx
11110            && (TARGET_SHIFT1
11111                || TARGET_DOUBLE_WITH_ADD)))
11112    && ix86_match_ccmode (insn, CCGOCmode)
11113    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11114 {
11115   switch (get_attr_type (insn))
11116     {
11117     case TYPE_ALU:
11118       gcc_assert (operands[2] == const1_rtx);
11119       return "add{q}\t%0, %0";
11120
11121     default:
11122       if (REG_P (operands[2]))
11123         return "sal{q}\t{%b2, %0|%0, %b2}";
11124       else if (operands[2] == const1_rtx
11125                && (TARGET_SHIFT1 || optimize_size))
11126         return "sal{q}\t%0";
11127       else
11128         return "sal{q}\t{%2, %0|%0, %2}";
11129     }
11130 }
11131   [(set (attr "type")
11132      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11133                           (const_int 0))
11134                       (match_operand 0 "register_operand" ""))
11135                  (match_operand 2 "const1_operand" ""))
11136               (const_string "alu")
11137            ]
11138            (const_string "ishift")))
11139    (set_attr "mode" "DI")])
11140
11141 (define_insn "*ashldi3_1"
11142   [(set (match_operand:DI 0 "register_operand" "=&r,r")
11143         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11144                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11145    (clobber (reg:CC FLAGS_REG))]
11146   "!TARGET_64BIT"
11147   "#"
11148   [(set_attr "type" "multi")])
11149
11150 ;; By default we don't ask for a scratch register, because when DImode
11151 ;; values are manipulated, registers are already at a premium.  But if
11152 ;; we have one handy, we won't turn it away.
11153 (define_peephole2
11154   [(match_scratch:SI 3 "r")
11155    (parallel [(set (match_operand:DI 0 "register_operand" "")
11156                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11157                               (match_operand:QI 2 "nonmemory_operand" "")))
11158               (clobber (reg:CC FLAGS_REG))])
11159    (match_dup 3)]
11160   "!TARGET_64BIT && TARGET_CMOVE"
11161   [(const_int 0)]
11162   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11163
11164 (define_split
11165   [(set (match_operand:DI 0 "register_operand" "")
11166         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11167                    (match_operand:QI 2 "nonmemory_operand" "")))
11168    (clobber (reg:CC FLAGS_REG))]
11169   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11170                      ? epilogue_completed : reload_completed)"
11171   [(const_int 0)]
11172   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11173
11174 (define_insn "x86_shld_1"
11175   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11176         (ior:SI (ashift:SI (match_dup 0)
11177                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11178                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11179                   (minus:QI (const_int 32) (match_dup 2)))))
11180    (clobber (reg:CC FLAGS_REG))]
11181   ""
11182   "@
11183    shld{l}\t{%2, %1, %0|%0, %1, %2}
11184    shld{l}\t{%s2%1, %0|%0, %1, %2}"
11185   [(set_attr "type" "ishift")
11186    (set_attr "prefix_0f" "1")
11187    (set_attr "mode" "SI")
11188    (set_attr "pent_pair" "np")
11189    (set_attr "athlon_decode" "vector")
11190    (set_attr "amdfam10_decode" "vector")])
11191
11192 (define_expand "x86_shift_adj_1"
11193   [(set (reg:CCZ FLAGS_REG)
11194         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11195                              (const_int 32))
11196                      (const_int 0)))
11197    (set (match_operand:SI 0 "register_operand" "")
11198         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11199                          (match_operand:SI 1 "register_operand" "")
11200                          (match_dup 0)))
11201    (set (match_dup 1)
11202         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11203                          (match_operand:SI 3 "register_operand" "r")
11204                          (match_dup 1)))]
11205   "TARGET_CMOVE"
11206   "")
11207
11208 (define_expand "x86_shift_adj_2"
11209   [(use (match_operand:SI 0 "register_operand" ""))
11210    (use (match_operand:SI 1 "register_operand" ""))
11211    (use (match_operand:QI 2 "register_operand" ""))]
11212   ""
11213 {
11214   rtx label = gen_label_rtx ();
11215   rtx tmp;
11216
11217   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11218
11219   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11220   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11221   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11222                               gen_rtx_LABEL_REF (VOIDmode, label),
11223                               pc_rtx);
11224   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11225   JUMP_LABEL (tmp) = label;
11226
11227   emit_move_insn (operands[0], operands[1]);
11228   ix86_expand_clear (operands[1]);
11229
11230   emit_label (label);
11231   LABEL_NUSES (label) = 1;
11232
11233   DONE;
11234 })
11235
11236 (define_expand "ashlsi3"
11237   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11238         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11239                    (match_operand:QI 2 "nonmemory_operand" "")))
11240    (clobber (reg:CC FLAGS_REG))]
11241   ""
11242   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11243
11244 (define_insn "*ashlsi3_1"
11245   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11246         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11247                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11248    (clobber (reg:CC FLAGS_REG))]
11249   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11250 {
11251   switch (get_attr_type (insn))
11252     {
11253     case TYPE_ALU:
11254       gcc_assert (operands[2] == const1_rtx);
11255       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11256       return "add{l}\t%0, %0";
11257
11258     case TYPE_LEA:
11259       return "#";
11260
11261     default:
11262       if (REG_P (operands[2]))
11263         return "sal{l}\t{%b2, %0|%0, %b2}";
11264       else if (operands[2] == const1_rtx
11265                && (TARGET_SHIFT1 || optimize_size))
11266         return "sal{l}\t%0";
11267       else
11268         return "sal{l}\t{%2, %0|%0, %2}";
11269     }
11270 }
11271   [(set (attr "type")
11272      (cond [(eq_attr "alternative" "1")
11273               (const_string "lea")
11274             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11275                           (const_int 0))
11276                       (match_operand 0 "register_operand" ""))
11277                  (match_operand 2 "const1_operand" ""))
11278               (const_string "alu")
11279            ]
11280            (const_string "ishift")))
11281    (set_attr "mode" "SI")])
11282
11283 ;; Convert lea to the lea pattern to avoid flags dependency.
11284 (define_split
11285   [(set (match_operand 0 "register_operand" "")
11286         (ashift (match_operand 1 "index_register_operand" "")
11287                 (match_operand:QI 2 "const_int_operand" "")))
11288    (clobber (reg:CC FLAGS_REG))]
11289   "reload_completed
11290    && true_regnum (operands[0]) != true_regnum (operands[1])
11291    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11292   [(const_int 0)]
11293 {
11294   rtx pat;
11295   enum machine_mode mode = GET_MODE (operands[0]);
11296
11297   if (GET_MODE_SIZE (mode) < 4)
11298     operands[0] = gen_lowpart (SImode, operands[0]);
11299   if (mode != Pmode)
11300     operands[1] = gen_lowpart (Pmode, operands[1]);
11301   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11302
11303   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11304   if (Pmode != SImode)
11305     pat = gen_rtx_SUBREG (SImode, pat, 0);
11306   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11307   DONE;
11308 })
11309
11310 ;; Rare case of shifting RSP is handled by generating move and shift
11311 (define_split
11312   [(set (match_operand 0 "register_operand" "")
11313         (ashift (match_operand 1 "register_operand" "")
11314                 (match_operand:QI 2 "const_int_operand" "")))
11315    (clobber (reg:CC FLAGS_REG))]
11316   "reload_completed
11317    && true_regnum (operands[0]) != true_regnum (operands[1])"
11318   [(const_int 0)]
11319 {
11320   rtx pat, clob;
11321   emit_move_insn (operands[0], operands[1]);
11322   pat = gen_rtx_SET (VOIDmode, operands[0],
11323                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11324                                      operands[0], operands[2]));
11325   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11326   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11327   DONE;
11328 })
11329
11330 (define_insn "*ashlsi3_1_zext"
11331   [(set (match_operand:DI 0 "register_operand" "=r,r")
11332         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11333                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11334    (clobber (reg:CC FLAGS_REG))]
11335   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11336 {
11337   switch (get_attr_type (insn))
11338     {
11339     case TYPE_ALU:
11340       gcc_assert (operands[2] == const1_rtx);
11341       return "add{l}\t%k0, %k0";
11342
11343     case TYPE_LEA:
11344       return "#";
11345
11346     default:
11347       if (REG_P (operands[2]))
11348         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11349       else if (operands[2] == const1_rtx
11350                && (TARGET_SHIFT1 || optimize_size))
11351         return "sal{l}\t%k0";
11352       else
11353         return "sal{l}\t{%2, %k0|%k0, %2}";
11354     }
11355 }
11356   [(set (attr "type")
11357      (cond [(eq_attr "alternative" "1")
11358               (const_string "lea")
11359             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11360                      (const_int 0))
11361                  (match_operand 2 "const1_operand" ""))
11362               (const_string "alu")
11363            ]
11364            (const_string "ishift")))
11365    (set_attr "mode" "SI")])
11366
11367 ;; Convert lea to the lea pattern to avoid flags dependency.
11368 (define_split
11369   [(set (match_operand:DI 0 "register_operand" "")
11370         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11371                                 (match_operand:QI 2 "const_int_operand" ""))))
11372    (clobber (reg:CC FLAGS_REG))]
11373   "TARGET_64BIT && reload_completed
11374    && true_regnum (operands[0]) != true_regnum (operands[1])"
11375   [(set (match_dup 0) (zero_extend:DI
11376                         (subreg:SI (mult:SI (match_dup 1)
11377                                             (match_dup 2)) 0)))]
11378 {
11379   operands[1] = gen_lowpart (Pmode, operands[1]);
11380   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11381 })
11382
11383 ;; This pattern can't accept a variable shift count, since shifts by
11384 ;; zero don't affect the flags.  We assume that shifts by constant
11385 ;; zero are optimized away.
11386 (define_insn "*ashlsi3_cmp"
11387   [(set (reg FLAGS_REG)
11388         (compare
11389           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11390                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11391           (const_int 0)))
11392    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11393         (ashift:SI (match_dup 1) (match_dup 2)))]
11394    "(optimize_size
11395      || !TARGET_PARTIAL_FLAG_REG_STALL
11396      || (operands[2] == const1_rtx
11397          && (TARGET_SHIFT1
11398              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11399    && ix86_match_ccmode (insn, CCGOCmode)
11400    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11401 {
11402   switch (get_attr_type (insn))
11403     {
11404     case TYPE_ALU:
11405       gcc_assert (operands[2] == const1_rtx);
11406       return "add{l}\t%0, %0";
11407
11408     default:
11409       if (REG_P (operands[2]))
11410         return "sal{l}\t{%b2, %0|%0, %b2}";
11411       else if (operands[2] == const1_rtx
11412                && (TARGET_SHIFT1 || optimize_size))
11413         return "sal{l}\t%0";
11414       else
11415         return "sal{l}\t{%2, %0|%0, %2}";
11416     }
11417 }
11418   [(set (attr "type")
11419      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11420                           (const_int 0))
11421                       (match_operand 0 "register_operand" ""))
11422                  (match_operand 2 "const1_operand" ""))
11423               (const_string "alu")
11424            ]
11425            (const_string "ishift")))
11426    (set_attr "mode" "SI")])
11427
11428 (define_insn "*ashlsi3_cconly"
11429   [(set (reg FLAGS_REG)
11430         (compare
11431           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11432                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11433           (const_int 0)))
11434    (clobber (match_scratch:SI 0 "=r"))]
11435   "(optimize_size
11436     || !TARGET_PARTIAL_FLAG_REG_STALL
11437     || (operands[2] == const1_rtx
11438         && (TARGET_SHIFT1
11439             || TARGET_DOUBLE_WITH_ADD)))
11440    && ix86_match_ccmode (insn, CCGOCmode)
11441    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11442 {
11443   switch (get_attr_type (insn))
11444     {
11445     case TYPE_ALU:
11446       gcc_assert (operands[2] == const1_rtx);
11447       return "add{l}\t%0, %0";
11448
11449     default:
11450       if (REG_P (operands[2]))
11451         return "sal{l}\t{%b2, %0|%0, %b2}";
11452       else if (operands[2] == const1_rtx
11453                && (TARGET_SHIFT1 || optimize_size))
11454         return "sal{l}\t%0";
11455       else
11456         return "sal{l}\t{%2, %0|%0, %2}";
11457     }
11458 }
11459   [(set (attr "type")
11460      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11461                           (const_int 0))
11462                       (match_operand 0 "register_operand" ""))
11463                  (match_operand 2 "const1_operand" ""))
11464               (const_string "alu")
11465            ]
11466            (const_string "ishift")))
11467    (set_attr "mode" "SI")])
11468
11469 (define_insn "*ashlsi3_cmp_zext"
11470   [(set (reg FLAGS_REG)
11471         (compare
11472           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11473                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11474           (const_int 0)))
11475    (set (match_operand:DI 0 "register_operand" "=r")
11476         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11477   "TARGET_64BIT
11478    && (optimize_size
11479        || !TARGET_PARTIAL_FLAG_REG_STALL
11480        || (operands[2] == const1_rtx
11481            && (TARGET_SHIFT1
11482                || TARGET_DOUBLE_WITH_ADD)))
11483    && ix86_match_ccmode (insn, CCGOCmode)
11484    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11485 {
11486   switch (get_attr_type (insn))
11487     {
11488     case TYPE_ALU:
11489       gcc_assert (operands[2] == const1_rtx);
11490       return "add{l}\t%k0, %k0";
11491
11492     default:
11493       if (REG_P (operands[2]))
11494         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11495       else if (operands[2] == const1_rtx
11496                && (TARGET_SHIFT1 || optimize_size))
11497         return "sal{l}\t%k0";
11498       else
11499         return "sal{l}\t{%2, %k0|%k0, %2}";
11500     }
11501 }
11502   [(set (attr "type")
11503      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11504                      (const_int 0))
11505                  (match_operand 2 "const1_operand" ""))
11506               (const_string "alu")
11507            ]
11508            (const_string "ishift")))
11509    (set_attr "mode" "SI")])
11510
11511 (define_expand "ashlhi3"
11512   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11513         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11514                    (match_operand:QI 2 "nonmemory_operand" "")))
11515    (clobber (reg:CC FLAGS_REG))]
11516   "TARGET_HIMODE_MATH"
11517   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11518
11519 (define_insn "*ashlhi3_1_lea"
11520   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11521         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11522                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11523    (clobber (reg:CC FLAGS_REG))]
11524   "!TARGET_PARTIAL_REG_STALL
11525    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11526 {
11527   switch (get_attr_type (insn))
11528     {
11529     case TYPE_LEA:
11530       return "#";
11531     case TYPE_ALU:
11532       gcc_assert (operands[2] == const1_rtx);
11533       return "add{w}\t%0, %0";
11534
11535     default:
11536       if (REG_P (operands[2]))
11537         return "sal{w}\t{%b2, %0|%0, %b2}";
11538       else if (operands[2] == const1_rtx
11539                && (TARGET_SHIFT1 || optimize_size))
11540         return "sal{w}\t%0";
11541       else
11542         return "sal{w}\t{%2, %0|%0, %2}";
11543     }
11544 }
11545   [(set (attr "type")
11546      (cond [(eq_attr "alternative" "1")
11547               (const_string "lea")
11548             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11549                           (const_int 0))
11550                       (match_operand 0 "register_operand" ""))
11551                  (match_operand 2 "const1_operand" ""))
11552               (const_string "alu")
11553            ]
11554            (const_string "ishift")))
11555    (set_attr "mode" "HI,SI")])
11556
11557 (define_insn "*ashlhi3_1"
11558   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11559         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11560                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11561    (clobber (reg:CC FLAGS_REG))]
11562   "TARGET_PARTIAL_REG_STALL
11563    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11564 {
11565   switch (get_attr_type (insn))
11566     {
11567     case TYPE_ALU:
11568       gcc_assert (operands[2] == const1_rtx);
11569       return "add{w}\t%0, %0";
11570
11571     default:
11572       if (REG_P (operands[2]))
11573         return "sal{w}\t{%b2, %0|%0, %b2}";
11574       else if (operands[2] == const1_rtx
11575                && (TARGET_SHIFT1 || optimize_size))
11576         return "sal{w}\t%0";
11577       else
11578         return "sal{w}\t{%2, %0|%0, %2}";
11579     }
11580 }
11581   [(set (attr "type")
11582      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11583                           (const_int 0))
11584                       (match_operand 0 "register_operand" ""))
11585                  (match_operand 2 "const1_operand" ""))
11586               (const_string "alu")
11587            ]
11588            (const_string "ishift")))
11589    (set_attr "mode" "HI")])
11590
11591 ;; This pattern can't accept a variable shift count, since shifts by
11592 ;; zero don't affect the flags.  We assume that shifts by constant
11593 ;; zero are optimized away.
11594 (define_insn "*ashlhi3_cmp"
11595   [(set (reg FLAGS_REG)
11596         (compare
11597           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11598                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11599           (const_int 0)))
11600    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11601         (ashift:HI (match_dup 1) (match_dup 2)))]
11602   "(optimize_size
11603     || !TARGET_PARTIAL_FLAG_REG_STALL
11604     || (operands[2] == const1_rtx
11605         && (TARGET_SHIFT1
11606             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11607    && ix86_match_ccmode (insn, CCGOCmode)
11608    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11609 {
11610   switch (get_attr_type (insn))
11611     {
11612     case TYPE_ALU:
11613       gcc_assert (operands[2] == const1_rtx);
11614       return "add{w}\t%0, %0";
11615
11616     default:
11617       if (REG_P (operands[2]))
11618         return "sal{w}\t{%b2, %0|%0, %b2}";
11619       else if (operands[2] == const1_rtx
11620                && (TARGET_SHIFT1 || optimize_size))
11621         return "sal{w}\t%0";
11622       else
11623         return "sal{w}\t{%2, %0|%0, %2}";
11624     }
11625 }
11626   [(set (attr "type")
11627      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11628                           (const_int 0))
11629                       (match_operand 0 "register_operand" ""))
11630                  (match_operand 2 "const1_operand" ""))
11631               (const_string "alu")
11632            ]
11633            (const_string "ishift")))
11634    (set_attr "mode" "HI")])
11635
11636 (define_insn "*ashlhi3_cconly"
11637   [(set (reg FLAGS_REG)
11638         (compare
11639           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11640                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11641           (const_int 0)))
11642    (clobber (match_scratch:HI 0 "=r"))]
11643   "(optimize_size
11644     || !TARGET_PARTIAL_FLAG_REG_STALL
11645     || (operands[2] == const1_rtx
11646         && (TARGET_SHIFT1
11647             || TARGET_DOUBLE_WITH_ADD)))
11648    && ix86_match_ccmode (insn, CCGOCmode)
11649    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11650 {
11651   switch (get_attr_type (insn))
11652     {
11653     case TYPE_ALU:
11654       gcc_assert (operands[2] == const1_rtx);
11655       return "add{w}\t%0, %0";
11656
11657     default:
11658       if (REG_P (operands[2]))
11659         return "sal{w}\t{%b2, %0|%0, %b2}";
11660       else if (operands[2] == const1_rtx
11661                && (TARGET_SHIFT1 || optimize_size))
11662         return "sal{w}\t%0";
11663       else
11664         return "sal{w}\t{%2, %0|%0, %2}";
11665     }
11666 }
11667   [(set (attr "type")
11668      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11669                           (const_int 0))
11670                       (match_operand 0 "register_operand" ""))
11671                  (match_operand 2 "const1_operand" ""))
11672               (const_string "alu")
11673            ]
11674            (const_string "ishift")))
11675    (set_attr "mode" "HI")])
11676
11677 (define_expand "ashlqi3"
11678   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11679         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11680                    (match_operand:QI 2 "nonmemory_operand" "")))
11681    (clobber (reg:CC FLAGS_REG))]
11682   "TARGET_QIMODE_MATH"
11683   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11684
11685 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11686
11687 (define_insn "*ashlqi3_1_lea"
11688   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11689         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11690                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11691    (clobber (reg:CC FLAGS_REG))]
11692   "!TARGET_PARTIAL_REG_STALL
11693    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11694 {
11695   switch (get_attr_type (insn))
11696     {
11697     case TYPE_LEA:
11698       return "#";
11699     case TYPE_ALU:
11700       gcc_assert (operands[2] == const1_rtx);
11701       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11702         return "add{l}\t%k0, %k0";
11703       else
11704         return "add{b}\t%0, %0";
11705
11706     default:
11707       if (REG_P (operands[2]))
11708         {
11709           if (get_attr_mode (insn) == MODE_SI)
11710             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11711           else
11712             return "sal{b}\t{%b2, %0|%0, %b2}";
11713         }
11714       else if (operands[2] == const1_rtx
11715                && (TARGET_SHIFT1 || optimize_size))
11716         {
11717           if (get_attr_mode (insn) == MODE_SI)
11718             return "sal{l}\t%0";
11719           else
11720             return "sal{b}\t%0";
11721         }
11722       else
11723         {
11724           if (get_attr_mode (insn) == MODE_SI)
11725             return "sal{l}\t{%2, %k0|%k0, %2}";
11726           else
11727             return "sal{b}\t{%2, %0|%0, %2}";
11728         }
11729     }
11730 }
11731   [(set (attr "type")
11732      (cond [(eq_attr "alternative" "2")
11733               (const_string "lea")
11734             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11735                           (const_int 0))
11736                       (match_operand 0 "register_operand" ""))
11737                  (match_operand 2 "const1_operand" ""))
11738               (const_string "alu")
11739            ]
11740            (const_string "ishift")))
11741    (set_attr "mode" "QI,SI,SI")])
11742
11743 (define_insn "*ashlqi3_1"
11744   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11745         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11746                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11747    (clobber (reg:CC FLAGS_REG))]
11748   "TARGET_PARTIAL_REG_STALL
11749    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11750 {
11751   switch (get_attr_type (insn))
11752     {
11753     case TYPE_ALU:
11754       gcc_assert (operands[2] == const1_rtx);
11755       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11756         return "add{l}\t%k0, %k0";
11757       else
11758         return "add{b}\t%0, %0";
11759
11760     default:
11761       if (REG_P (operands[2]))
11762         {
11763           if (get_attr_mode (insn) == MODE_SI)
11764             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11765           else
11766             return "sal{b}\t{%b2, %0|%0, %b2}";
11767         }
11768       else if (operands[2] == const1_rtx
11769                && (TARGET_SHIFT1 || optimize_size))
11770         {
11771           if (get_attr_mode (insn) == MODE_SI)
11772             return "sal{l}\t%0";
11773           else
11774             return "sal{b}\t%0";
11775         }
11776       else
11777         {
11778           if (get_attr_mode (insn) == MODE_SI)
11779             return "sal{l}\t{%2, %k0|%k0, %2}";
11780           else
11781             return "sal{b}\t{%2, %0|%0, %2}";
11782         }
11783     }
11784 }
11785   [(set (attr "type")
11786      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11787                           (const_int 0))
11788                       (match_operand 0 "register_operand" ""))
11789                  (match_operand 2 "const1_operand" ""))
11790               (const_string "alu")
11791            ]
11792            (const_string "ishift")))
11793    (set_attr "mode" "QI,SI")])
11794
11795 ;; This pattern can't accept a variable shift count, since shifts by
11796 ;; zero don't affect the flags.  We assume that shifts by constant
11797 ;; zero are optimized away.
11798 (define_insn "*ashlqi3_cmp"
11799   [(set (reg FLAGS_REG)
11800         (compare
11801           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11802                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11803           (const_int 0)))
11804    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11805         (ashift:QI (match_dup 1) (match_dup 2)))]
11806   "(optimize_size
11807     || !TARGET_PARTIAL_FLAG_REG_STALL
11808     || (operands[2] == const1_rtx
11809         && (TARGET_SHIFT1
11810             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11811    && ix86_match_ccmode (insn, CCGOCmode)
11812    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11813 {
11814   switch (get_attr_type (insn))
11815     {
11816     case TYPE_ALU:
11817       gcc_assert (operands[2] == const1_rtx);
11818       return "add{b}\t%0, %0";
11819
11820     default:
11821       if (REG_P (operands[2]))
11822         return "sal{b}\t{%b2, %0|%0, %b2}";
11823       else if (operands[2] == const1_rtx
11824                && (TARGET_SHIFT1 || optimize_size))
11825         return "sal{b}\t%0";
11826       else
11827         return "sal{b}\t{%2, %0|%0, %2}";
11828     }
11829 }
11830   [(set (attr "type")
11831      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11832                           (const_int 0))
11833                       (match_operand 0 "register_operand" ""))
11834                  (match_operand 2 "const1_operand" ""))
11835               (const_string "alu")
11836            ]
11837            (const_string "ishift")))
11838    (set_attr "mode" "QI")])
11839
11840 (define_insn "*ashlqi3_cconly"
11841   [(set (reg FLAGS_REG)
11842         (compare
11843           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11844                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11845           (const_int 0)))
11846    (clobber (match_scratch:QI 0 "=q"))]
11847   "(optimize_size
11848     || !TARGET_PARTIAL_FLAG_REG_STALL
11849     || (operands[2] == const1_rtx
11850         && (TARGET_SHIFT1
11851             || TARGET_DOUBLE_WITH_ADD)))
11852    && ix86_match_ccmode (insn, CCGOCmode)
11853    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11854 {
11855   switch (get_attr_type (insn))
11856     {
11857     case TYPE_ALU:
11858       gcc_assert (operands[2] == const1_rtx);
11859       return "add{b}\t%0, %0";
11860
11861     default:
11862       if (REG_P (operands[2]))
11863         return "sal{b}\t{%b2, %0|%0, %b2}";
11864       else if (operands[2] == const1_rtx
11865                && (TARGET_SHIFT1 || optimize_size))
11866         return "sal{b}\t%0";
11867       else
11868         return "sal{b}\t{%2, %0|%0, %2}";
11869     }
11870 }
11871   [(set (attr "type")
11872      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11873                           (const_int 0))
11874                       (match_operand 0 "register_operand" ""))
11875                  (match_operand 2 "const1_operand" ""))
11876               (const_string "alu")
11877            ]
11878            (const_string "ishift")))
11879    (set_attr "mode" "QI")])
11880
11881 ;; See comment above `ashldi3' about how this works.
11882
11883 (define_expand "ashrti3"
11884   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11885                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11886                                 (match_operand:QI 2 "nonmemory_operand" "")))
11887               (clobber (reg:CC FLAGS_REG))])]
11888   "TARGET_64BIT"
11889 {
11890   if (! immediate_operand (operands[2], QImode))
11891     {
11892       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11893       DONE;
11894     }
11895   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11896   DONE;
11897 })
11898
11899 (define_insn "ashrti3_1"
11900   [(set (match_operand:TI 0 "register_operand" "=r")
11901         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11902                      (match_operand:QI 2 "register_operand" "c")))
11903    (clobber (match_scratch:DI 3 "=&r"))
11904    (clobber (reg:CC FLAGS_REG))]
11905   "TARGET_64BIT"
11906   "#"
11907   [(set_attr "type" "multi")])
11908
11909 (define_insn "*ashrti3_2"
11910   [(set (match_operand:TI 0 "register_operand" "=r")
11911         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11912                      (match_operand:QI 2 "immediate_operand" "O")))
11913    (clobber (reg:CC FLAGS_REG))]
11914   "TARGET_64BIT"
11915   "#"
11916   [(set_attr "type" "multi")])
11917
11918 (define_split
11919   [(set (match_operand:TI 0 "register_operand" "")
11920         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11921                      (match_operand:QI 2 "register_operand" "")))
11922    (clobber (match_scratch:DI 3 ""))
11923    (clobber (reg:CC FLAGS_REG))]
11924   "TARGET_64BIT && reload_completed"
11925   [(const_int 0)]
11926   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11927
11928 (define_split
11929   [(set (match_operand:TI 0 "register_operand" "")
11930         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11931                      (match_operand:QI 2 "immediate_operand" "")))
11932    (clobber (reg:CC FLAGS_REG))]
11933   "TARGET_64BIT && reload_completed"
11934   [(const_int 0)]
11935   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11936
11937 (define_insn "x86_64_shrd"
11938   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11939         (ior:DI (ashiftrt:DI (match_dup 0)
11940                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11941                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11942                   (minus:QI (const_int 64) (match_dup 2)))))
11943    (clobber (reg:CC FLAGS_REG))]
11944   "TARGET_64BIT"
11945   "@
11946    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11947    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11948   [(set_attr "type" "ishift")
11949    (set_attr "prefix_0f" "1")
11950    (set_attr "mode" "DI")
11951    (set_attr "athlon_decode" "vector")
11952    (set_attr "amdfam10_decode" "vector")])
11953
11954 (define_expand "ashrdi3"
11955   [(set (match_operand:DI 0 "shiftdi_operand" "")
11956         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11957                      (match_operand:QI 2 "nonmemory_operand" "")))]
11958   ""
11959   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11960
11961 (define_insn "*ashrdi3_63_rex64"
11962   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11963         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11964                      (match_operand:DI 2 "const_int_operand" "i,i")))
11965    (clobber (reg:CC FLAGS_REG))]
11966   "TARGET_64BIT && INTVAL (operands[2]) == 63
11967    && (TARGET_USE_CLTD || optimize_size)
11968    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11969   "@
11970    {cqto|cqo}
11971    sar{q}\t{%2, %0|%0, %2}"
11972   [(set_attr "type" "imovx,ishift")
11973    (set_attr "prefix_0f" "0,*")
11974    (set_attr "length_immediate" "0,*")
11975    (set_attr "modrm" "0,1")
11976    (set_attr "mode" "DI")])
11977
11978 (define_insn "*ashrdi3_1_one_bit_rex64"
11979   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11980         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11981                      (match_operand:QI 2 "const1_operand" "")))
11982    (clobber (reg:CC FLAGS_REG))]
11983   "TARGET_64BIT
11984    && (TARGET_SHIFT1 || optimize_size)
11985    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11986   "sar{q}\t%0"
11987   [(set_attr "type" "ishift")
11988    (set (attr "length")
11989      (if_then_else (match_operand:DI 0 "register_operand" "")
11990         (const_string "2")
11991         (const_string "*")))])
11992
11993 (define_insn "*ashrdi3_1_rex64"
11994   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11995         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11996                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11997    (clobber (reg:CC FLAGS_REG))]
11998   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11999   "@
12000    sar{q}\t{%2, %0|%0, %2}
12001    sar{q}\t{%b2, %0|%0, %b2}"
12002   [(set_attr "type" "ishift")
12003    (set_attr "mode" "DI")])
12004
12005 ;; This pattern can't accept a variable shift count, since shifts by
12006 ;; zero don't affect the flags.  We assume that shifts by constant
12007 ;; zero are optimized away.
12008 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12009   [(set (reg FLAGS_REG)
12010         (compare
12011           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12012                        (match_operand:QI 2 "const1_operand" ""))
12013           (const_int 0)))
12014    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12015         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12016   "TARGET_64BIT
12017    && (TARGET_SHIFT1 || optimize_size)
12018    && ix86_match_ccmode (insn, CCGOCmode)
12019    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12020   "sar{q}\t%0"
12021   [(set_attr "type" "ishift")
12022    (set (attr "length")
12023      (if_then_else (match_operand:DI 0 "register_operand" "")
12024         (const_string "2")
12025         (const_string "*")))])
12026
12027 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12028   [(set (reg FLAGS_REG)
12029         (compare
12030           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12031                        (match_operand:QI 2 "const1_operand" ""))
12032           (const_int 0)))
12033    (clobber (match_scratch:DI 0 "=r"))]
12034   "TARGET_64BIT
12035    && (TARGET_SHIFT1 || optimize_size)
12036    && ix86_match_ccmode (insn, CCGOCmode)
12037    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12038   "sar{q}\t%0"
12039   [(set_attr "type" "ishift")
12040    (set_attr "length" "2")])
12041
12042 ;; This pattern can't accept a variable shift count, since shifts by
12043 ;; zero don't affect the flags.  We assume that shifts by constant
12044 ;; zero are optimized away.
12045 (define_insn "*ashrdi3_cmp_rex64"
12046   [(set (reg FLAGS_REG)
12047         (compare
12048           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12049                        (match_operand:QI 2 "const_int_operand" "n"))
12050           (const_int 0)))
12051    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12052         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12053   "TARGET_64BIT
12054    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12055    && ix86_match_ccmode (insn, CCGOCmode)
12056    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12057   "sar{q}\t{%2, %0|%0, %2}"
12058   [(set_attr "type" "ishift")
12059    (set_attr "mode" "DI")])
12060
12061 (define_insn "*ashrdi3_cconly_rex64"
12062   [(set (reg FLAGS_REG)
12063         (compare
12064           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12065                        (match_operand:QI 2 "const_int_operand" "n"))
12066           (const_int 0)))
12067    (clobber (match_scratch:DI 0 "=r"))]
12068   "TARGET_64BIT
12069    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12070    && ix86_match_ccmode (insn, CCGOCmode)
12071    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12072   "sar{q}\t{%2, %0|%0, %2}"
12073   [(set_attr "type" "ishift")
12074    (set_attr "mode" "DI")])
12075
12076 (define_insn "*ashrdi3_1"
12077   [(set (match_operand:DI 0 "register_operand" "=r")
12078         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12079                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12080    (clobber (reg:CC FLAGS_REG))]
12081   "!TARGET_64BIT"
12082   "#"
12083   [(set_attr "type" "multi")])
12084
12085 ;; By default we don't ask for a scratch register, because when DImode
12086 ;; values are manipulated, registers are already at a premium.  But if
12087 ;; we have one handy, we won't turn it away.
12088 (define_peephole2
12089   [(match_scratch:SI 3 "r")
12090    (parallel [(set (match_operand:DI 0 "register_operand" "")
12091                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12092                                 (match_operand:QI 2 "nonmemory_operand" "")))
12093               (clobber (reg:CC FLAGS_REG))])
12094    (match_dup 3)]
12095   "!TARGET_64BIT && TARGET_CMOVE"
12096   [(const_int 0)]
12097   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12098
12099 (define_split
12100   [(set (match_operand:DI 0 "register_operand" "")
12101         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12102                      (match_operand:QI 2 "nonmemory_operand" "")))
12103    (clobber (reg:CC FLAGS_REG))]
12104   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12105                      ? epilogue_completed : reload_completed)"
12106   [(const_int 0)]
12107   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12108
12109 (define_insn "x86_shrd_1"
12110   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
12111         (ior:SI (ashiftrt:SI (match_dup 0)
12112                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
12113                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
12114                   (minus:QI (const_int 32) (match_dup 2)))))
12115    (clobber (reg:CC FLAGS_REG))]
12116   ""
12117   "@
12118    shrd{l}\t{%2, %1, %0|%0, %1, %2}
12119    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12120   [(set_attr "type" "ishift")
12121    (set_attr "prefix_0f" "1")
12122    (set_attr "pent_pair" "np")
12123    (set_attr "mode" "SI")])
12124
12125 (define_expand "x86_shift_adj_3"
12126   [(use (match_operand:SI 0 "register_operand" ""))
12127    (use (match_operand:SI 1 "register_operand" ""))
12128    (use (match_operand:QI 2 "register_operand" ""))]
12129   ""
12130 {
12131   rtx label = gen_label_rtx ();
12132   rtx tmp;
12133
12134   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12135
12136   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12137   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12138   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12139                               gen_rtx_LABEL_REF (VOIDmode, label),
12140                               pc_rtx);
12141   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12142   JUMP_LABEL (tmp) = label;
12143
12144   emit_move_insn (operands[0], operands[1]);
12145   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12146
12147   emit_label (label);
12148   LABEL_NUSES (label) = 1;
12149
12150   DONE;
12151 })
12152
12153 (define_insn "ashrsi3_31"
12154   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12155         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12156                      (match_operand:SI 2 "const_int_operand" "i,i")))
12157    (clobber (reg:CC FLAGS_REG))]
12158   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12159    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12160   "@
12161    {cltd|cdq}
12162    sar{l}\t{%2, %0|%0, %2}"
12163   [(set_attr "type" "imovx,ishift")
12164    (set_attr "prefix_0f" "0,*")
12165    (set_attr "length_immediate" "0,*")
12166    (set_attr "modrm" "0,1")
12167    (set_attr "mode" "SI")])
12168
12169 (define_insn "*ashrsi3_31_zext"
12170   [(set (match_operand:DI 0 "register_operand" "=*d,r")
12171         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12172                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
12173    (clobber (reg:CC FLAGS_REG))]
12174   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12175    && INTVAL (operands[2]) == 31
12176    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12177   "@
12178    {cltd|cdq}
12179    sar{l}\t{%2, %k0|%k0, %2}"
12180   [(set_attr "type" "imovx,ishift")
12181    (set_attr "prefix_0f" "0,*")
12182    (set_attr "length_immediate" "0,*")
12183    (set_attr "modrm" "0,1")
12184    (set_attr "mode" "SI")])
12185
12186 (define_expand "ashrsi3"
12187   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12188         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12189                      (match_operand:QI 2 "nonmemory_operand" "")))
12190    (clobber (reg:CC FLAGS_REG))]
12191   ""
12192   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12193
12194 (define_insn "*ashrsi3_1_one_bit"
12195   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12196         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12197                      (match_operand:QI 2 "const1_operand" "")))
12198    (clobber (reg:CC FLAGS_REG))]
12199   "(TARGET_SHIFT1 || optimize_size)
12200    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12201   "sar{l}\t%0"
12202   [(set_attr "type" "ishift")
12203    (set (attr "length")
12204      (if_then_else (match_operand:SI 0 "register_operand" "")
12205         (const_string "2")
12206         (const_string "*")))])
12207
12208 (define_insn "*ashrsi3_1_one_bit_zext"
12209   [(set (match_operand:DI 0 "register_operand" "=r")
12210         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12211                                      (match_operand:QI 2 "const1_operand" ""))))
12212    (clobber (reg:CC FLAGS_REG))]
12213   "TARGET_64BIT
12214    && (TARGET_SHIFT1 || optimize_size)
12215    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12216   "sar{l}\t%k0"
12217   [(set_attr "type" "ishift")
12218    (set_attr "length" "2")])
12219
12220 (define_insn "*ashrsi3_1"
12221   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12222         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12223                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12224    (clobber (reg:CC FLAGS_REG))]
12225   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12226   "@
12227    sar{l}\t{%2, %0|%0, %2}
12228    sar{l}\t{%b2, %0|%0, %b2}"
12229   [(set_attr "type" "ishift")
12230    (set_attr "mode" "SI")])
12231
12232 (define_insn "*ashrsi3_1_zext"
12233   [(set (match_operand:DI 0 "register_operand" "=r,r")
12234         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12235                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12236    (clobber (reg:CC FLAGS_REG))]
12237   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12238   "@
12239    sar{l}\t{%2, %k0|%k0, %2}
12240    sar{l}\t{%b2, %k0|%k0, %b2}"
12241   [(set_attr "type" "ishift")
12242    (set_attr "mode" "SI")])
12243
12244 ;; This pattern can't accept a variable shift count, since shifts by
12245 ;; zero don't affect the flags.  We assume that shifts by constant
12246 ;; zero are optimized away.
12247 (define_insn "*ashrsi3_one_bit_cmp"
12248   [(set (reg FLAGS_REG)
12249         (compare
12250           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12251                        (match_operand:QI 2 "const1_operand" ""))
12252           (const_int 0)))
12253    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12254         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12255   "(TARGET_SHIFT1 || optimize_size)
12256    && ix86_match_ccmode (insn, CCGOCmode)
12257    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12258   "sar{l}\t%0"
12259   [(set_attr "type" "ishift")
12260    (set (attr "length")
12261      (if_then_else (match_operand:SI 0 "register_operand" "")
12262         (const_string "2")
12263         (const_string "*")))])
12264
12265 (define_insn "*ashrsi3_one_bit_cconly"
12266   [(set (reg FLAGS_REG)
12267         (compare
12268           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12269                        (match_operand:QI 2 "const1_operand" ""))
12270           (const_int 0)))
12271    (clobber (match_scratch:SI 0 "=r"))]
12272   "(TARGET_SHIFT1 || optimize_size)
12273    && ix86_match_ccmode (insn, CCGOCmode)
12274    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12275   "sar{l}\t%0"
12276   [(set_attr "type" "ishift")
12277    (set_attr "length" "2")])
12278
12279 (define_insn "*ashrsi3_one_bit_cmp_zext"
12280   [(set (reg FLAGS_REG)
12281         (compare
12282           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12283                        (match_operand:QI 2 "const1_operand" ""))
12284           (const_int 0)))
12285    (set (match_operand:DI 0 "register_operand" "=r")
12286         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12287   "TARGET_64BIT
12288    && (TARGET_SHIFT1 || optimize_size)
12289    && ix86_match_ccmode (insn, CCmode)
12290    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12291   "sar{l}\t%k0"
12292   [(set_attr "type" "ishift")
12293    (set_attr "length" "2")])
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_cmp"
12299   [(set (reg FLAGS_REG)
12300         (compare
12301           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12302                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12303           (const_int 0)))
12304    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12305         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12306   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12307    && ix86_match_ccmode (insn, CCGOCmode)
12308    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12309   "sar{l}\t{%2, %0|%0, %2}"
12310   [(set_attr "type" "ishift")
12311    (set_attr "mode" "SI")])
12312
12313 (define_insn "*ashrsi3_cconly"
12314   [(set (reg FLAGS_REG)
12315         (compare
12316           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12317                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12318           (const_int 0)))
12319    (clobber (match_scratch:SI 0 "=r"))]
12320   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12321    && ix86_match_ccmode (insn, CCGOCmode)
12322    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12323   "sar{l}\t{%2, %0|%0, %2}"
12324   [(set_attr "type" "ishift")
12325    (set_attr "mode" "SI")])
12326
12327 (define_insn "*ashrsi3_cmp_zext"
12328   [(set (reg FLAGS_REG)
12329         (compare
12330           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12331                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12332           (const_int 0)))
12333    (set (match_operand:DI 0 "register_operand" "=r")
12334         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12335   "TARGET_64BIT
12336    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12337    && ix86_match_ccmode (insn, CCGOCmode)
12338    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12339   "sar{l}\t{%2, %k0|%k0, %2}"
12340   [(set_attr "type" "ishift")
12341    (set_attr "mode" "SI")])
12342
12343 (define_expand "ashrhi3"
12344   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12345         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12346                      (match_operand:QI 2 "nonmemory_operand" "")))
12347    (clobber (reg:CC FLAGS_REG))]
12348   "TARGET_HIMODE_MATH"
12349   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12350
12351 (define_insn "*ashrhi3_1_one_bit"
12352   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12353         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12354                      (match_operand:QI 2 "const1_operand" "")))
12355    (clobber (reg:CC FLAGS_REG))]
12356   "(TARGET_SHIFT1 || optimize_size)
12357    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12358   "sar{w}\t%0"
12359   [(set_attr "type" "ishift")
12360    (set (attr "length")
12361      (if_then_else (match_operand 0 "register_operand" "")
12362         (const_string "2")
12363         (const_string "*")))])
12364
12365 (define_insn "*ashrhi3_1"
12366   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12367         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12368                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12369    (clobber (reg:CC FLAGS_REG))]
12370   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12371   "@
12372    sar{w}\t{%2, %0|%0, %2}
12373    sar{w}\t{%b2, %0|%0, %b2}"
12374   [(set_attr "type" "ishift")
12375    (set_attr "mode" "HI")])
12376
12377 ;; This pattern can't accept a variable shift count, since shifts by
12378 ;; zero don't affect the flags.  We assume that shifts by constant
12379 ;; zero are optimized away.
12380 (define_insn "*ashrhi3_one_bit_cmp"
12381   [(set (reg FLAGS_REG)
12382         (compare
12383           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12384                        (match_operand:QI 2 "const1_operand" ""))
12385           (const_int 0)))
12386    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12387         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12388   "(TARGET_SHIFT1 || optimize_size)
12389    && ix86_match_ccmode (insn, CCGOCmode)
12390    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12391   "sar{w}\t%0"
12392   [(set_attr "type" "ishift")
12393    (set (attr "length")
12394      (if_then_else (match_operand 0 "register_operand" "")
12395         (const_string "2")
12396         (const_string "*")))])
12397
12398 (define_insn "*ashrhi3_one_bit_cconly"
12399   [(set (reg FLAGS_REG)
12400         (compare
12401           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12402                        (match_operand:QI 2 "const1_operand" ""))
12403           (const_int 0)))
12404    (clobber (match_scratch:HI 0 "=r"))]
12405   "(TARGET_SHIFT1 || optimize_size)
12406    && ix86_match_ccmode (insn, CCGOCmode)
12407    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12408   "sar{w}\t%0"
12409   [(set_attr "type" "ishift")
12410    (set_attr "length" "2")])
12411
12412 ;; This pattern can't accept a variable shift count, since shifts by
12413 ;; zero don't affect the flags.  We assume that shifts by constant
12414 ;; zero are optimized away.
12415 (define_insn "*ashrhi3_cmp"
12416   [(set (reg FLAGS_REG)
12417         (compare
12418           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12419                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12420           (const_int 0)))
12421    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12422         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12423   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12424    && ix86_match_ccmode (insn, CCGOCmode)
12425    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12426   "sar{w}\t{%2, %0|%0, %2}"
12427   [(set_attr "type" "ishift")
12428    (set_attr "mode" "HI")])
12429
12430 (define_insn "*ashrhi3_cconly"
12431   [(set (reg FLAGS_REG)
12432         (compare
12433           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12434                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12435           (const_int 0)))
12436    (clobber (match_scratch:HI 0 "=r"))]
12437   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12438    && ix86_match_ccmode (insn, CCGOCmode)
12439    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12440   "sar{w}\t{%2, %0|%0, %2}"
12441   [(set_attr "type" "ishift")
12442    (set_attr "mode" "HI")])
12443
12444 (define_expand "ashrqi3"
12445   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12446         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12447                      (match_operand:QI 2 "nonmemory_operand" "")))
12448    (clobber (reg:CC FLAGS_REG))]
12449   "TARGET_QIMODE_MATH"
12450   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12451
12452 (define_insn "*ashrqi3_1_one_bit"
12453   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12454         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12455                      (match_operand:QI 2 "const1_operand" "")))
12456    (clobber (reg:CC FLAGS_REG))]
12457   "(TARGET_SHIFT1 || optimize_size)
12458    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12459   "sar{b}\t%0"
12460   [(set_attr "type" "ishift")
12461    (set (attr "length")
12462      (if_then_else (match_operand 0 "register_operand" "")
12463         (const_string "2")
12464         (const_string "*")))])
12465
12466 (define_insn "*ashrqi3_1_one_bit_slp"
12467   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12468         (ashiftrt:QI (match_dup 0)
12469                      (match_operand:QI 1 "const1_operand" "")))
12470    (clobber (reg:CC FLAGS_REG))]
12471   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12472    && (TARGET_SHIFT1 || optimize_size)
12473    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12474   "sar{b}\t%0"
12475   [(set_attr "type" "ishift1")
12476    (set (attr "length")
12477      (if_then_else (match_operand 0 "register_operand" "")
12478         (const_string "2")
12479         (const_string "*")))])
12480
12481 (define_insn "*ashrqi3_1"
12482   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12483         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12484                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12485    (clobber (reg:CC FLAGS_REG))]
12486   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12487   "@
12488    sar{b}\t{%2, %0|%0, %2}
12489    sar{b}\t{%b2, %0|%0, %b2}"
12490   [(set_attr "type" "ishift")
12491    (set_attr "mode" "QI")])
12492
12493 (define_insn "*ashrqi3_1_slp"
12494   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12495         (ashiftrt:QI (match_dup 0)
12496                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12497    (clobber (reg:CC FLAGS_REG))]
12498   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12499    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12500   "@
12501    sar{b}\t{%1, %0|%0, %1}
12502    sar{b}\t{%b1, %0|%0, %b1}"
12503   [(set_attr "type" "ishift1")
12504    (set_attr "mode" "QI")])
12505
12506 ;; This pattern can't accept a variable shift count, since shifts by
12507 ;; zero don't affect the flags.  We assume that shifts by constant
12508 ;; zero are optimized away.
12509 (define_insn "*ashrqi3_one_bit_cmp"
12510   [(set (reg FLAGS_REG)
12511         (compare
12512           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12513                        (match_operand:QI 2 "const1_operand" "I"))
12514           (const_int 0)))
12515    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12516         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12517   "(TARGET_SHIFT1 || optimize_size)
12518    && ix86_match_ccmode (insn, CCGOCmode)
12519    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12520   "sar{b}\t%0"
12521   [(set_attr "type" "ishift")
12522    (set (attr "length")
12523      (if_then_else (match_operand 0 "register_operand" "")
12524         (const_string "2")
12525         (const_string "*")))])
12526
12527 (define_insn "*ashrqi3_one_bit_cconly"
12528   [(set (reg FLAGS_REG)
12529         (compare
12530           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12531                        (match_operand:QI 2 "const1_operand" "I"))
12532           (const_int 0)))
12533    (clobber (match_scratch:QI 0 "=q"))]
12534   "(TARGET_SHIFT1 || optimize_size)
12535    && ix86_match_ccmode (insn, CCGOCmode)
12536    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12537   "sar{b}\t%0"
12538   [(set_attr "type" "ishift")
12539    (set_attr "length" "2")])
12540
12541 ;; This pattern can't accept a variable shift count, since shifts by
12542 ;; zero don't affect the flags.  We assume that shifts by constant
12543 ;; zero are optimized away.
12544 (define_insn "*ashrqi3_cmp"
12545   [(set (reg FLAGS_REG)
12546         (compare
12547           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12548                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12549           (const_int 0)))
12550    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12551         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12552   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12553    && ix86_match_ccmode (insn, CCGOCmode)
12554    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12555   "sar{b}\t{%2, %0|%0, %2}"
12556   [(set_attr "type" "ishift")
12557    (set_attr "mode" "QI")])
12558
12559 (define_insn "*ashrqi3_cconly"
12560   [(set (reg FLAGS_REG)
12561         (compare
12562           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12563                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12564           (const_int 0)))
12565    (clobber (match_scratch:QI 0 "=q"))]
12566   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12567    && ix86_match_ccmode (insn, CCGOCmode)
12568    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12569   "sar{b}\t{%2, %0|%0, %2}"
12570   [(set_attr "type" "ishift")
12571    (set_attr "mode" "QI")])
12572
12573 \f
12574 ;; Logical shift instructions
12575
12576 ;; See comment above `ashldi3' about how this works.
12577
12578 (define_expand "lshrti3"
12579   [(parallel [(set (match_operand:TI 0 "register_operand" "")
12580                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12581                                 (match_operand:QI 2 "nonmemory_operand" "")))
12582               (clobber (reg:CC FLAGS_REG))])]
12583   "TARGET_64BIT"
12584 {
12585   if (! immediate_operand (operands[2], QImode))
12586     {
12587       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12588       DONE;
12589     }
12590   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12591   DONE;
12592 })
12593
12594 (define_insn "lshrti3_1"
12595   [(set (match_operand:TI 0 "register_operand" "=r")
12596         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12597                      (match_operand:QI 2 "register_operand" "c")))
12598    (clobber (match_scratch:DI 3 "=&r"))
12599    (clobber (reg:CC FLAGS_REG))]
12600   "TARGET_64BIT"
12601   "#"
12602   [(set_attr "type" "multi")])
12603
12604 ;; This pattern must be defined before *lshrti3_2 to prevent
12605 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12606
12607 (define_insn "sse2_lshrti3"
12608   [(set (match_operand:TI 0 "register_operand" "=x")
12609         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12610                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12611   "TARGET_SSE2"
12612 {
12613   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12614   return "psrldq\t{%2, %0|%0, %2}";
12615 }
12616   [(set_attr "type" "sseishft")
12617    (set_attr "prefix_data16" "1")
12618    (set_attr "mode" "TI")])
12619
12620 (define_insn "*lshrti3_2"
12621   [(set (match_operand:TI 0 "register_operand" "=r")
12622         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12623                      (match_operand:QI 2 "immediate_operand" "O")))
12624    (clobber (reg:CC FLAGS_REG))]
12625   "TARGET_64BIT"
12626   "#"
12627   [(set_attr "type" "multi")])
12628
12629 (define_split
12630   [(set (match_operand:TI 0 "register_operand" "")
12631         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12632                      (match_operand:QI 2 "register_operand" "")))
12633    (clobber (match_scratch:DI 3 ""))
12634    (clobber (reg:CC FLAGS_REG))]
12635   "TARGET_64BIT && reload_completed"
12636   [(const_int 0)]
12637   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12638
12639 (define_split
12640   [(set (match_operand:TI 0 "register_operand" "")
12641         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12642                      (match_operand:QI 2 "immediate_operand" "")))
12643    (clobber (reg:CC FLAGS_REG))]
12644   "TARGET_64BIT && reload_completed"
12645   [(const_int 0)]
12646   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12647
12648 (define_expand "lshrdi3"
12649   [(set (match_operand:DI 0 "shiftdi_operand" "")
12650         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12651                      (match_operand:QI 2 "nonmemory_operand" "")))]
12652   ""
12653   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12654
12655 (define_insn "*lshrdi3_1_one_bit_rex64"
12656   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12657         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12658                      (match_operand:QI 2 "const1_operand" "")))
12659    (clobber (reg:CC FLAGS_REG))]
12660   "TARGET_64BIT
12661    && (TARGET_SHIFT1 || optimize_size)
12662    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12663   "shr{q}\t%0"
12664   [(set_attr "type" "ishift")
12665    (set (attr "length")
12666      (if_then_else (match_operand:DI 0 "register_operand" "")
12667         (const_string "2")
12668         (const_string "*")))])
12669
12670 (define_insn "*lshrdi3_1_rex64"
12671   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12672         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12673                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12674    (clobber (reg:CC FLAGS_REG))]
12675   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12676   "@
12677    shr{q}\t{%2, %0|%0, %2}
12678    shr{q}\t{%b2, %0|%0, %b2}"
12679   [(set_attr "type" "ishift")
12680    (set_attr "mode" "DI")])
12681
12682 ;; This pattern can't accept a variable shift count, since shifts by
12683 ;; zero don't affect the flags.  We assume that shifts by constant
12684 ;; zero are optimized away.
12685 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12686   [(set (reg FLAGS_REG)
12687         (compare
12688           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12689                        (match_operand:QI 2 "const1_operand" ""))
12690           (const_int 0)))
12691    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12692         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12693   "TARGET_64BIT
12694    && (TARGET_SHIFT1 || optimize_size)
12695    && ix86_match_ccmode (insn, CCGOCmode)
12696    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12697   "shr{q}\t%0"
12698   [(set_attr "type" "ishift")
12699    (set (attr "length")
12700      (if_then_else (match_operand:DI 0 "register_operand" "")
12701         (const_string "2")
12702         (const_string "*")))])
12703
12704 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12705   [(set (reg FLAGS_REG)
12706         (compare
12707           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12708                        (match_operand:QI 2 "const1_operand" ""))
12709           (const_int 0)))
12710    (clobber (match_scratch:DI 0 "=r"))]
12711   "TARGET_64BIT
12712    && (TARGET_SHIFT1 || optimize_size)
12713    && ix86_match_ccmode (insn, CCGOCmode)
12714    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12715   "shr{q}\t%0"
12716   [(set_attr "type" "ishift")
12717    (set_attr "length" "2")])
12718
12719 ;; This pattern can't accept a variable shift count, since shifts by
12720 ;; zero don't affect the flags.  We assume that shifts by constant
12721 ;; zero are optimized away.
12722 (define_insn "*lshrdi3_cmp_rex64"
12723   [(set (reg FLAGS_REG)
12724         (compare
12725           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12726                        (match_operand:QI 2 "const_int_operand" "e"))
12727           (const_int 0)))
12728    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12729         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12730   "TARGET_64BIT
12731    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12732    && ix86_match_ccmode (insn, CCGOCmode)
12733    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12734   "shr{q}\t{%2, %0|%0, %2}"
12735   [(set_attr "type" "ishift")
12736    (set_attr "mode" "DI")])
12737
12738 (define_insn "*lshrdi3_cconly_rex64"
12739   [(set (reg FLAGS_REG)
12740         (compare
12741           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12742                        (match_operand:QI 2 "const_int_operand" "e"))
12743           (const_int 0)))
12744    (clobber (match_scratch:DI 0 "=r"))]
12745   "TARGET_64BIT
12746    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12747    && ix86_match_ccmode (insn, CCGOCmode)
12748    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12749   "shr{q}\t{%2, %0|%0, %2}"
12750   [(set_attr "type" "ishift")
12751    (set_attr "mode" "DI")])
12752
12753 (define_insn "*lshrdi3_1"
12754   [(set (match_operand:DI 0 "register_operand" "=r")
12755         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12756                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12757    (clobber (reg:CC FLAGS_REG))]
12758   "!TARGET_64BIT"
12759   "#"
12760   [(set_attr "type" "multi")])
12761
12762 ;; By default we don't ask for a scratch register, because when DImode
12763 ;; values are manipulated, registers are already at a premium.  But if
12764 ;; we have one handy, we won't turn it away.
12765 (define_peephole2
12766   [(match_scratch:SI 3 "r")
12767    (parallel [(set (match_operand:DI 0 "register_operand" "")
12768                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12769                                 (match_operand:QI 2 "nonmemory_operand" "")))
12770               (clobber (reg:CC FLAGS_REG))])
12771    (match_dup 3)]
12772   "!TARGET_64BIT && TARGET_CMOVE"
12773   [(const_int 0)]
12774   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12775
12776 (define_split
12777   [(set (match_operand:DI 0 "register_operand" "")
12778         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12779                      (match_operand:QI 2 "nonmemory_operand" "")))
12780    (clobber (reg:CC FLAGS_REG))]
12781   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12782                      ? epilogue_completed : reload_completed)"
12783   [(const_int 0)]
12784   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12785
12786 (define_expand "lshrsi3"
12787   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12788         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12789                      (match_operand:QI 2 "nonmemory_operand" "")))
12790    (clobber (reg:CC FLAGS_REG))]
12791   ""
12792   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12793
12794 (define_insn "*lshrsi3_1_one_bit"
12795   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12796         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12797                      (match_operand:QI 2 "const1_operand" "")))
12798    (clobber (reg:CC FLAGS_REG))]
12799   "(TARGET_SHIFT1 || optimize_size)
12800    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12801   "shr{l}\t%0"
12802   [(set_attr "type" "ishift")
12803    (set (attr "length")
12804      (if_then_else (match_operand:SI 0 "register_operand" "")
12805         (const_string "2")
12806         (const_string "*")))])
12807
12808 (define_insn "*lshrsi3_1_one_bit_zext"
12809   [(set (match_operand:DI 0 "register_operand" "=r")
12810         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12811                      (match_operand:QI 2 "const1_operand" "")))
12812    (clobber (reg:CC FLAGS_REG))]
12813   "TARGET_64BIT
12814    && (TARGET_SHIFT1 || optimize_size)
12815    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12816   "shr{l}\t%k0"
12817   [(set_attr "type" "ishift")
12818    (set_attr "length" "2")])
12819
12820 (define_insn "*lshrsi3_1"
12821   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12822         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12823                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12824    (clobber (reg:CC FLAGS_REG))]
12825   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12826   "@
12827    shr{l}\t{%2, %0|%0, %2}
12828    shr{l}\t{%b2, %0|%0, %b2}"
12829   [(set_attr "type" "ishift")
12830    (set_attr "mode" "SI")])
12831
12832 (define_insn "*lshrsi3_1_zext"
12833   [(set (match_operand:DI 0 "register_operand" "=r,r")
12834         (zero_extend:DI
12835           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12836                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12837    (clobber (reg:CC FLAGS_REG))]
12838   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12839   "@
12840    shr{l}\t{%2, %k0|%k0, %2}
12841    shr{l}\t{%b2, %k0|%k0, %b2}"
12842   [(set_attr "type" "ishift")
12843    (set_attr "mode" "SI")])
12844
12845 ;; This pattern can't accept a variable shift count, since shifts by
12846 ;; zero don't affect the flags.  We assume that shifts by constant
12847 ;; zero are optimized away.
12848 (define_insn "*lshrsi3_one_bit_cmp"
12849   [(set (reg FLAGS_REG)
12850         (compare
12851           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12852                        (match_operand:QI 2 "const1_operand" ""))
12853           (const_int 0)))
12854    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12855         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12856   "(TARGET_SHIFT1 || optimize_size)
12857    && ix86_match_ccmode (insn, CCGOCmode)
12858    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12859   "shr{l}\t%0"
12860   [(set_attr "type" "ishift")
12861    (set (attr "length")
12862      (if_then_else (match_operand:SI 0 "register_operand" "")
12863         (const_string "2")
12864         (const_string "*")))])
12865
12866 (define_insn "*lshrsi3_one_bit_cconly"
12867   [(set (reg FLAGS_REG)
12868         (compare
12869           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12870                        (match_operand:QI 2 "const1_operand" ""))
12871           (const_int 0)))
12872    (clobber (match_scratch:SI 0 "=r"))]
12873   "(TARGET_SHIFT1 || optimize_size)
12874    && ix86_match_ccmode (insn, CCGOCmode)
12875    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12876   "shr{l}\t%0"
12877   [(set_attr "type" "ishift")
12878    (set_attr "length" "2")])
12879
12880 (define_insn "*lshrsi3_cmp_one_bit_zext"
12881   [(set (reg FLAGS_REG)
12882         (compare
12883           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12884                        (match_operand:QI 2 "const1_operand" ""))
12885           (const_int 0)))
12886    (set (match_operand:DI 0 "register_operand" "=r")
12887         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12888   "TARGET_64BIT
12889    && (TARGET_SHIFT1 || optimize_size)
12890    && ix86_match_ccmode (insn, CCGOCmode)
12891    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12892   "shr{l}\t%k0"
12893   [(set_attr "type" "ishift")
12894    (set_attr "length" "2")])
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_cmp"
12900   [(set (reg FLAGS_REG)
12901         (compare
12902           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12903                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12904           (const_int 0)))
12905    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12906         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12907   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12908    && ix86_match_ccmode (insn, CCGOCmode)
12909    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12910   "shr{l}\t{%2, %0|%0, %2}"
12911   [(set_attr "type" "ishift")
12912    (set_attr "mode" "SI")])
12913
12914 (define_insn "*lshrsi3_cconly"
12915   [(set (reg FLAGS_REG)
12916       (compare
12917         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12918                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12919         (const_int 0)))
12920    (clobber (match_scratch:SI 0 "=r"))]
12921   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12922    && ix86_match_ccmode (insn, CCGOCmode)
12923    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12924   "shr{l}\t{%2, %0|%0, %2}"
12925   [(set_attr "type" "ishift")
12926    (set_attr "mode" "SI")])
12927
12928 (define_insn "*lshrsi3_cmp_zext"
12929   [(set (reg FLAGS_REG)
12930         (compare
12931           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12932                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12933           (const_int 0)))
12934    (set (match_operand:DI 0 "register_operand" "=r")
12935         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12936   "TARGET_64BIT
12937    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12938    && ix86_match_ccmode (insn, CCGOCmode)
12939    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12940   "shr{l}\t{%2, %k0|%k0, %2}"
12941   [(set_attr "type" "ishift")
12942    (set_attr "mode" "SI")])
12943
12944 (define_expand "lshrhi3"
12945   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12946         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12947                      (match_operand:QI 2 "nonmemory_operand" "")))
12948    (clobber (reg:CC FLAGS_REG))]
12949   "TARGET_HIMODE_MATH"
12950   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12951
12952 (define_insn "*lshrhi3_1_one_bit"
12953   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12954         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12955                      (match_operand:QI 2 "const1_operand" "")))
12956    (clobber (reg:CC FLAGS_REG))]
12957   "(TARGET_SHIFT1 || optimize_size)
12958    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12959   "shr{w}\t%0"
12960   [(set_attr "type" "ishift")
12961    (set (attr "length")
12962      (if_then_else (match_operand 0 "register_operand" "")
12963         (const_string "2")
12964         (const_string "*")))])
12965
12966 (define_insn "*lshrhi3_1"
12967   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12968         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12969                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12970    (clobber (reg:CC FLAGS_REG))]
12971   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12972   "@
12973    shr{w}\t{%2, %0|%0, %2}
12974    shr{w}\t{%b2, %0|%0, %b2}"
12975   [(set_attr "type" "ishift")
12976    (set_attr "mode" "HI")])
12977
12978 ;; This pattern can't accept a variable shift count, since shifts by
12979 ;; zero don't affect the flags.  We assume that shifts by constant
12980 ;; zero are optimized away.
12981 (define_insn "*lshrhi3_one_bit_cmp"
12982   [(set (reg FLAGS_REG)
12983         (compare
12984           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12985                        (match_operand:QI 2 "const1_operand" ""))
12986           (const_int 0)))
12987    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12988         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12989   "(TARGET_SHIFT1 || optimize_size)
12990    && ix86_match_ccmode (insn, CCGOCmode)
12991    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12992   "shr{w}\t%0"
12993   [(set_attr "type" "ishift")
12994    (set (attr "length")
12995      (if_then_else (match_operand:SI 0 "register_operand" "")
12996         (const_string "2")
12997         (const_string "*")))])
12998
12999 (define_insn "*lshrhi3_one_bit_cconly"
13000   [(set (reg FLAGS_REG)
13001         (compare
13002           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13003                        (match_operand:QI 2 "const1_operand" ""))
13004           (const_int 0)))
13005    (clobber (match_scratch:HI 0 "=r"))]
13006   "(TARGET_SHIFT1 || optimize_size)
13007    && ix86_match_ccmode (insn, CCGOCmode)
13008    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13009   "shr{w}\t%0"
13010   [(set_attr "type" "ishift")
13011    (set_attr "length" "2")])
13012
13013 ;; This pattern can't accept a variable shift count, since shifts by
13014 ;; zero don't affect the flags.  We assume that shifts by constant
13015 ;; zero are optimized away.
13016 (define_insn "*lshrhi3_cmp"
13017   [(set (reg FLAGS_REG)
13018         (compare
13019           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13020                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13021           (const_int 0)))
13022    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13023         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13024   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13025    && ix86_match_ccmode (insn, CCGOCmode)
13026    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13027   "shr{w}\t{%2, %0|%0, %2}"
13028   [(set_attr "type" "ishift")
13029    (set_attr "mode" "HI")])
13030
13031 (define_insn "*lshrhi3_cconly"
13032   [(set (reg FLAGS_REG)
13033         (compare
13034           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13035                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13036           (const_int 0)))
13037    (clobber (match_scratch:HI 0 "=r"))]
13038   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13039    && ix86_match_ccmode (insn, CCGOCmode)
13040    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13041   "shr{w}\t{%2, %0|%0, %2}"
13042   [(set_attr "type" "ishift")
13043    (set_attr "mode" "HI")])
13044
13045 (define_expand "lshrqi3"
13046   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13047         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13048                      (match_operand:QI 2 "nonmemory_operand" "")))
13049    (clobber (reg:CC FLAGS_REG))]
13050   "TARGET_QIMODE_MATH"
13051   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13052
13053 (define_insn "*lshrqi3_1_one_bit"
13054   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13055         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13056                      (match_operand:QI 2 "const1_operand" "")))
13057    (clobber (reg:CC FLAGS_REG))]
13058   "(TARGET_SHIFT1 || optimize_size)
13059    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13060   "shr{b}\t%0"
13061   [(set_attr "type" "ishift")
13062    (set (attr "length")
13063      (if_then_else (match_operand 0 "register_operand" "")
13064         (const_string "2")
13065         (const_string "*")))])
13066
13067 (define_insn "*lshrqi3_1_one_bit_slp"
13068   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13069         (lshiftrt:QI (match_dup 0)
13070                      (match_operand:QI 1 "const1_operand" "")))
13071    (clobber (reg:CC FLAGS_REG))]
13072   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13073    && (TARGET_SHIFT1 || optimize_size)"
13074   "shr{b}\t%0"
13075   [(set_attr "type" "ishift1")
13076    (set (attr "length")
13077      (if_then_else (match_operand 0 "register_operand" "")
13078         (const_string "2")
13079         (const_string "*")))])
13080
13081 (define_insn "*lshrqi3_1"
13082   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13083         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13084                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13085    (clobber (reg:CC FLAGS_REG))]
13086   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13087   "@
13088    shr{b}\t{%2, %0|%0, %2}
13089    shr{b}\t{%b2, %0|%0, %b2}"
13090   [(set_attr "type" "ishift")
13091    (set_attr "mode" "QI")])
13092
13093 (define_insn "*lshrqi3_1_slp"
13094   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13095         (lshiftrt:QI (match_dup 0)
13096                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13097    (clobber (reg:CC FLAGS_REG))]
13098   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13099    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13100   "@
13101    shr{b}\t{%1, %0|%0, %1}
13102    shr{b}\t{%b1, %0|%0, %b1}"
13103   [(set_attr "type" "ishift1")
13104    (set_attr "mode" "QI")])
13105
13106 ;; This pattern can't accept a variable shift count, since shifts by
13107 ;; zero don't affect the flags.  We assume that shifts by constant
13108 ;; zero are optimized away.
13109 (define_insn "*lshrqi2_one_bit_cmp"
13110   [(set (reg FLAGS_REG)
13111         (compare
13112           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13113                        (match_operand:QI 2 "const1_operand" ""))
13114           (const_int 0)))
13115    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13116         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13117   "(TARGET_SHIFT1 || optimize_size)
13118    && ix86_match_ccmode (insn, CCGOCmode)
13119    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13120   "shr{b}\t%0"
13121   [(set_attr "type" "ishift")
13122    (set (attr "length")
13123      (if_then_else (match_operand:SI 0 "register_operand" "")
13124         (const_string "2")
13125         (const_string "*")))])
13126
13127 (define_insn "*lshrqi2_one_bit_cconly"
13128   [(set (reg FLAGS_REG)
13129         (compare
13130           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13131                        (match_operand:QI 2 "const1_operand" ""))
13132           (const_int 0)))
13133    (clobber (match_scratch:QI 0 "=q"))]
13134   "(TARGET_SHIFT1 || optimize_size)
13135    && ix86_match_ccmode (insn, CCGOCmode)
13136    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13137   "shr{b}\t%0"
13138   [(set_attr "type" "ishift")
13139    (set_attr "length" "2")])
13140
13141 ;; This pattern can't accept a variable shift count, since shifts by
13142 ;; zero don't affect the flags.  We assume that shifts by constant
13143 ;; zero are optimized away.
13144 (define_insn "*lshrqi2_cmp"
13145   [(set (reg FLAGS_REG)
13146         (compare
13147           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13148                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13149           (const_int 0)))
13150    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13151         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13152   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13153    && ix86_match_ccmode (insn, CCGOCmode)
13154    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13155   "shr{b}\t{%2, %0|%0, %2}"
13156   [(set_attr "type" "ishift")
13157    (set_attr "mode" "QI")])
13158
13159 (define_insn "*lshrqi2_cconly"
13160   [(set (reg FLAGS_REG)
13161         (compare
13162           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13163                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13164           (const_int 0)))
13165    (clobber (match_scratch:QI 0 "=q"))]
13166   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13167    && ix86_match_ccmode (insn, CCGOCmode)
13168    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13169   "shr{b}\t{%2, %0|%0, %2}"
13170   [(set_attr "type" "ishift")
13171    (set_attr "mode" "QI")])
13172 \f
13173 ;; Rotate instructions
13174
13175 (define_expand "rotldi3"
13176   [(set (match_operand:DI 0 "shiftdi_operand" "")
13177         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13178                    (match_operand:QI 2 "nonmemory_operand" "")))
13179    (clobber (reg:CC FLAGS_REG))]
13180  ""
13181 {
13182   if (TARGET_64BIT)
13183     {
13184       ix86_expand_binary_operator (ROTATE, DImode, operands);
13185       DONE;
13186     }
13187   if (!const_1_to_31_operand (operands[2], VOIDmode))
13188     FAIL;
13189   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13190   DONE;
13191 })
13192
13193 ;; Implement rotation using two double-precision shift instructions
13194 ;; and a scratch register.
13195 (define_insn_and_split "ix86_rotldi3"
13196  [(set (match_operand:DI 0 "register_operand" "=r")
13197        (rotate:DI (match_operand:DI 1 "register_operand" "0")
13198                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
13199   (clobber (reg:CC FLAGS_REG))
13200   (clobber (match_scratch:SI 3 "=&r"))]
13201  "!TARGET_64BIT"
13202  ""
13203  "&& reload_completed"
13204  [(set (match_dup 3) (match_dup 4))
13205   (parallel
13206    [(set (match_dup 4)
13207          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13208                  (lshiftrt:SI (match_dup 5)
13209                               (minus:QI (const_int 32) (match_dup 2)))))
13210     (clobber (reg:CC FLAGS_REG))])
13211   (parallel
13212    [(set (match_dup 5)
13213          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13214                  (lshiftrt:SI (match_dup 3)
13215                               (minus:QI (const_int 32) (match_dup 2)))))
13216     (clobber (reg:CC FLAGS_REG))])]
13217  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13218
13219 (define_insn "*rotlsi3_1_one_bit_rex64"
13220   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13221         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13222                    (match_operand:QI 2 "const1_operand" "")))
13223    (clobber (reg:CC FLAGS_REG))]
13224   "TARGET_64BIT
13225    && (TARGET_SHIFT1 || optimize_size)
13226    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13227   "rol{q}\t%0"
13228   [(set_attr "type" "rotate")
13229    (set (attr "length")
13230      (if_then_else (match_operand:DI 0 "register_operand" "")
13231         (const_string "2")
13232         (const_string "*")))])
13233
13234 (define_insn "*rotldi3_1_rex64"
13235   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13236         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13237                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
13238    (clobber (reg:CC FLAGS_REG))]
13239   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13240   "@
13241    rol{q}\t{%2, %0|%0, %2}
13242    rol{q}\t{%b2, %0|%0, %b2}"
13243   [(set_attr "type" "rotate")
13244    (set_attr "mode" "DI")])
13245
13246 (define_expand "rotlsi3"
13247   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13248         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13249                    (match_operand:QI 2 "nonmemory_operand" "")))
13250    (clobber (reg:CC FLAGS_REG))]
13251   ""
13252   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13253
13254 (define_insn "*rotlsi3_1_one_bit"
13255   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13256         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13257                    (match_operand:QI 2 "const1_operand" "")))
13258    (clobber (reg:CC FLAGS_REG))]
13259   "(TARGET_SHIFT1 || optimize_size)
13260    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13261   "rol{l}\t%0"
13262   [(set_attr "type" "rotate")
13263    (set (attr "length")
13264      (if_then_else (match_operand:SI 0 "register_operand" "")
13265         (const_string "2")
13266         (const_string "*")))])
13267
13268 (define_insn "*rotlsi3_1_one_bit_zext"
13269   [(set (match_operand:DI 0 "register_operand" "=r")
13270         (zero_extend:DI
13271           (rotate:SI (match_operand:SI 1 "register_operand" "0")
13272                      (match_operand:QI 2 "const1_operand" ""))))
13273    (clobber (reg:CC FLAGS_REG))]
13274   "TARGET_64BIT
13275    && (TARGET_SHIFT1 || optimize_size)
13276    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13277   "rol{l}\t%k0"
13278   [(set_attr "type" "rotate")
13279    (set_attr "length" "2")])
13280
13281 (define_insn "*rotlsi3_1"
13282   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13283         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13284                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13285    (clobber (reg:CC FLAGS_REG))]
13286   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13287   "@
13288    rol{l}\t{%2, %0|%0, %2}
13289    rol{l}\t{%b2, %0|%0, %b2}"
13290   [(set_attr "type" "rotate")
13291    (set_attr "mode" "SI")])
13292
13293 (define_insn "*rotlsi3_1_zext"
13294   [(set (match_operand:DI 0 "register_operand" "=r,r")
13295         (zero_extend:DI
13296           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13297                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13298    (clobber (reg:CC FLAGS_REG))]
13299   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13300   "@
13301    rol{l}\t{%2, %k0|%k0, %2}
13302    rol{l}\t{%b2, %k0|%k0, %b2}"
13303   [(set_attr "type" "rotate")
13304    (set_attr "mode" "SI")])
13305
13306 (define_expand "rotlhi3"
13307   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13308         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13309                    (match_operand:QI 2 "nonmemory_operand" "")))
13310    (clobber (reg:CC FLAGS_REG))]
13311   "TARGET_HIMODE_MATH"
13312   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13313
13314 (define_insn "*rotlhi3_1_one_bit"
13315   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13316         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13317                    (match_operand:QI 2 "const1_operand" "")))
13318    (clobber (reg:CC FLAGS_REG))]
13319   "(TARGET_SHIFT1 || optimize_size)
13320    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13321   "rol{w}\t%0"
13322   [(set_attr "type" "rotate")
13323    (set (attr "length")
13324      (if_then_else (match_operand 0 "register_operand" "")
13325         (const_string "2")
13326         (const_string "*")))])
13327
13328 (define_insn "*rotlhi3_1"
13329   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13330         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13331                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13332    (clobber (reg:CC FLAGS_REG))]
13333   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13334   "@
13335    rol{w}\t{%2, %0|%0, %2}
13336    rol{w}\t{%b2, %0|%0, %b2}"
13337   [(set_attr "type" "rotate")
13338    (set_attr "mode" "HI")])
13339
13340 (define_split
13341  [(set (match_operand:HI 0 "register_operand" "")
13342        (rotate:HI (match_dup 0) (const_int 8)))
13343   (clobber (reg:CC FLAGS_REG))]
13344  "reload_completed"
13345  [(parallel [(set (strict_low_part (match_dup 0))
13346                   (bswap:HI (match_dup 0)))
13347              (clobber (reg:CC FLAGS_REG))])]
13348  "")
13349
13350 (define_expand "rotlqi3"
13351   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13352         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13353                    (match_operand:QI 2 "nonmemory_operand" "")))
13354    (clobber (reg:CC FLAGS_REG))]
13355   "TARGET_QIMODE_MATH"
13356   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13357
13358 (define_insn "*rotlqi3_1_one_bit_slp"
13359   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13360         (rotate:QI (match_dup 0)
13361                    (match_operand:QI 1 "const1_operand" "")))
13362    (clobber (reg:CC FLAGS_REG))]
13363   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13364    && (TARGET_SHIFT1 || optimize_size)"
13365   "rol{b}\t%0"
13366   [(set_attr "type" "rotate1")
13367    (set (attr "length")
13368      (if_then_else (match_operand 0 "register_operand" "")
13369         (const_string "2")
13370         (const_string "*")))])
13371
13372 (define_insn "*rotlqi3_1_one_bit"
13373   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13374         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13375                    (match_operand:QI 2 "const1_operand" "")))
13376    (clobber (reg:CC FLAGS_REG))]
13377   "(TARGET_SHIFT1 || optimize_size)
13378    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13379   "rol{b}\t%0"
13380   [(set_attr "type" "rotate")
13381    (set (attr "length")
13382      (if_then_else (match_operand 0 "register_operand" "")
13383         (const_string "2")
13384         (const_string "*")))])
13385
13386 (define_insn "*rotlqi3_1_slp"
13387   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13388         (rotate:QI (match_dup 0)
13389                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13390    (clobber (reg:CC FLAGS_REG))]
13391   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13392    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13393   "@
13394    rol{b}\t{%1, %0|%0, %1}
13395    rol{b}\t{%b1, %0|%0, %b1}"
13396   [(set_attr "type" "rotate1")
13397    (set_attr "mode" "QI")])
13398
13399 (define_insn "*rotlqi3_1"
13400   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13401         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13402                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13403    (clobber (reg:CC FLAGS_REG))]
13404   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13405   "@
13406    rol{b}\t{%2, %0|%0, %2}
13407    rol{b}\t{%b2, %0|%0, %b2}"
13408   [(set_attr "type" "rotate")
13409    (set_attr "mode" "QI")])
13410
13411 (define_expand "rotrdi3"
13412   [(set (match_operand:DI 0 "shiftdi_operand" "")
13413         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13414                    (match_operand:QI 2 "nonmemory_operand" "")))
13415    (clobber (reg:CC FLAGS_REG))]
13416  ""
13417 {
13418   if (TARGET_64BIT)
13419     {
13420       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13421       DONE;
13422     }
13423   if (!const_1_to_31_operand (operands[2], VOIDmode))
13424     FAIL;
13425   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13426   DONE;
13427 })
13428
13429 ;; Implement rotation using two double-precision shift instructions
13430 ;; and a scratch register.
13431 (define_insn_and_split "ix86_rotrdi3"
13432  [(set (match_operand:DI 0 "register_operand" "=r")
13433        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13434                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13435   (clobber (reg:CC FLAGS_REG))
13436   (clobber (match_scratch:SI 3 "=&r"))]
13437  "!TARGET_64BIT"
13438  ""
13439  "&& reload_completed"
13440  [(set (match_dup 3) (match_dup 4))
13441   (parallel
13442    [(set (match_dup 4)
13443          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13444                  (ashift:SI (match_dup 5)
13445                             (minus:QI (const_int 32) (match_dup 2)))))
13446     (clobber (reg:CC FLAGS_REG))])
13447   (parallel
13448    [(set (match_dup 5)
13449          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13450                  (ashift:SI (match_dup 3)
13451                             (minus:QI (const_int 32) (match_dup 2)))))
13452     (clobber (reg:CC FLAGS_REG))])]
13453  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13454
13455 (define_insn "*rotrdi3_1_one_bit_rex64"
13456   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13457         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13458                      (match_operand:QI 2 "const1_operand" "")))
13459    (clobber (reg:CC FLAGS_REG))]
13460   "TARGET_64BIT
13461    && (TARGET_SHIFT1 || optimize_size)
13462    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13463   "ror{q}\t%0"
13464   [(set_attr "type" "rotate")
13465    (set (attr "length")
13466      (if_then_else (match_operand:DI 0 "register_operand" "")
13467         (const_string "2")
13468         (const_string "*")))])
13469
13470 (define_insn "*rotrdi3_1_rex64"
13471   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13472         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13473                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13474    (clobber (reg:CC FLAGS_REG))]
13475   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13476   "@
13477    ror{q}\t{%2, %0|%0, %2}
13478    ror{q}\t{%b2, %0|%0, %b2}"
13479   [(set_attr "type" "rotate")
13480    (set_attr "mode" "DI")])
13481
13482 (define_expand "rotrsi3"
13483   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13484         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13485                      (match_operand:QI 2 "nonmemory_operand" "")))
13486    (clobber (reg:CC FLAGS_REG))]
13487   ""
13488   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13489
13490 (define_insn "*rotrsi3_1_one_bit"
13491   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13492         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13493                      (match_operand:QI 2 "const1_operand" "")))
13494    (clobber (reg:CC FLAGS_REG))]
13495   "(TARGET_SHIFT1 || optimize_size)
13496    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13497   "ror{l}\t%0"
13498   [(set_attr "type" "rotate")
13499    (set (attr "length")
13500      (if_then_else (match_operand:SI 0 "register_operand" "")
13501         (const_string "2")
13502         (const_string "*")))])
13503
13504 (define_insn "*rotrsi3_1_one_bit_zext"
13505   [(set (match_operand:DI 0 "register_operand" "=r")
13506         (zero_extend:DI
13507           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13508                        (match_operand:QI 2 "const1_operand" ""))))
13509    (clobber (reg:CC FLAGS_REG))]
13510   "TARGET_64BIT
13511    && (TARGET_SHIFT1 || optimize_size)
13512    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13513   "ror{l}\t%k0"
13514   [(set_attr "type" "rotate")
13515    (set (attr "length")
13516      (if_then_else (match_operand:SI 0 "register_operand" "")
13517         (const_string "2")
13518         (const_string "*")))])
13519
13520 (define_insn "*rotrsi3_1"
13521   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13522         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13523                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13524    (clobber (reg:CC FLAGS_REG))]
13525   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13526   "@
13527    ror{l}\t{%2, %0|%0, %2}
13528    ror{l}\t{%b2, %0|%0, %b2}"
13529   [(set_attr "type" "rotate")
13530    (set_attr "mode" "SI")])
13531
13532 (define_insn "*rotrsi3_1_zext"
13533   [(set (match_operand:DI 0 "register_operand" "=r,r")
13534         (zero_extend:DI
13535           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13536                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13537    (clobber (reg:CC FLAGS_REG))]
13538   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13539   "@
13540    ror{l}\t{%2, %k0|%k0, %2}
13541    ror{l}\t{%b2, %k0|%k0, %b2}"
13542   [(set_attr "type" "rotate")
13543    (set_attr "mode" "SI")])
13544
13545 (define_expand "rotrhi3"
13546   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13547         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13548                      (match_operand:QI 2 "nonmemory_operand" "")))
13549    (clobber (reg:CC FLAGS_REG))]
13550   "TARGET_HIMODE_MATH"
13551   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13552
13553 (define_insn "*rotrhi3_one_bit"
13554   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13555         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13556                      (match_operand:QI 2 "const1_operand" "")))
13557    (clobber (reg:CC FLAGS_REG))]
13558   "(TARGET_SHIFT1 || optimize_size)
13559    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13560   "ror{w}\t%0"
13561   [(set_attr "type" "rotate")
13562    (set (attr "length")
13563      (if_then_else (match_operand 0 "register_operand" "")
13564         (const_string "2")
13565         (const_string "*")))])
13566
13567 (define_insn "*rotrhi3_1"
13568   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13569         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13570                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13571    (clobber (reg:CC FLAGS_REG))]
13572   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13573   "@
13574    ror{w}\t{%2, %0|%0, %2}
13575    ror{w}\t{%b2, %0|%0, %b2}"
13576   [(set_attr "type" "rotate")
13577    (set_attr "mode" "HI")])
13578
13579 (define_split
13580  [(set (match_operand:HI 0 "register_operand" "")
13581        (rotatert:HI (match_dup 0) (const_int 8)))
13582   (clobber (reg:CC FLAGS_REG))]
13583  "reload_completed"
13584  [(parallel [(set (strict_low_part (match_dup 0))
13585                   (bswap:HI (match_dup 0)))
13586              (clobber (reg:CC FLAGS_REG))])]
13587  "")
13588
13589 (define_expand "rotrqi3"
13590   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13591         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13592                      (match_operand:QI 2 "nonmemory_operand" "")))
13593    (clobber (reg:CC FLAGS_REG))]
13594   "TARGET_QIMODE_MATH"
13595   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13596
13597 (define_insn "*rotrqi3_1_one_bit"
13598   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13599         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13600                      (match_operand:QI 2 "const1_operand" "")))
13601    (clobber (reg:CC FLAGS_REG))]
13602   "(TARGET_SHIFT1 || optimize_size)
13603    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13604   "ror{b}\t%0"
13605   [(set_attr "type" "rotate")
13606    (set (attr "length")
13607      (if_then_else (match_operand 0 "register_operand" "")
13608         (const_string "2")
13609         (const_string "*")))])
13610
13611 (define_insn "*rotrqi3_1_one_bit_slp"
13612   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13613         (rotatert:QI (match_dup 0)
13614                      (match_operand:QI 1 "const1_operand" "")))
13615    (clobber (reg:CC FLAGS_REG))]
13616   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13617    && (TARGET_SHIFT1 || optimize_size)"
13618   "ror{b}\t%0"
13619   [(set_attr "type" "rotate1")
13620    (set (attr "length")
13621      (if_then_else (match_operand 0 "register_operand" "")
13622         (const_string "2")
13623         (const_string "*")))])
13624
13625 (define_insn "*rotrqi3_1"
13626   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13627         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13628                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13629    (clobber (reg:CC FLAGS_REG))]
13630   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13631   "@
13632    ror{b}\t{%2, %0|%0, %2}
13633    ror{b}\t{%b2, %0|%0, %b2}"
13634   [(set_attr "type" "rotate")
13635    (set_attr "mode" "QI")])
13636
13637 (define_insn "*rotrqi3_1_slp"
13638   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13639         (rotatert:QI (match_dup 0)
13640                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13641    (clobber (reg:CC FLAGS_REG))]
13642   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13643    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13644   "@
13645    ror{b}\t{%1, %0|%0, %1}
13646    ror{b}\t{%b1, %0|%0, %b1}"
13647   [(set_attr "type" "rotate1")
13648    (set_attr "mode" "QI")])
13649 \f
13650 ;; Bit set / bit test instructions
13651
13652 (define_expand "extv"
13653   [(set (match_operand:SI 0 "register_operand" "")
13654         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13655                          (match_operand:SI 2 "const8_operand" "")
13656                          (match_operand:SI 3 "const8_operand" "")))]
13657   ""
13658 {
13659   /* Handle extractions from %ah et al.  */
13660   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13661     FAIL;
13662
13663   /* From mips.md: extract_bit_field doesn't verify that our source
13664      matches the predicate, so check it again here.  */
13665   if (! ext_register_operand (operands[1], VOIDmode))
13666     FAIL;
13667 })
13668
13669 (define_expand "extzv"
13670   [(set (match_operand:SI 0 "register_operand" "")
13671         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13672                          (match_operand:SI 2 "const8_operand" "")
13673                          (match_operand:SI 3 "const8_operand" "")))]
13674   ""
13675 {
13676   /* Handle extractions from %ah et al.  */
13677   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13678     FAIL;
13679
13680   /* From mips.md: extract_bit_field doesn't verify that our source
13681      matches the predicate, so check it again here.  */
13682   if (! ext_register_operand (operands[1], VOIDmode))
13683     FAIL;
13684 })
13685
13686 (define_expand "insv"
13687   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13688                       (match_operand 1 "const8_operand" "")
13689                       (match_operand 2 "const8_operand" ""))
13690         (match_operand 3 "register_operand" ""))]
13691   ""
13692 {
13693   /* Handle insertions to %ah et al.  */
13694   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13695     FAIL;
13696
13697   /* From mips.md: insert_bit_field doesn't verify that our source
13698      matches the predicate, so check it again here.  */
13699   if (! ext_register_operand (operands[0], VOIDmode))
13700     FAIL;
13701
13702   if (TARGET_64BIT)
13703     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13704   else
13705     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13706
13707   DONE;
13708 })
13709
13710 ;; %%% bts, btr, btc, bt.
13711 ;; In general these instructions are *slow* when applied to memory,
13712 ;; since they enforce atomic operation.  When applied to registers,
13713 ;; it depends on the cpu implementation.  They're never faster than
13714 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13715 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13716 ;; within the instruction itself, so operating on bits in the high
13717 ;; 32-bits of a register becomes easier.
13718 ;;
13719 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13720 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13721 ;; negdf respectively, so they can never be disabled entirely.
13722
13723 (define_insn "*btsq"
13724   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13725                          (const_int 1)
13726                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13727         (const_int 1))
13728    (clobber (reg:CC FLAGS_REG))]
13729   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13730   "bts{q} %1,%0"
13731   [(set_attr "type" "alu1")])
13732
13733 (define_insn "*btrq"
13734   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13735                          (const_int 1)
13736                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13737         (const_int 0))
13738    (clobber (reg:CC FLAGS_REG))]
13739   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13740   "btr{q} %1,%0"
13741   [(set_attr "type" "alu1")])
13742
13743 (define_insn "*btcq"
13744   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13745                          (const_int 1)
13746                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13747         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13748    (clobber (reg:CC FLAGS_REG))]
13749   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13750   "btc{q} %1,%0"
13751   [(set_attr "type" "alu1")])
13752
13753 ;; Allow Nocona to avoid these instructions if a register is available.
13754
13755 (define_peephole2
13756   [(match_scratch:DI 2 "r")
13757    (parallel [(set (zero_extract:DI
13758                      (match_operand:DI 0 "register_operand" "")
13759                      (const_int 1)
13760                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13761                    (const_int 1))
13762               (clobber (reg:CC FLAGS_REG))])]
13763   "TARGET_64BIT && !TARGET_USE_BT"
13764   [(const_int 0)]
13765 {
13766   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13767   rtx op1;
13768
13769   if (HOST_BITS_PER_WIDE_INT >= 64)
13770     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13771   else if (i < HOST_BITS_PER_WIDE_INT)
13772     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13773   else
13774     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13775
13776   op1 = immed_double_const (lo, hi, DImode);
13777   if (i >= 31)
13778     {
13779       emit_move_insn (operands[2], op1);
13780       op1 = operands[2];
13781     }
13782
13783   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13784   DONE;
13785 })
13786
13787 (define_peephole2
13788   [(match_scratch:DI 2 "r")
13789    (parallel [(set (zero_extract:DI
13790                      (match_operand:DI 0 "register_operand" "")
13791                      (const_int 1)
13792                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13793                    (const_int 0))
13794               (clobber (reg:CC FLAGS_REG))])]
13795   "TARGET_64BIT && !TARGET_USE_BT"
13796   [(const_int 0)]
13797 {
13798   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13799   rtx op1;
13800
13801   if (HOST_BITS_PER_WIDE_INT >= 64)
13802     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13803   else if (i < HOST_BITS_PER_WIDE_INT)
13804     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13805   else
13806     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13807
13808   op1 = immed_double_const (~lo, ~hi, DImode);
13809   if (i >= 32)
13810     {
13811       emit_move_insn (operands[2], op1);
13812       op1 = operands[2];
13813     }
13814
13815   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13816   DONE;
13817 })
13818
13819 (define_peephole2
13820   [(match_scratch:DI 2 "r")
13821    (parallel [(set (zero_extract:DI
13822                      (match_operand:DI 0 "register_operand" "")
13823                      (const_int 1)
13824                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13825               (not:DI (zero_extract:DI
13826                         (match_dup 0) (const_int 1) (match_dup 1))))
13827               (clobber (reg:CC FLAGS_REG))])]
13828   "TARGET_64BIT && !TARGET_USE_BT"
13829   [(const_int 0)]
13830 {
13831   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13832   rtx op1;
13833
13834   if (HOST_BITS_PER_WIDE_INT >= 64)
13835     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13836   else if (i < HOST_BITS_PER_WIDE_INT)
13837     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13838   else
13839     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13840
13841   op1 = immed_double_const (lo, hi, DImode);
13842   if (i >= 31)
13843     {
13844       emit_move_insn (operands[2], op1);
13845       op1 = operands[2];
13846     }
13847
13848   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13849   DONE;
13850 })
13851 \f
13852 ;; Store-flag instructions.
13853
13854 ;; For all sCOND expanders, also expand the compare or test insn that
13855 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13856
13857 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13858 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13859 ;; way, which can later delete the movzx if only QImode is needed.
13860
13861 (define_expand "s<code>"
13862   [(set (match_operand:QI 0 "register_operand" "")
13863         (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13864   ""
13865   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13866
13867 (define_expand "s<code>"
13868   [(set (match_operand:QI 0 "register_operand" "")
13869         (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13870   "TARGET_80387 || TARGET_SSE"
13871   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13872
13873 (define_insn "*setcc_1"
13874   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13875         (match_operator:QI 1 "ix86_comparison_operator"
13876           [(reg FLAGS_REG) (const_int 0)]))]
13877   ""
13878   "set%C1\t%0"
13879   [(set_attr "type" "setcc")
13880    (set_attr "mode" "QI")])
13881
13882 (define_insn "*setcc_2"
13883   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13884         (match_operator:QI 1 "ix86_comparison_operator"
13885           [(reg FLAGS_REG) (const_int 0)]))]
13886   ""
13887   "set%C1\t%0"
13888   [(set_attr "type" "setcc")
13889    (set_attr "mode" "QI")])
13890
13891 ;; In general it is not safe to assume too much about CCmode registers,
13892 ;; so simplify-rtx stops when it sees a second one.  Under certain
13893 ;; conditions this is safe on x86, so help combine not create
13894 ;;
13895 ;;      seta    %al
13896 ;;      testb   %al, %al
13897 ;;      sete    %al
13898
13899 (define_split
13900   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13901         (ne:QI (match_operator 1 "ix86_comparison_operator"
13902                  [(reg FLAGS_REG) (const_int 0)])
13903             (const_int 0)))]
13904   ""
13905   [(set (match_dup 0) (match_dup 1))]
13906 {
13907   PUT_MODE (operands[1], QImode);
13908 })
13909
13910 (define_split
13911   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13912         (ne:QI (match_operator 1 "ix86_comparison_operator"
13913                  [(reg FLAGS_REG) (const_int 0)])
13914             (const_int 0)))]
13915   ""
13916   [(set (match_dup 0) (match_dup 1))]
13917 {
13918   PUT_MODE (operands[1], QImode);
13919 })
13920
13921 (define_split
13922   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13923         (eq:QI (match_operator 1 "ix86_comparison_operator"
13924                  [(reg FLAGS_REG) (const_int 0)])
13925             (const_int 0)))]
13926   ""
13927   [(set (match_dup 0) (match_dup 1))]
13928 {
13929   rtx new_op1 = copy_rtx (operands[1]);
13930   operands[1] = new_op1;
13931   PUT_MODE (new_op1, QImode);
13932   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13933                                              GET_MODE (XEXP (new_op1, 0))));
13934
13935   /* Make sure that (a) the CCmode we have for the flags is strong
13936      enough for the reversed compare or (b) we have a valid FP compare.  */
13937   if (! ix86_comparison_operator (new_op1, VOIDmode))
13938     FAIL;
13939 })
13940
13941 (define_split
13942   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13943         (eq:QI (match_operator 1 "ix86_comparison_operator"
13944                  [(reg FLAGS_REG) (const_int 0)])
13945             (const_int 0)))]
13946   ""
13947   [(set (match_dup 0) (match_dup 1))]
13948 {
13949   rtx new_op1 = copy_rtx (operands[1]);
13950   operands[1] = new_op1;
13951   PUT_MODE (new_op1, QImode);
13952   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13953                                              GET_MODE (XEXP (new_op1, 0))));
13954
13955   /* Make sure that (a) the CCmode we have for the flags is strong
13956      enough for the reversed compare or (b) we have a valid FP compare.  */
13957   if (! ix86_comparison_operator (new_op1, VOIDmode))
13958     FAIL;
13959 })
13960
13961 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13962 ;; subsequent logical operations are used to imitate conditional moves.
13963 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13964 ;; it directly.
13965
13966 (define_insn "*sse_setcc<mode>"
13967   [(set (match_operand:MODEF 0 "register_operand" "=x")
13968         (match_operator:MODEF 1 "sse_comparison_operator"
13969           [(match_operand:MODEF 2 "register_operand" "0")
13970            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13971   "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
13972   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13973   [(set_attr "type" "ssecmp")
13974    (set_attr "mode" "<MODE>")])
13975
13976 (define_insn "*sse5_setcc<mode>"
13977   [(set (match_operand:MODEF 0 "register_operand" "=x")
13978         (match_operator:MODEF 1 "sse5_comparison_float_operator"
13979           [(match_operand:MODEF 2 "register_operand" "x")
13980            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13981   "TARGET_SSE5"
13982   "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13983   [(set_attr "type" "sse4arg")
13984    (set_attr "mode" "<MODE>")])
13985
13986 \f
13987 ;; Basic conditional jump instructions.
13988 ;; We ignore the overflow flag for signed branch instructions.
13989
13990 ;; For all bCOND expanders, also expand the compare or test insn that
13991 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13992
13993 (define_expand "b<code>"
13994   [(set (pc)
13995         (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
13996                                    (const_int 0))
13997                       (label_ref (match_operand 0 ""))
13998                       (pc)))]
13999   ""
14000   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14001
14002 (define_expand "b<code>"
14003   [(set (pc)
14004         (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
14005                                   (const_int 0))
14006                       (label_ref (match_operand 0 ""))
14007                       (pc)))]
14008   "TARGET_80387 || TARGET_SSE_MATH"
14009   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14010
14011 (define_insn "*jcc_1"
14012   [(set (pc)
14013         (if_then_else (match_operator 1 "ix86_comparison_operator"
14014                                       [(reg FLAGS_REG) (const_int 0)])
14015                       (label_ref (match_operand 0 "" ""))
14016                       (pc)))]
14017   ""
14018   "%+j%C1\t%l0"
14019   [(set_attr "type" "ibr")
14020    (set_attr "modrm" "0")
14021    (set (attr "length")
14022            (if_then_else (and (ge (minus (match_dup 0) (pc))
14023                                   (const_int -126))
14024                               (lt (minus (match_dup 0) (pc))
14025                                   (const_int 128)))
14026              (const_int 2)
14027              (const_int 6)))])
14028
14029 (define_insn "*jcc_2"
14030   [(set (pc)
14031         (if_then_else (match_operator 1 "ix86_comparison_operator"
14032                                       [(reg FLAGS_REG) (const_int 0)])
14033                       (pc)
14034                       (label_ref (match_operand 0 "" ""))))]
14035   ""
14036   "%+j%c1\t%l0"
14037   [(set_attr "type" "ibr")
14038    (set_attr "modrm" "0")
14039    (set (attr "length")
14040            (if_then_else (and (ge (minus (match_dup 0) (pc))
14041                                   (const_int -126))
14042                               (lt (minus (match_dup 0) (pc))
14043                                   (const_int 128)))
14044              (const_int 2)
14045              (const_int 6)))])
14046
14047 ;; In general it is not safe to assume too much about CCmode registers,
14048 ;; so simplify-rtx stops when it sees a second one.  Under certain
14049 ;; conditions this is safe on x86, so help combine not create
14050 ;;
14051 ;;      seta    %al
14052 ;;      testb   %al, %al
14053 ;;      je      Lfoo
14054
14055 (define_split
14056   [(set (pc)
14057         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14058                                       [(reg FLAGS_REG) (const_int 0)])
14059                           (const_int 0))
14060                       (label_ref (match_operand 1 "" ""))
14061                       (pc)))]
14062   ""
14063   [(set (pc)
14064         (if_then_else (match_dup 0)
14065                       (label_ref (match_dup 1))
14066                       (pc)))]
14067 {
14068   PUT_MODE (operands[0], VOIDmode);
14069 })
14070
14071 (define_split
14072   [(set (pc)
14073         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14074                                       [(reg FLAGS_REG) (const_int 0)])
14075                           (const_int 0))
14076                       (label_ref (match_operand 1 "" ""))
14077                       (pc)))]
14078   ""
14079   [(set (pc)
14080         (if_then_else (match_dup 0)
14081                       (label_ref (match_dup 1))
14082                       (pc)))]
14083 {
14084   rtx new_op0 = copy_rtx (operands[0]);
14085   operands[0] = new_op0;
14086   PUT_MODE (new_op0, VOIDmode);
14087   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14088                                              GET_MODE (XEXP (new_op0, 0))));
14089
14090   /* Make sure that (a) the CCmode we have for the flags is strong
14091      enough for the reversed compare or (b) we have a valid FP compare.  */
14092   if (! ix86_comparison_operator (new_op0, VOIDmode))
14093     FAIL;
14094 })
14095
14096 ;; Define combination compare-and-branch fp compare instructions to use
14097 ;; during early optimization.  Splitting the operation apart early makes
14098 ;; for bad code when we want to reverse the operation.
14099
14100 (define_insn "*fp_jcc_1_mixed"
14101   [(set (pc)
14102         (if_then_else (match_operator 0 "comparison_operator"
14103                         [(match_operand 1 "register_operand" "f,x")
14104                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14105           (label_ref (match_operand 3 "" ""))
14106           (pc)))
14107    (clobber (reg:CCFP FPSR_REG))
14108    (clobber (reg:CCFP FLAGS_REG))]
14109   "TARGET_MIX_SSE_I387
14110    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14111    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14112    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14113   "#")
14114
14115 (define_insn "*fp_jcc_1_sse"
14116   [(set (pc)
14117         (if_then_else (match_operator 0 "comparison_operator"
14118                         [(match_operand 1 "register_operand" "x")
14119                          (match_operand 2 "nonimmediate_operand" "xm")])
14120           (label_ref (match_operand 3 "" ""))
14121           (pc)))
14122    (clobber (reg:CCFP FPSR_REG))
14123    (clobber (reg:CCFP FLAGS_REG))]
14124   "TARGET_SSE_MATH
14125    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14126    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14127    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14128   "#")
14129
14130 (define_insn "*fp_jcc_1_387"
14131   [(set (pc)
14132         (if_then_else (match_operator 0 "comparison_operator"
14133                         [(match_operand 1 "register_operand" "f")
14134                          (match_operand 2 "register_operand" "f")])
14135           (label_ref (match_operand 3 "" ""))
14136           (pc)))
14137    (clobber (reg:CCFP FPSR_REG))
14138    (clobber (reg:CCFP FLAGS_REG))]
14139   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14140    && TARGET_CMOVE
14141    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14142    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14143   "#")
14144
14145 (define_insn "*fp_jcc_2_mixed"
14146   [(set (pc)
14147         (if_then_else (match_operator 0 "comparison_operator"
14148                         [(match_operand 1 "register_operand" "f,x")
14149                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14150           (pc)
14151           (label_ref (match_operand 3 "" ""))))
14152    (clobber (reg:CCFP FPSR_REG))
14153    (clobber (reg:CCFP FLAGS_REG))]
14154   "TARGET_MIX_SSE_I387
14155    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14156    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14157    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14158   "#")
14159
14160 (define_insn "*fp_jcc_2_sse"
14161   [(set (pc)
14162         (if_then_else (match_operator 0 "comparison_operator"
14163                         [(match_operand 1 "register_operand" "x")
14164                          (match_operand 2 "nonimmediate_operand" "xm")])
14165           (pc)
14166           (label_ref (match_operand 3 "" ""))))
14167    (clobber (reg:CCFP FPSR_REG))
14168    (clobber (reg:CCFP FLAGS_REG))]
14169   "TARGET_SSE_MATH
14170    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14171    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14172    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14173   "#")
14174
14175 (define_insn "*fp_jcc_2_387"
14176   [(set (pc)
14177         (if_then_else (match_operator 0 "comparison_operator"
14178                         [(match_operand 1 "register_operand" "f")
14179                          (match_operand 2 "register_operand" "f")])
14180           (pc)
14181           (label_ref (match_operand 3 "" ""))))
14182    (clobber (reg:CCFP FPSR_REG))
14183    (clobber (reg:CCFP FLAGS_REG))]
14184   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14185    && TARGET_CMOVE
14186    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14187    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14188   "#")
14189
14190 (define_insn "*fp_jcc_3_387"
14191   [(set (pc)
14192         (if_then_else (match_operator 0 "comparison_operator"
14193                         [(match_operand 1 "register_operand" "f")
14194                          (match_operand 2 "nonimmediate_operand" "fm")])
14195           (label_ref (match_operand 3 "" ""))
14196           (pc)))
14197    (clobber (reg:CCFP FPSR_REG))
14198    (clobber (reg:CCFP FLAGS_REG))
14199    (clobber (match_scratch:HI 4 "=a"))]
14200   "TARGET_80387
14201    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14202    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14203    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14204    && SELECT_CC_MODE (GET_CODE (operands[0]),
14205                       operands[1], operands[2]) == CCFPmode
14206    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14207   "#")
14208
14209 (define_insn "*fp_jcc_4_387"
14210   [(set (pc)
14211         (if_then_else (match_operator 0 "comparison_operator"
14212                         [(match_operand 1 "register_operand" "f")
14213                          (match_operand 2 "nonimmediate_operand" "fm")])
14214           (pc)
14215           (label_ref (match_operand 3 "" ""))))
14216    (clobber (reg:CCFP FPSR_REG))
14217    (clobber (reg:CCFP FLAGS_REG))
14218    (clobber (match_scratch:HI 4 "=a"))]
14219   "TARGET_80387
14220    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14221    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14222    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14223    && SELECT_CC_MODE (GET_CODE (operands[0]),
14224                       operands[1], operands[2]) == CCFPmode
14225    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14226   "#")
14227
14228 (define_insn "*fp_jcc_5_387"
14229   [(set (pc)
14230         (if_then_else (match_operator 0 "comparison_operator"
14231                         [(match_operand 1 "register_operand" "f")
14232                          (match_operand 2 "register_operand" "f")])
14233           (label_ref (match_operand 3 "" ""))
14234           (pc)))
14235    (clobber (reg:CCFP FPSR_REG))
14236    (clobber (reg:CCFP FLAGS_REG))
14237    (clobber (match_scratch:HI 4 "=a"))]
14238   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14239    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14240    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14241   "#")
14242
14243 (define_insn "*fp_jcc_6_387"
14244   [(set (pc)
14245         (if_then_else (match_operator 0 "comparison_operator"
14246                         [(match_operand 1 "register_operand" "f")
14247                          (match_operand 2 "register_operand" "f")])
14248           (pc)
14249           (label_ref (match_operand 3 "" ""))))
14250    (clobber (reg:CCFP FPSR_REG))
14251    (clobber (reg:CCFP FLAGS_REG))
14252    (clobber (match_scratch:HI 4 "=a"))]
14253   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14254    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14255    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14256   "#")
14257
14258 (define_insn "*fp_jcc_7_387"
14259   [(set (pc)
14260         (if_then_else (match_operator 0 "comparison_operator"
14261                         [(match_operand 1 "register_operand" "f")
14262                          (match_operand 2 "const0_operand" "X")])
14263           (label_ref (match_operand 3 "" ""))
14264           (pc)))
14265    (clobber (reg:CCFP FPSR_REG))
14266    (clobber (reg:CCFP FLAGS_REG))
14267    (clobber (match_scratch:HI 4 "=a"))]
14268   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14269    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14270    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14271    && SELECT_CC_MODE (GET_CODE (operands[0]),
14272                       operands[1], operands[2]) == CCFPmode
14273    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14274   "#")
14275
14276 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14277 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14278 ;; with a precedence over other operators and is always put in the first
14279 ;; place. Swap condition and operands to match ficom instruction.
14280
14281 (define_insn "*fp_jcc_8<mode>_387"
14282   [(set (pc)
14283         (if_then_else (match_operator 0 "comparison_operator"
14284                         [(match_operator 1 "float_operator"
14285                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14286                            (match_operand 3 "register_operand" "f,f")])
14287           (label_ref (match_operand 4 "" ""))
14288           (pc)))
14289    (clobber (reg:CCFP FPSR_REG))
14290    (clobber (reg:CCFP FLAGS_REG))
14291    (clobber (match_scratch:HI 5 "=a,a"))]
14292   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14293    && TARGET_USE_<MODE>MODE_FIOP
14294    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14295    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14296    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14297    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14298   "#")
14299
14300 (define_split
14301   [(set (pc)
14302         (if_then_else (match_operator 0 "comparison_operator"
14303                         [(match_operand 1 "register_operand" "")
14304                          (match_operand 2 "nonimmediate_operand" "")])
14305           (match_operand 3 "" "")
14306           (match_operand 4 "" "")))
14307    (clobber (reg:CCFP FPSR_REG))
14308    (clobber (reg:CCFP FLAGS_REG))]
14309   "reload_completed"
14310   [(const_int 0)]
14311 {
14312   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14313                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14314   DONE;
14315 })
14316
14317 (define_split
14318   [(set (pc)
14319         (if_then_else (match_operator 0 "comparison_operator"
14320                         [(match_operand 1 "register_operand" "")
14321                          (match_operand 2 "general_operand" "")])
14322           (match_operand 3 "" "")
14323           (match_operand 4 "" "")))
14324    (clobber (reg:CCFP FPSR_REG))
14325    (clobber (reg:CCFP FLAGS_REG))
14326    (clobber (match_scratch:HI 5 "=a"))]
14327   "reload_completed"
14328   [(const_int 0)]
14329 {
14330   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14331                         operands[3], operands[4], operands[5], NULL_RTX);
14332   DONE;
14333 })
14334
14335 (define_split
14336   [(set (pc)
14337         (if_then_else (match_operator 0 "comparison_operator"
14338                         [(match_operator 1 "float_operator"
14339                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14340                            (match_operand 3 "register_operand" "")])
14341           (match_operand 4 "" "")
14342           (match_operand 5 "" "")))
14343    (clobber (reg:CCFP FPSR_REG))
14344    (clobber (reg:CCFP FLAGS_REG))
14345    (clobber (match_scratch:HI 6 "=a"))]
14346   "reload_completed"
14347   [(const_int 0)]
14348 {
14349   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14350   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14351                         operands[3], operands[7],
14352                         operands[4], operands[5], operands[6], NULL_RTX);
14353   DONE;
14354 })
14355
14356 ;; %%% Kill this when reload knows how to do it.
14357 (define_split
14358   [(set (pc)
14359         (if_then_else (match_operator 0 "comparison_operator"
14360                         [(match_operator 1 "float_operator"
14361                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14362                            (match_operand 3 "register_operand" "")])
14363           (match_operand 4 "" "")
14364           (match_operand 5 "" "")))
14365    (clobber (reg:CCFP FPSR_REG))
14366    (clobber (reg:CCFP FLAGS_REG))
14367    (clobber (match_scratch:HI 6 "=a"))]
14368   "reload_completed"
14369   [(const_int 0)]
14370 {
14371   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14372   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14373   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14374                         operands[3], operands[7],
14375                         operands[4], operands[5], operands[6], operands[2]);
14376   DONE;
14377 })
14378 \f
14379 ;; Unconditional and other jump instructions
14380
14381 (define_insn "jump"
14382   [(set (pc)
14383         (label_ref (match_operand 0 "" "")))]
14384   ""
14385   "jmp\t%l0"
14386   [(set_attr "type" "ibr")
14387    (set (attr "length")
14388            (if_then_else (and (ge (minus (match_dup 0) (pc))
14389                                   (const_int -126))
14390                               (lt (minus (match_dup 0) (pc))
14391                                   (const_int 128)))
14392              (const_int 2)
14393              (const_int 5)))
14394    (set_attr "modrm" "0")])
14395
14396 (define_expand "indirect_jump"
14397   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14398   ""
14399   "")
14400
14401 (define_insn "*indirect_jump"
14402   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14403   "!TARGET_64BIT"
14404   "jmp\t%A0"
14405   [(set_attr "type" "ibr")
14406    (set_attr "length_immediate" "0")])
14407
14408 (define_insn "*indirect_jump_rtx64"
14409   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14410   "TARGET_64BIT"
14411   "jmp\t%A0"
14412   [(set_attr "type" "ibr")
14413    (set_attr "length_immediate" "0")])
14414
14415 (define_expand "tablejump"
14416   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14417               (use (label_ref (match_operand 1 "" "")))])]
14418   ""
14419 {
14420   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14421      relative.  Convert the relative address to an absolute address.  */
14422   if (flag_pic)
14423     {
14424       rtx op0, op1;
14425       enum rtx_code code;
14426
14427       /* We can't use @GOTOFF for text labels on VxWorks;
14428          see gotoff_operand.  */
14429       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14430         {
14431           code = PLUS;
14432           op0 = operands[0];
14433           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14434         }
14435       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14436         {
14437           code = PLUS;
14438           op0 = operands[0];
14439           op1 = pic_offset_table_rtx;
14440         }
14441       else
14442         {
14443           code = MINUS;
14444           op0 = pic_offset_table_rtx;
14445           op1 = operands[0];
14446         }
14447
14448       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14449                                          OPTAB_DIRECT);
14450     }
14451 })
14452
14453 (define_insn "*tablejump_1"
14454   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14455    (use (label_ref (match_operand 1 "" "")))]
14456   "!TARGET_64BIT"
14457   "jmp\t%A0"
14458   [(set_attr "type" "ibr")
14459    (set_attr "length_immediate" "0")])
14460
14461 (define_insn "*tablejump_1_rtx64"
14462   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14463    (use (label_ref (match_operand 1 "" "")))]
14464   "TARGET_64BIT"
14465   "jmp\t%A0"
14466   [(set_attr "type" "ibr")
14467    (set_attr "length_immediate" "0")])
14468 \f
14469 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14470
14471 (define_peephole2
14472   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14473    (set (match_operand:QI 1 "register_operand" "")
14474         (match_operator:QI 2 "ix86_comparison_operator"
14475           [(reg FLAGS_REG) (const_int 0)]))
14476    (set (match_operand 3 "q_regs_operand" "")
14477         (zero_extend (match_dup 1)))]
14478   "(peep2_reg_dead_p (3, operands[1])
14479     || operands_match_p (operands[1], operands[3]))
14480    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14481   [(set (match_dup 4) (match_dup 0))
14482    (set (strict_low_part (match_dup 5))
14483         (match_dup 2))]
14484 {
14485   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14486   operands[5] = gen_lowpart (QImode, operands[3]);
14487   ix86_expand_clear (operands[3]);
14488 })
14489
14490 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14491
14492 (define_peephole2
14493   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14494    (set (match_operand:QI 1 "register_operand" "")
14495         (match_operator:QI 2 "ix86_comparison_operator"
14496           [(reg FLAGS_REG) (const_int 0)]))
14497    (parallel [(set (match_operand 3 "q_regs_operand" "")
14498                    (zero_extend (match_dup 1)))
14499               (clobber (reg:CC FLAGS_REG))])]
14500   "(peep2_reg_dead_p (3, operands[1])
14501     || operands_match_p (operands[1], operands[3]))
14502    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14503   [(set (match_dup 4) (match_dup 0))
14504    (set (strict_low_part (match_dup 5))
14505         (match_dup 2))]
14506 {
14507   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14508   operands[5] = gen_lowpart (QImode, operands[3]);
14509   ix86_expand_clear (operands[3]);
14510 })
14511 \f
14512 ;; Call instructions.
14513
14514 ;; The predicates normally associated with named expanders are not properly
14515 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14516 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14517
14518 ;; Call subroutine returning no value.
14519
14520 (define_expand "call_pop"
14521   [(parallel [(call (match_operand:QI 0 "" "")
14522                     (match_operand:SI 1 "" ""))
14523               (set (reg:SI SP_REG)
14524                    (plus:SI (reg:SI SP_REG)
14525                             (match_operand:SI 3 "" "")))])]
14526   "!TARGET_64BIT"
14527 {
14528   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14529   DONE;
14530 })
14531
14532 (define_insn "*call_pop_0"
14533   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14534          (match_operand:SI 1 "" ""))
14535    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14536                             (match_operand:SI 2 "immediate_operand" "")))]
14537   "!TARGET_64BIT"
14538 {
14539   if (SIBLING_CALL_P (insn))
14540     return "jmp\t%P0";
14541   else
14542     return "call\t%P0";
14543 }
14544   [(set_attr "type" "call")])
14545
14546 (define_insn "*call_pop_1"
14547   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14548          (match_operand:SI 1 "" ""))
14549    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14550                             (match_operand:SI 2 "immediate_operand" "i")))]
14551   "!TARGET_64BIT"
14552 {
14553   if (constant_call_address_operand (operands[0], Pmode))
14554     {
14555       if (SIBLING_CALL_P (insn))
14556         return "jmp\t%P0";
14557       else
14558         return "call\t%P0";
14559     }
14560   if (SIBLING_CALL_P (insn))
14561     return "jmp\t%A0";
14562   else
14563     return "call\t%A0";
14564 }
14565   [(set_attr "type" "call")])
14566
14567 (define_expand "call"
14568   [(call (match_operand:QI 0 "" "")
14569          (match_operand 1 "" ""))
14570    (use (match_operand 2 "" ""))]
14571   ""
14572 {
14573   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14574   DONE;
14575 })
14576
14577 (define_expand "sibcall"
14578   [(call (match_operand:QI 0 "" "")
14579          (match_operand 1 "" ""))
14580    (use (match_operand 2 "" ""))]
14581   ""
14582 {
14583   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14584   DONE;
14585 })
14586
14587 (define_insn "*call_0"
14588   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14589          (match_operand 1 "" ""))]
14590   ""
14591 {
14592   if (SIBLING_CALL_P (insn))
14593     return "jmp\t%P0";
14594   else
14595     return "call\t%P0";
14596 }
14597   [(set_attr "type" "call")])
14598
14599 (define_insn "*call_1"
14600   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14601          (match_operand 1 "" ""))]
14602   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14603 {
14604   if (constant_call_address_operand (operands[0], Pmode))
14605     return "call\t%P0";
14606   return "call\t%A0";
14607 }
14608   [(set_attr "type" "call")])
14609
14610 (define_insn "*sibcall_1"
14611   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14612          (match_operand 1 "" ""))]
14613   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14614 {
14615   if (constant_call_address_operand (operands[0], Pmode))
14616     return "jmp\t%P0";
14617   return "jmp\t%A0";
14618 }
14619   [(set_attr "type" "call")])
14620
14621 (define_insn "*call_1_rex64"
14622   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14623          (match_operand 1 "" ""))]
14624   "!SIBLING_CALL_P (insn) && TARGET_64BIT
14625    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14626 {
14627   if (constant_call_address_operand (operands[0], Pmode))
14628     return "call\t%P0";
14629   return "call\t%A0";
14630 }
14631   [(set_attr "type" "call")])
14632
14633 (define_insn "*call_1_rex64_large"
14634   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14635          (match_operand 1 "" ""))]
14636   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14637   "call\t%A0"
14638   [(set_attr "type" "call")])
14639
14640 (define_insn "*sibcall_1_rex64"
14641   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14642          (match_operand 1 "" ""))]
14643   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14644   "jmp\t%P0"
14645   [(set_attr "type" "call")])
14646
14647 (define_insn "*sibcall_1_rex64_v"
14648   [(call (mem:QI (reg:DI R11_REG))
14649          (match_operand 0 "" ""))]
14650   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14651   "jmp\t{*%%}r11"
14652   [(set_attr "type" "call")])
14653
14654
14655 ;; Call subroutine, returning value in operand 0
14656
14657 (define_expand "call_value_pop"
14658   [(parallel [(set (match_operand 0 "" "")
14659                    (call (match_operand:QI 1 "" "")
14660                          (match_operand:SI 2 "" "")))
14661               (set (reg:SI SP_REG)
14662                    (plus:SI (reg:SI SP_REG)
14663                             (match_operand:SI 4 "" "")))])]
14664   "!TARGET_64BIT"
14665 {
14666   ix86_expand_call (operands[0], operands[1], operands[2],
14667                     operands[3], operands[4], 0);
14668   DONE;
14669 })
14670
14671 (define_expand "call_value"
14672   [(set (match_operand 0 "" "")
14673         (call (match_operand:QI 1 "" "")
14674               (match_operand:SI 2 "" "")))
14675    (use (match_operand:SI 3 "" ""))]
14676   ;; Operand 2 not used on the i386.
14677   ""
14678 {
14679   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14680   DONE;
14681 })
14682
14683 (define_expand "sibcall_value"
14684   [(set (match_operand 0 "" "")
14685         (call (match_operand:QI 1 "" "")
14686               (match_operand:SI 2 "" "")))
14687    (use (match_operand:SI 3 "" ""))]
14688   ;; Operand 2 not used on the i386.
14689   ""
14690 {
14691   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14692   DONE;
14693 })
14694
14695 ;; Call subroutine returning any type.
14696
14697 (define_expand "untyped_call"
14698   [(parallel [(call (match_operand 0 "" "")
14699                     (const_int 0))
14700               (match_operand 1 "" "")
14701               (match_operand 2 "" "")])]
14702   ""
14703 {
14704   int i;
14705
14706   /* In order to give reg-stack an easier job in validating two
14707      coprocessor registers as containing a possible return value,
14708      simply pretend the untyped call returns a complex long double
14709      value.  */
14710
14711   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14712                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14713                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14714                     NULL, 0);
14715
14716   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14717     {
14718       rtx set = XVECEXP (operands[2], 0, i);
14719       emit_move_insn (SET_DEST (set), SET_SRC (set));
14720     }
14721
14722   /* The optimizer does not know that the call sets the function value
14723      registers we stored in the result block.  We avoid problems by
14724      claiming that all hard registers are used and clobbered at this
14725      point.  */
14726   emit_insn (gen_blockage ());
14727
14728   DONE;
14729 })
14730 \f
14731 ;; Prologue and epilogue instructions
14732
14733 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14734 ;; all of memory.  This blocks insns from being moved across this point.
14735
14736 (define_insn "blockage"
14737   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14738   ""
14739   ""
14740   [(set_attr "length" "0")])
14741
14742 ;; As USE insns aren't meaningful after reload, this is used instead
14743 ;; to prevent deleting instructions setting registers for PIC code
14744 (define_insn "prologue_use"
14745   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14746   ""
14747   ""
14748   [(set_attr "length" "0")])
14749
14750 ;; Insn emitted into the body of a function to return from a function.
14751 ;; This is only done if the function's epilogue is known to be simple.
14752 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14753
14754 (define_expand "return"
14755   [(return)]
14756   "ix86_can_use_return_insn_p ()"
14757 {
14758   if (crtl->args.pops_args)
14759     {
14760       rtx popc = GEN_INT (crtl->args.pops_args);
14761       emit_jump_insn (gen_return_pop_internal (popc));
14762       DONE;
14763     }
14764 })
14765
14766 (define_insn "return_internal"
14767   [(return)]
14768   "reload_completed"
14769   "ret"
14770   [(set_attr "length" "1")
14771    (set_attr "length_immediate" "0")
14772    (set_attr "modrm" "0")])
14773
14774 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14775 ;; instruction Athlon and K8 have.
14776
14777 (define_insn "return_internal_long"
14778   [(return)
14779    (unspec [(const_int 0)] UNSPEC_REP)]
14780   "reload_completed"
14781   "rep\;ret"
14782   [(set_attr "length" "1")
14783    (set_attr "length_immediate" "0")
14784    (set_attr "prefix_rep" "1")
14785    (set_attr "modrm" "0")])
14786
14787 (define_insn "return_pop_internal"
14788   [(return)
14789    (use (match_operand:SI 0 "const_int_operand" ""))]
14790   "reload_completed"
14791   "ret\t%0"
14792   [(set_attr "length" "3")
14793    (set_attr "length_immediate" "2")
14794    (set_attr "modrm" "0")])
14795
14796 (define_insn "return_indirect_internal"
14797   [(return)
14798    (use (match_operand:SI 0 "register_operand" "r"))]
14799   "reload_completed"
14800   "jmp\t%A0"
14801   [(set_attr "type" "ibr")
14802    (set_attr "length_immediate" "0")])
14803
14804 (define_insn "nop"
14805   [(const_int 0)]
14806   ""
14807   "nop"
14808   [(set_attr "length" "1")
14809    (set_attr "length_immediate" "0")
14810    (set_attr "modrm" "0")])
14811
14812 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14813 ;; branch prediction penalty for the third jump in a 16-byte
14814 ;; block on K8.
14815
14816 (define_insn "align"
14817   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14818   ""
14819 {
14820 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14821   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14822 #else
14823   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14824      The align insn is used to avoid 3 jump instructions in the row to improve
14825      branch prediction and the benefits hardly outweigh the cost of extra 8
14826      nops on the average inserted by full alignment pseudo operation.  */
14827 #endif
14828   return "";
14829 }
14830   [(set_attr "length" "16")])
14831
14832 (define_expand "prologue"
14833   [(const_int 0)]
14834   ""
14835   "ix86_expand_prologue (); DONE;")
14836
14837 (define_insn "set_got"
14838   [(set (match_operand:SI 0 "register_operand" "=r")
14839         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14840    (clobber (reg:CC FLAGS_REG))]
14841   "!TARGET_64BIT"
14842   { return output_set_got (operands[0], NULL_RTX); }
14843   [(set_attr "type" "multi")
14844    (set_attr "length" "12")])
14845
14846 (define_insn "set_got_labelled"
14847   [(set (match_operand:SI 0 "register_operand" "=r")
14848         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14849          UNSPEC_SET_GOT))
14850    (clobber (reg:CC FLAGS_REG))]
14851   "!TARGET_64BIT"
14852   { return output_set_got (operands[0], operands[1]); }
14853   [(set_attr "type" "multi")
14854    (set_attr "length" "12")])
14855
14856 (define_insn "set_got_rex64"
14857   [(set (match_operand:DI 0 "register_operand" "=r")
14858         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14859   "TARGET_64BIT"
14860   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14861   [(set_attr "type" "lea")
14862    (set_attr "length" "6")])
14863
14864 (define_insn "set_rip_rex64"
14865   [(set (match_operand:DI 0 "register_operand" "=r")
14866         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14867   "TARGET_64BIT"
14868   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
14869   [(set_attr "type" "lea")
14870    (set_attr "length" "6")])
14871
14872 (define_insn "set_got_offset_rex64"
14873   [(set (match_operand:DI 0 "register_operand" "=r")
14874         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
14875   "TARGET_64BIT"
14876   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
14877   [(set_attr "type" "imov")
14878    (set_attr "length" "11")])
14879
14880 (define_expand "epilogue"
14881   [(const_int 0)]
14882   ""
14883   "ix86_expand_epilogue (1); DONE;")
14884
14885 (define_expand "sibcall_epilogue"
14886   [(const_int 0)]
14887   ""
14888   "ix86_expand_epilogue (0); DONE;")
14889
14890 (define_expand "eh_return"
14891   [(use (match_operand 0 "register_operand" ""))]
14892   ""
14893 {
14894   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14895
14896   /* Tricky bit: we write the address of the handler to which we will
14897      be returning into someone else's stack frame, one word below the
14898      stack address we wish to restore.  */
14899   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14900   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14901   tmp = gen_rtx_MEM (Pmode, tmp);
14902   emit_move_insn (tmp, ra);
14903
14904   if (Pmode == SImode)
14905     emit_jump_insn (gen_eh_return_si (sa));
14906   else
14907     emit_jump_insn (gen_eh_return_di (sa));
14908   emit_barrier ();
14909   DONE;
14910 })
14911
14912 (define_insn_and_split "eh_return_si"
14913   [(set (pc)
14914         (unspec [(match_operand:SI 0 "register_operand" "c")]
14915                  UNSPEC_EH_RETURN))]
14916   "!TARGET_64BIT"
14917   "#"
14918   "reload_completed"
14919   [(const_int 0)]
14920   "ix86_expand_epilogue (2); DONE;")
14921
14922 (define_insn_and_split "eh_return_di"
14923   [(set (pc)
14924         (unspec [(match_operand:DI 0 "register_operand" "c")]
14925                  UNSPEC_EH_RETURN))]
14926   "TARGET_64BIT"
14927   "#"
14928   "reload_completed"
14929   [(const_int 0)]
14930   "ix86_expand_epilogue (2); DONE;")
14931
14932 (define_insn "leave"
14933   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14934    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14935    (clobber (mem:BLK (scratch)))]
14936   "!TARGET_64BIT"
14937   "leave"
14938   [(set_attr "type" "leave")])
14939
14940 (define_insn "leave_rex64"
14941   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14942    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14943    (clobber (mem:BLK (scratch)))]
14944   "TARGET_64BIT"
14945   "leave"
14946   [(set_attr "type" "leave")])
14947 \f
14948 (define_expand "ffssi2"
14949   [(parallel
14950      [(set (match_operand:SI 0 "register_operand" "")
14951            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14952       (clobber (match_scratch:SI 2 ""))
14953       (clobber (reg:CC FLAGS_REG))])]
14954   ""
14955 {
14956   if (TARGET_CMOVE)
14957     {
14958       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
14959       DONE;
14960     }
14961 })
14962
14963 (define_expand "ffs_cmove"
14964   [(set (match_dup 2) (const_int -1))
14965    (parallel [(set (reg:CCZ FLAGS_REG)
14966                    (compare:CCZ (match_operand:SI 1 "register_operand" "")
14967                                 (const_int 0)))
14968               (set (match_operand:SI 0 "nonimmediate_operand" "")
14969                    (ctz:SI (match_dup 1)))])
14970    (set (match_dup 0) (if_then_else:SI
14971                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14972                         (match_dup 2)
14973                         (match_dup 0)))
14974    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14975               (clobber (reg:CC FLAGS_REG))])]
14976   "TARGET_CMOVE"
14977   "operands[2] = gen_reg_rtx (SImode);")
14978
14979 (define_insn_and_split "*ffs_no_cmove"
14980   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14981         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14982    (clobber (match_scratch:SI 2 "=&q"))
14983    (clobber (reg:CC FLAGS_REG))]
14984   "!TARGET_CMOVE"
14985   "#"
14986   "&& reload_completed"
14987   [(parallel [(set (reg:CCZ FLAGS_REG)
14988                    (compare:CCZ (match_dup 1) (const_int 0)))
14989               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14990    (set (strict_low_part (match_dup 3))
14991         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14992    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14993               (clobber (reg:CC FLAGS_REG))])
14994    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14995               (clobber (reg:CC FLAGS_REG))])
14996    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14997               (clobber (reg:CC FLAGS_REG))])]
14998 {
14999   operands[3] = gen_lowpart (QImode, operands[2]);
15000   ix86_expand_clear (operands[2]);
15001 })
15002
15003 (define_insn "*ffssi_1"
15004   [(set (reg:CCZ FLAGS_REG)
15005         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15006                      (const_int 0)))
15007    (set (match_operand:SI 0 "register_operand" "=r")
15008         (ctz:SI (match_dup 1)))]
15009   ""
15010   "bsf{l}\t{%1, %0|%0, %1}"
15011   [(set_attr "prefix_0f" "1")])
15012
15013 (define_expand "ffsdi2"
15014   [(set (match_dup 2) (const_int -1))
15015    (parallel [(set (reg:CCZ FLAGS_REG)
15016                    (compare:CCZ (match_operand:DI 1 "register_operand" "")
15017                                 (const_int 0)))
15018               (set (match_operand:DI 0 "nonimmediate_operand" "")
15019                    (ctz:DI (match_dup 1)))])
15020    (set (match_dup 0) (if_then_else:DI
15021                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15022                         (match_dup 2)
15023                         (match_dup 0)))
15024    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15025               (clobber (reg:CC FLAGS_REG))])]
15026   "TARGET_64BIT"
15027   "operands[2] = gen_reg_rtx (DImode);")
15028
15029 (define_insn "*ffsdi_1"
15030   [(set (reg:CCZ FLAGS_REG)
15031         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15032                      (const_int 0)))
15033    (set (match_operand:DI 0 "register_operand" "=r")
15034         (ctz:DI (match_dup 1)))]
15035   "TARGET_64BIT"
15036   "bsf{q}\t{%1, %0|%0, %1}"
15037   [(set_attr "prefix_0f" "1")])
15038
15039 (define_insn "ctzsi2"
15040   [(set (match_operand:SI 0 "register_operand" "=r")
15041         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15042    (clobber (reg:CC FLAGS_REG))]
15043   ""
15044   "bsf{l}\t{%1, %0|%0, %1}"
15045   [(set_attr "prefix_0f" "1")])
15046
15047 (define_insn "ctzdi2"
15048   [(set (match_operand:DI 0 "register_operand" "=r")
15049         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15050    (clobber (reg:CC FLAGS_REG))]
15051   "TARGET_64BIT"
15052   "bsf{q}\t{%1, %0|%0, %1}"
15053   [(set_attr "prefix_0f" "1")])
15054
15055 (define_expand "clzsi2"
15056   [(parallel
15057      [(set (match_operand:SI 0 "register_operand" "")
15058            (minus:SI (const_int 31)
15059                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15060       (clobber (reg:CC FLAGS_REG))])
15061    (parallel
15062      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15063       (clobber (reg:CC FLAGS_REG))])]
15064   ""
15065 {
15066   if (TARGET_ABM)
15067     {
15068       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15069       DONE;
15070     }
15071 })
15072
15073 (define_insn "clzsi2_abm"
15074   [(set (match_operand:SI 0 "register_operand" "=r")
15075         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15076    (clobber (reg:CC FLAGS_REG))]
15077   "TARGET_ABM"
15078   "lzcnt{l}\t{%1, %0|%0, %1}"
15079   [(set_attr "prefix_rep" "1")
15080    (set_attr "type" "bitmanip")
15081    (set_attr "mode" "SI")])
15082
15083 (define_insn "*bsr"
15084   [(set (match_operand:SI 0 "register_operand" "=r")
15085         (minus:SI (const_int 31)
15086                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15087    (clobber (reg:CC FLAGS_REG))]
15088   ""
15089   "bsr{l}\t{%1, %0|%0, %1}"
15090   [(set_attr "prefix_0f" "1")
15091    (set_attr "mode" "SI")])
15092
15093 (define_insn "popcountsi2"
15094   [(set (match_operand:SI 0 "register_operand" "=r")
15095         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15096    (clobber (reg:CC FLAGS_REG))]
15097   "TARGET_POPCNT"
15098   "popcnt{l}\t{%1, %0|%0, %1}"
15099   [(set_attr "prefix_rep" "1")
15100    (set_attr "type" "bitmanip")
15101    (set_attr "mode" "SI")])
15102
15103 (define_insn "*popcountsi2_cmp"
15104   [(set (reg FLAGS_REG)
15105         (compare
15106           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15107           (const_int 0)))
15108    (set (match_operand:SI 0 "register_operand" "=r")
15109         (popcount:SI (match_dup 1)))]
15110   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15111   "popcnt{l}\t{%1, %0|%0, %1}"
15112   [(set_attr "prefix_rep" "1")
15113    (set_attr "type" "bitmanip")
15114    (set_attr "mode" "SI")])
15115
15116 (define_insn "*popcountsi2_cmp_zext"
15117   [(set (reg FLAGS_REG)
15118         (compare
15119           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15120           (const_int 0)))
15121    (set (match_operand:DI 0 "register_operand" "=r")
15122         (zero_extend:DI(popcount:SI (match_dup 1))))]
15123   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15124   "popcnt{l}\t{%1, %0|%0, %1}"
15125   [(set_attr "prefix_rep" "1")
15126    (set_attr "type" "bitmanip")
15127    (set_attr "mode" "SI")])
15128
15129 (define_expand "bswapsi2"
15130   [(set (match_operand:SI 0 "register_operand" "")
15131         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15132   ""
15133 {
15134   if (!TARGET_BSWAP)
15135     {
15136       rtx x = operands[0];
15137
15138       emit_move_insn (x, operands[1]);
15139       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15140       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15141       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15142       DONE;
15143     }
15144 })
15145
15146 (define_insn "*bswapsi_1"
15147   [(set (match_operand:SI 0 "register_operand" "=r")
15148         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15149   "TARGET_BSWAP"
15150   "bswap\t%0"
15151   [(set_attr "prefix_0f" "1")
15152    (set_attr "length" "2")])
15153
15154 (define_insn "*bswaphi_lowpart_1"
15155   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15156         (bswap:HI (match_dup 0)))
15157    (clobber (reg:CC FLAGS_REG))]
15158   "TARGET_USE_XCHGB || optimize_size"
15159   "@
15160     xchg{b}\t{%h0, %b0|%b0, %h0}
15161     rol{w}\t{$8, %0|%0, 8}"
15162   [(set_attr "length" "2,4")
15163    (set_attr "mode" "QI,HI")])
15164
15165 (define_insn "bswaphi_lowpart"
15166   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15167         (bswap:HI (match_dup 0)))
15168    (clobber (reg:CC FLAGS_REG))]
15169   ""
15170   "rol{w}\t{$8, %0|%0, 8}"
15171   [(set_attr "length" "4")
15172    (set_attr "mode" "HI")])
15173
15174 (define_insn "bswapdi2"
15175   [(set (match_operand:DI 0 "register_operand" "=r")
15176         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15177   "TARGET_64BIT"
15178   "bswap\t%0"
15179   [(set_attr "prefix_0f" "1")
15180    (set_attr "length" "3")])
15181
15182 (define_expand "clzdi2"
15183   [(parallel
15184      [(set (match_operand:DI 0 "register_operand" "")
15185            (minus:DI (const_int 63)
15186                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15187       (clobber (reg:CC FLAGS_REG))])
15188    (parallel
15189      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15190       (clobber (reg:CC FLAGS_REG))])]
15191   "TARGET_64BIT"
15192 {
15193   if (TARGET_ABM)
15194     {
15195       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15196       DONE;
15197     }
15198 })
15199
15200 (define_insn "clzdi2_abm"
15201   [(set (match_operand:DI 0 "register_operand" "=r")
15202         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15203    (clobber (reg:CC FLAGS_REG))]
15204   "TARGET_64BIT && TARGET_ABM"
15205   "lzcnt{q}\t{%1, %0|%0, %1}"
15206   [(set_attr "prefix_rep" "1")
15207    (set_attr "type" "bitmanip")
15208    (set_attr "mode" "DI")])
15209
15210 (define_insn "*bsr_rex64"
15211   [(set (match_operand:DI 0 "register_operand" "=r")
15212         (minus:DI (const_int 63)
15213                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15214    (clobber (reg:CC FLAGS_REG))]
15215   "TARGET_64BIT"
15216   "bsr{q}\t{%1, %0|%0, %1}"
15217   [(set_attr "prefix_0f" "1")
15218    (set_attr "mode" "DI")])
15219
15220 (define_insn "popcountdi2"
15221   [(set (match_operand:DI 0 "register_operand" "=r")
15222         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15223    (clobber (reg:CC FLAGS_REG))]
15224   "TARGET_64BIT && TARGET_POPCNT"
15225   "popcnt{q}\t{%1, %0|%0, %1}"
15226   [(set_attr "prefix_rep" "1")
15227    (set_attr "type" "bitmanip")
15228    (set_attr "mode" "DI")])
15229
15230 (define_insn "*popcountdi2_cmp"
15231   [(set (reg FLAGS_REG)
15232         (compare
15233           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15234           (const_int 0)))
15235    (set (match_operand:DI 0 "register_operand" "=r")
15236         (popcount:DI (match_dup 1)))]
15237   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15238   "popcnt{q}\t{%1, %0|%0, %1}"
15239   [(set_attr "prefix_rep" "1")
15240    (set_attr "type" "bitmanip")
15241    (set_attr "mode" "DI")])
15242
15243 (define_expand "clzhi2"
15244   [(parallel
15245      [(set (match_operand:HI 0 "register_operand" "")
15246            (minus:HI (const_int 15)
15247                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15248       (clobber (reg:CC FLAGS_REG))])
15249    (parallel
15250      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15251       (clobber (reg:CC FLAGS_REG))])]
15252   ""
15253 {
15254   if (TARGET_ABM)
15255     {
15256       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15257       DONE;
15258     }
15259 })
15260
15261 (define_insn "clzhi2_abm"
15262   [(set (match_operand:HI 0 "register_operand" "=r")
15263         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15264    (clobber (reg:CC FLAGS_REG))]
15265   "TARGET_ABM"
15266   "lzcnt{w}\t{%1, %0|%0, %1}"
15267   [(set_attr "prefix_rep" "1")
15268    (set_attr "type" "bitmanip")
15269    (set_attr "mode" "HI")])
15270
15271 (define_insn "*bsrhi"
15272   [(set (match_operand:HI 0 "register_operand" "=r")
15273         (minus:HI (const_int 15)
15274                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15275    (clobber (reg:CC FLAGS_REG))]
15276   ""
15277   "bsr{w}\t{%1, %0|%0, %1}"
15278   [(set_attr "prefix_0f" "1")
15279    (set_attr "mode" "HI")])
15280
15281 (define_insn "popcounthi2"
15282   [(set (match_operand:HI 0 "register_operand" "=r")
15283         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15284    (clobber (reg:CC FLAGS_REG))]
15285   "TARGET_POPCNT"
15286   "popcnt{w}\t{%1, %0|%0, %1}"
15287   [(set_attr "prefix_rep" "1")
15288    (set_attr "type" "bitmanip")
15289    (set_attr "mode" "HI")])
15290
15291 (define_insn "*popcounthi2_cmp"
15292   [(set (reg FLAGS_REG)
15293         (compare
15294           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15295           (const_int 0)))
15296    (set (match_operand:HI 0 "register_operand" "=r")
15297         (popcount:HI (match_dup 1)))]
15298   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15299   "popcnt{w}\t{%1, %0|%0, %1}"
15300   [(set_attr "prefix_rep" "1")
15301    (set_attr "type" "bitmanip")
15302    (set_attr "mode" "HI")])
15303
15304 (define_expand "paritydi2"
15305   [(set (match_operand:DI 0 "register_operand" "")
15306         (parity:DI (match_operand:DI 1 "register_operand" "")))]
15307   "! TARGET_POPCNT"
15308 {
15309   rtx scratch = gen_reg_rtx (QImode);
15310   rtx cond;
15311
15312   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15313                                 NULL_RTX, operands[1]));
15314
15315   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15316                          gen_rtx_REG (CCmode, FLAGS_REG),
15317                          const0_rtx);
15318   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15319
15320   if (TARGET_64BIT)
15321     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15322   else
15323     {
15324       rtx tmp = gen_reg_rtx (SImode);
15325
15326       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15327       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15328     }
15329   DONE;
15330 })
15331
15332 (define_insn_and_split "paritydi2_cmp"
15333   [(set (reg:CC FLAGS_REG)
15334         (parity:CC (match_operand:DI 3 "register_operand" "0")))
15335    (clobber (match_scratch:DI 0 "=r"))
15336    (clobber (match_scratch:SI 1 "=&r"))
15337    (clobber (match_scratch:HI 2 "=Q"))]
15338   "! TARGET_POPCNT"
15339   "#"
15340   "&& reload_completed"
15341   [(parallel
15342      [(set (match_dup 1)
15343            (xor:SI (match_dup 1) (match_dup 4)))
15344       (clobber (reg:CC FLAGS_REG))])
15345    (parallel
15346      [(set (reg:CC FLAGS_REG)
15347            (parity:CC (match_dup 1)))
15348       (clobber (match_dup 1))
15349       (clobber (match_dup 2))])]
15350 {
15351   operands[4] = gen_lowpart (SImode, operands[3]);
15352
15353   if (TARGET_64BIT)
15354     {
15355       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15356       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15357     }
15358   else
15359     operands[1] = gen_highpart (SImode, operands[3]);
15360 })
15361
15362 (define_expand "paritysi2"
15363   [(set (match_operand:SI 0 "register_operand" "")
15364         (parity:SI (match_operand:SI 1 "register_operand" "")))]
15365   "! TARGET_POPCNT"
15366 {
15367   rtx scratch = gen_reg_rtx (QImode);
15368   rtx cond;
15369
15370   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15371
15372   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15373                          gen_rtx_REG (CCmode, FLAGS_REG),
15374                          const0_rtx);
15375   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15376
15377   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15378   DONE;
15379 })
15380
15381 (define_insn_and_split "paritysi2_cmp"
15382   [(set (reg:CC FLAGS_REG)
15383         (parity:CC (match_operand:SI 2 "register_operand" "0")))
15384    (clobber (match_scratch:SI 0 "=r"))
15385    (clobber (match_scratch:HI 1 "=&Q"))]
15386   "! TARGET_POPCNT"
15387   "#"
15388   "&& reload_completed"
15389   [(parallel
15390      [(set (match_dup 1)
15391            (xor:HI (match_dup 1) (match_dup 3)))
15392       (clobber (reg:CC FLAGS_REG))])
15393    (parallel
15394      [(set (reg:CC FLAGS_REG)
15395            (parity:CC (match_dup 1)))
15396       (clobber (match_dup 1))])]
15397 {
15398   operands[3] = gen_lowpart (HImode, operands[2]);
15399
15400   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15401   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15402 })
15403
15404 (define_insn "*parityhi2_cmp"
15405   [(set (reg:CC FLAGS_REG)
15406         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15407    (clobber (match_scratch:HI 0 "=Q"))]
15408   "! TARGET_POPCNT"
15409   "xor{b}\t{%h0, %b0|%b0, %h0}"
15410   [(set_attr "length" "2")
15411    (set_attr "mode" "HI")])
15412
15413 (define_insn "*parityqi2_cmp"
15414   [(set (reg:CC FLAGS_REG)
15415         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15416   "! TARGET_POPCNT"
15417   "test{b}\t%0, %0"
15418   [(set_attr "length" "2")
15419    (set_attr "mode" "QI")])
15420 \f
15421 ;; Thread-local storage patterns for ELF.
15422 ;;
15423 ;; Note that these code sequences must appear exactly as shown
15424 ;; in order to allow linker relaxation.
15425
15426 (define_insn "*tls_global_dynamic_32_gnu"
15427   [(set (match_operand:SI 0 "register_operand" "=a")
15428         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15429                     (match_operand:SI 2 "tls_symbolic_operand" "")
15430                     (match_operand:SI 3 "call_insn_operand" "")]
15431                     UNSPEC_TLS_GD))
15432    (clobber (match_scratch:SI 4 "=d"))
15433    (clobber (match_scratch:SI 5 "=c"))
15434    (clobber (reg:CC FLAGS_REG))]
15435   "!TARGET_64BIT && TARGET_GNU_TLS"
15436   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15437   [(set_attr "type" "multi")
15438    (set_attr "length" "12")])
15439
15440 (define_insn "*tls_global_dynamic_32_sun"
15441   [(set (match_operand:SI 0 "register_operand" "=a")
15442         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15443                     (match_operand:SI 2 "tls_symbolic_operand" "")
15444                     (match_operand:SI 3 "call_insn_operand" "")]
15445                     UNSPEC_TLS_GD))
15446    (clobber (match_scratch:SI 4 "=d"))
15447    (clobber (match_scratch:SI 5 "=c"))
15448    (clobber (reg:CC FLAGS_REG))]
15449   "!TARGET_64BIT && TARGET_SUN_TLS"
15450   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15451         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15452   [(set_attr "type" "multi")
15453    (set_attr "length" "14")])
15454
15455 (define_expand "tls_global_dynamic_32"
15456   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15457                    (unspec:SI
15458                     [(match_dup 2)
15459                      (match_operand:SI 1 "tls_symbolic_operand" "")
15460                      (match_dup 3)]
15461                     UNSPEC_TLS_GD))
15462               (clobber (match_scratch:SI 4 ""))
15463               (clobber (match_scratch:SI 5 ""))
15464               (clobber (reg:CC FLAGS_REG))])]
15465   ""
15466 {
15467   if (flag_pic)
15468     operands[2] = pic_offset_table_rtx;
15469   else
15470     {
15471       operands[2] = gen_reg_rtx (Pmode);
15472       emit_insn (gen_set_got (operands[2]));
15473     }
15474   if (TARGET_GNU2_TLS)
15475     {
15476        emit_insn (gen_tls_dynamic_gnu2_32
15477                   (operands[0], operands[1], operands[2]));
15478        DONE;
15479     }
15480   operands[3] = ix86_tls_get_addr ();
15481 })
15482
15483 (define_insn "*tls_global_dynamic_64"
15484   [(set (match_operand:DI 0 "register_operand" "=a")
15485         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15486                  (match_operand:DI 3 "" "")))
15487    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15488               UNSPEC_TLS_GD)]
15489   "TARGET_64BIT"
15490   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15491   [(set_attr "type" "multi")
15492    (set_attr "length" "16")])
15493
15494 (define_expand "tls_global_dynamic_64"
15495   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15496                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15497               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15498                          UNSPEC_TLS_GD)])]
15499   ""
15500 {
15501   if (TARGET_GNU2_TLS)
15502     {
15503        emit_insn (gen_tls_dynamic_gnu2_64
15504                   (operands[0], operands[1]));
15505        DONE;
15506     }
15507   operands[2] = ix86_tls_get_addr ();
15508 })
15509
15510 (define_insn "*tls_local_dynamic_base_32_gnu"
15511   [(set (match_operand:SI 0 "register_operand" "=a")
15512         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15513                     (match_operand:SI 2 "call_insn_operand" "")]
15514                    UNSPEC_TLS_LD_BASE))
15515    (clobber (match_scratch:SI 3 "=d"))
15516    (clobber (match_scratch:SI 4 "=c"))
15517    (clobber (reg:CC FLAGS_REG))]
15518   "!TARGET_64BIT && TARGET_GNU_TLS"
15519   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15520   [(set_attr "type" "multi")
15521    (set_attr "length" "11")])
15522
15523 (define_insn "*tls_local_dynamic_base_32_sun"
15524   [(set (match_operand:SI 0 "register_operand" "=a")
15525         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15526                     (match_operand:SI 2 "call_insn_operand" "")]
15527                    UNSPEC_TLS_LD_BASE))
15528    (clobber (match_scratch:SI 3 "=d"))
15529    (clobber (match_scratch:SI 4 "=c"))
15530    (clobber (reg:CC FLAGS_REG))]
15531   "!TARGET_64BIT && TARGET_SUN_TLS"
15532   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15533         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15534   [(set_attr "type" "multi")
15535    (set_attr "length" "13")])
15536
15537 (define_expand "tls_local_dynamic_base_32"
15538   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15539                    (unspec:SI [(match_dup 1) (match_dup 2)]
15540                               UNSPEC_TLS_LD_BASE))
15541               (clobber (match_scratch:SI 3 ""))
15542               (clobber (match_scratch:SI 4 ""))
15543               (clobber (reg:CC FLAGS_REG))])]
15544   ""
15545 {
15546   if (flag_pic)
15547     operands[1] = pic_offset_table_rtx;
15548   else
15549     {
15550       operands[1] = gen_reg_rtx (Pmode);
15551       emit_insn (gen_set_got (operands[1]));
15552     }
15553   if (TARGET_GNU2_TLS)
15554     {
15555        emit_insn (gen_tls_dynamic_gnu2_32
15556                   (operands[0], ix86_tls_module_base (), operands[1]));
15557        DONE;
15558     }
15559   operands[2] = ix86_tls_get_addr ();
15560 })
15561
15562 (define_insn "*tls_local_dynamic_base_64"
15563   [(set (match_operand:DI 0 "register_operand" "=a")
15564         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15565                  (match_operand:DI 2 "" "")))
15566    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15567   "TARGET_64BIT"
15568   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15569   [(set_attr "type" "multi")
15570    (set_attr "length" "12")])
15571
15572 (define_expand "tls_local_dynamic_base_64"
15573   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15574                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15575               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15576   ""
15577 {
15578   if (TARGET_GNU2_TLS)
15579     {
15580        emit_insn (gen_tls_dynamic_gnu2_64
15581                   (operands[0], ix86_tls_module_base ()));
15582        DONE;
15583     }
15584   operands[1] = ix86_tls_get_addr ();
15585 })
15586
15587 ;; Local dynamic of a single variable is a lose.  Show combine how
15588 ;; to convert that back to global dynamic.
15589
15590 (define_insn_and_split "*tls_local_dynamic_32_once"
15591   [(set (match_operand:SI 0 "register_operand" "=a")
15592         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15593                              (match_operand:SI 2 "call_insn_operand" "")]
15594                             UNSPEC_TLS_LD_BASE)
15595                  (const:SI (unspec:SI
15596                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15597                             UNSPEC_DTPOFF))))
15598    (clobber (match_scratch:SI 4 "=d"))
15599    (clobber (match_scratch:SI 5 "=c"))
15600    (clobber (reg:CC FLAGS_REG))]
15601   ""
15602   "#"
15603   ""
15604   [(parallel [(set (match_dup 0)
15605                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15606                               UNSPEC_TLS_GD))
15607               (clobber (match_dup 4))
15608               (clobber (match_dup 5))
15609               (clobber (reg:CC FLAGS_REG))])]
15610   "")
15611
15612 ;; Load and add the thread base pointer from %gs:0.
15613
15614 (define_insn "*load_tp_si"
15615   [(set (match_operand:SI 0 "register_operand" "=r")
15616         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15617   "!TARGET_64BIT"
15618   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15619   [(set_attr "type" "imov")
15620    (set_attr "modrm" "0")
15621    (set_attr "length" "7")
15622    (set_attr "memory" "load")
15623    (set_attr "imm_disp" "false")])
15624
15625 (define_insn "*add_tp_si"
15626   [(set (match_operand:SI 0 "register_operand" "=r")
15627         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15628                  (match_operand:SI 1 "register_operand" "0")))
15629    (clobber (reg:CC FLAGS_REG))]
15630   "!TARGET_64BIT"
15631   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15632   [(set_attr "type" "alu")
15633    (set_attr "modrm" "0")
15634    (set_attr "length" "7")
15635    (set_attr "memory" "load")
15636    (set_attr "imm_disp" "false")])
15637
15638 (define_insn "*load_tp_di"
15639   [(set (match_operand:DI 0 "register_operand" "=r")
15640         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15641   "TARGET_64BIT"
15642   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15643   [(set_attr "type" "imov")
15644    (set_attr "modrm" "0")
15645    (set_attr "length" "7")
15646    (set_attr "memory" "load")
15647    (set_attr "imm_disp" "false")])
15648
15649 (define_insn "*add_tp_di"
15650   [(set (match_operand:DI 0 "register_operand" "=r")
15651         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15652                  (match_operand:DI 1 "register_operand" "0")))
15653    (clobber (reg:CC FLAGS_REG))]
15654   "TARGET_64BIT"
15655   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15656   [(set_attr "type" "alu")
15657    (set_attr "modrm" "0")
15658    (set_attr "length" "7")
15659    (set_attr "memory" "load")
15660    (set_attr "imm_disp" "false")])
15661
15662 ;; GNU2 TLS patterns can be split.
15663
15664 (define_expand "tls_dynamic_gnu2_32"
15665   [(set (match_dup 3)
15666         (plus:SI (match_operand:SI 2 "register_operand" "")
15667                  (const:SI
15668                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15669                              UNSPEC_TLSDESC))))
15670    (parallel
15671     [(set (match_operand:SI 0 "register_operand" "")
15672           (unspec:SI [(match_dup 1) (match_dup 3)
15673                       (match_dup 2) (reg:SI SP_REG)]
15674                       UNSPEC_TLSDESC))
15675      (clobber (reg:CC FLAGS_REG))])]
15676   "!TARGET_64BIT && TARGET_GNU2_TLS"
15677 {
15678   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15679   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15680 })
15681
15682 (define_insn "*tls_dynamic_lea_32"
15683   [(set (match_operand:SI 0 "register_operand" "=r")
15684         (plus:SI (match_operand:SI 1 "register_operand" "b")
15685                  (const:SI
15686                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15687                               UNSPEC_TLSDESC))))]
15688   "!TARGET_64BIT && TARGET_GNU2_TLS"
15689   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15690   [(set_attr "type" "lea")
15691    (set_attr "mode" "SI")
15692    (set_attr "length" "6")
15693    (set_attr "length_address" "4")])
15694
15695 (define_insn "*tls_dynamic_call_32"
15696   [(set (match_operand:SI 0 "register_operand" "=a")
15697         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15698                     (match_operand:SI 2 "register_operand" "0")
15699                     ;; we have to make sure %ebx still points to the GOT
15700                     (match_operand:SI 3 "register_operand" "b")
15701                     (reg:SI SP_REG)]
15702                    UNSPEC_TLSDESC))
15703    (clobber (reg:CC FLAGS_REG))]
15704   "!TARGET_64BIT && TARGET_GNU2_TLS"
15705   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15706   [(set_attr "type" "call")
15707    (set_attr "length" "2")
15708    (set_attr "length_address" "0")])
15709
15710 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15711   [(set (match_operand:SI 0 "register_operand" "=&a")
15712         (plus:SI
15713          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15714                      (match_operand:SI 4 "" "")
15715                      (match_operand:SI 2 "register_operand" "b")
15716                      (reg:SI SP_REG)]
15717                     UNSPEC_TLSDESC)
15718          (const:SI (unspec:SI
15719                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15720                     UNSPEC_DTPOFF))))
15721    (clobber (reg:CC FLAGS_REG))]
15722   "!TARGET_64BIT && TARGET_GNU2_TLS"
15723   "#"
15724   ""
15725   [(set (match_dup 0) (match_dup 5))]
15726 {
15727   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15728   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15729 })
15730
15731 (define_expand "tls_dynamic_gnu2_64"
15732   [(set (match_dup 2)
15733         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15734                    UNSPEC_TLSDESC))
15735    (parallel
15736     [(set (match_operand:DI 0 "register_operand" "")
15737           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15738                      UNSPEC_TLSDESC))
15739      (clobber (reg:CC FLAGS_REG))])]
15740   "TARGET_64BIT && TARGET_GNU2_TLS"
15741 {
15742   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15743   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15744 })
15745
15746 (define_insn "*tls_dynamic_lea_64"
15747   [(set (match_operand:DI 0 "register_operand" "=r")
15748         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15749                    UNSPEC_TLSDESC))]
15750   "TARGET_64BIT && TARGET_GNU2_TLS"
15751   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15752   [(set_attr "type" "lea")
15753    (set_attr "mode" "DI")
15754    (set_attr "length" "7")
15755    (set_attr "length_address" "4")])
15756
15757 (define_insn "*tls_dynamic_call_64"
15758   [(set (match_operand:DI 0 "register_operand" "=a")
15759         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15760                     (match_operand:DI 2 "register_operand" "0")
15761                     (reg:DI SP_REG)]
15762                    UNSPEC_TLSDESC))
15763    (clobber (reg:CC FLAGS_REG))]
15764   "TARGET_64BIT && TARGET_GNU2_TLS"
15765   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15766   [(set_attr "type" "call")
15767    (set_attr "length" "2")
15768    (set_attr "length_address" "0")])
15769
15770 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15771   [(set (match_operand:DI 0 "register_operand" "=&a")
15772         (plus:DI
15773          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15774                      (match_operand:DI 3 "" "")
15775                      (reg:DI SP_REG)]
15776                     UNSPEC_TLSDESC)
15777          (const:DI (unspec:DI
15778                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15779                     UNSPEC_DTPOFF))))
15780    (clobber (reg:CC FLAGS_REG))]
15781   "TARGET_64BIT && TARGET_GNU2_TLS"
15782   "#"
15783   ""
15784   [(set (match_dup 0) (match_dup 4))]
15785 {
15786   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15787   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15788 })
15789
15790 ;;
15791 \f
15792 ;; These patterns match the binary 387 instructions for addM3, subM3,
15793 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15794 ;; SFmode.  The first is the normal insn, the second the same insn but
15795 ;; with one operand a conversion, and the third the same insn but with
15796 ;; the other operand a conversion.  The conversion may be SFmode or
15797 ;; SImode if the target mode DFmode, but only SImode if the target mode
15798 ;; is SFmode.
15799
15800 ;; Gcc is slightly more smart about handling normal two address instructions
15801 ;; so use special patterns for add and mull.
15802
15803 (define_insn "*fop_sf_comm_mixed"
15804   [(set (match_operand:SF 0 "register_operand" "=f,x")
15805         (match_operator:SF 3 "binary_fp_operator"
15806                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15807                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15808   "TARGET_MIX_SSE_I387
15809    && COMMUTATIVE_ARITH_P (operands[3])
15810    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15811   "* return output_387_binary_op (insn, operands);"
15812   [(set (attr "type")
15813         (if_then_else (eq_attr "alternative" "1")
15814            (if_then_else (match_operand:SF 3 "mult_operator" "")
15815               (const_string "ssemul")
15816               (const_string "sseadd"))
15817            (if_then_else (match_operand:SF 3 "mult_operator" "")
15818               (const_string "fmul")
15819               (const_string "fop"))))
15820    (set_attr "mode" "SF")])
15821
15822 (define_insn "*fop_sf_comm_sse"
15823   [(set (match_operand:SF 0 "register_operand" "=x")
15824         (match_operator:SF 3 "binary_fp_operator"
15825                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15826                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15827   "TARGET_SSE_MATH
15828    && COMMUTATIVE_ARITH_P (operands[3])
15829    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15830   "* return output_387_binary_op (insn, operands);"
15831   [(set (attr "type")
15832         (if_then_else (match_operand:SF 3 "mult_operator" "")
15833            (const_string "ssemul")
15834            (const_string "sseadd")))
15835    (set_attr "mode" "SF")])
15836
15837 (define_insn "*fop_sf_comm_i387"
15838   [(set (match_operand:SF 0 "register_operand" "=f")
15839         (match_operator:SF 3 "binary_fp_operator"
15840                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15841                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15842   "TARGET_80387
15843    && COMMUTATIVE_ARITH_P (operands[3])
15844    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15845   "* return output_387_binary_op (insn, operands);"
15846   [(set (attr "type")
15847         (if_then_else (match_operand:SF 3 "mult_operator" "")
15848            (const_string "fmul")
15849            (const_string "fop")))
15850    (set_attr "mode" "SF")])
15851
15852 (define_insn "*fop_sf_1_mixed"
15853   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15854         (match_operator:SF 3 "binary_fp_operator"
15855                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15856                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15857   "TARGET_MIX_SSE_I387
15858    && !COMMUTATIVE_ARITH_P (operands[3])
15859    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15860   "* return output_387_binary_op (insn, operands);"
15861   [(set (attr "type")
15862         (cond [(and (eq_attr "alternative" "2")
15863                     (match_operand:SF 3 "mult_operator" ""))
15864                  (const_string "ssemul")
15865                (and (eq_attr "alternative" "2")
15866                     (match_operand:SF 3 "div_operator" ""))
15867                  (const_string "ssediv")
15868                (eq_attr "alternative" "2")
15869                  (const_string "sseadd")
15870                (match_operand:SF 3 "mult_operator" "")
15871                  (const_string "fmul")
15872                (match_operand:SF 3 "div_operator" "")
15873                  (const_string "fdiv")
15874               ]
15875               (const_string "fop")))
15876    (set_attr "mode" "SF")])
15877
15878 (define_insn "*rcpsf2_sse"
15879   [(set (match_operand:SF 0 "register_operand" "=x")
15880         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15881                    UNSPEC_RCP))]
15882   "TARGET_SSE_MATH"
15883   "rcpss\t{%1, %0|%0, %1}"
15884   [(set_attr "type" "sse")
15885    (set_attr "mode" "SF")])
15886
15887 (define_insn "*fop_sf_1_sse"
15888   [(set (match_operand:SF 0 "register_operand" "=x")
15889         (match_operator:SF 3 "binary_fp_operator"
15890                         [(match_operand:SF 1 "register_operand" "0")
15891                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15892   "TARGET_SSE_MATH
15893    && !COMMUTATIVE_ARITH_P (operands[3])"
15894   "* return output_387_binary_op (insn, operands);"
15895   [(set (attr "type")
15896         (cond [(match_operand:SF 3 "mult_operator" "")
15897                  (const_string "ssemul")
15898                (match_operand:SF 3 "div_operator" "")
15899                  (const_string "ssediv")
15900               ]
15901               (const_string "sseadd")))
15902    (set_attr "mode" "SF")])
15903
15904 ;; This pattern is not fully shadowed by the pattern above.
15905 (define_insn "*fop_sf_1_i387"
15906   [(set (match_operand:SF 0 "register_operand" "=f,f")
15907         (match_operator:SF 3 "binary_fp_operator"
15908                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15909                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15910   "TARGET_80387 && !TARGET_SSE_MATH
15911    && !COMMUTATIVE_ARITH_P (operands[3])
15912    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15913   "* return output_387_binary_op (insn, operands);"
15914   [(set (attr "type")
15915         (cond [(match_operand:SF 3 "mult_operator" "")
15916                  (const_string "fmul")
15917                (match_operand:SF 3 "div_operator" "")
15918                  (const_string "fdiv")
15919               ]
15920               (const_string "fop")))
15921    (set_attr "mode" "SF")])
15922
15923 ;; ??? Add SSE splitters for these!
15924 (define_insn "*fop_sf_2<mode>_i387"
15925   [(set (match_operand:SF 0 "register_operand" "=f,f")
15926         (match_operator:SF 3 "binary_fp_operator"
15927           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15928            (match_operand:SF 2 "register_operand" "0,0")]))]
15929   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15930   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15931   [(set (attr "type")
15932         (cond [(match_operand:SF 3 "mult_operator" "")
15933                  (const_string "fmul")
15934                (match_operand:SF 3 "div_operator" "")
15935                  (const_string "fdiv")
15936               ]
15937               (const_string "fop")))
15938    (set_attr "fp_int_src" "true")
15939    (set_attr "mode" "<MODE>")])
15940
15941 (define_insn "*fop_sf_3<mode>_i387"
15942   [(set (match_operand:SF 0 "register_operand" "=f,f")
15943         (match_operator:SF 3 "binary_fp_operator"
15944           [(match_operand:SF 1 "register_operand" "0,0")
15945            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15946   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15947   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15948   [(set (attr "type")
15949         (cond [(match_operand:SF 3 "mult_operator" "")
15950                  (const_string "fmul")
15951                (match_operand:SF 3 "div_operator" "")
15952                  (const_string "fdiv")
15953               ]
15954               (const_string "fop")))
15955    (set_attr "fp_int_src" "true")
15956    (set_attr "mode" "<MODE>")])
15957
15958 (define_insn "*fop_df_comm_mixed"
15959   [(set (match_operand:DF 0 "register_operand" "=f,x")
15960         (match_operator:DF 3 "binary_fp_operator"
15961           [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15962            (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15963   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15964    && COMMUTATIVE_ARITH_P (operands[3])
15965    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15966   "* return output_387_binary_op (insn, operands);"
15967   [(set (attr "type")
15968         (if_then_else (eq_attr "alternative" "1")
15969            (if_then_else (match_operand:DF 3 "mult_operator" "")
15970               (const_string "ssemul")
15971               (const_string "sseadd"))
15972            (if_then_else (match_operand:DF 3 "mult_operator" "")
15973               (const_string "fmul")
15974               (const_string "fop"))))
15975    (set_attr "mode" "DF")])
15976
15977 (define_insn "*fop_df_comm_sse"
15978   [(set (match_operand:DF 0 "register_operand" "=x")
15979         (match_operator:DF 3 "binary_fp_operator"
15980           [(match_operand:DF 1 "nonimmediate_operand" "%0")
15981            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15982   "TARGET_SSE2 && TARGET_SSE_MATH
15983    && COMMUTATIVE_ARITH_P (operands[3])
15984    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15985   "* return output_387_binary_op (insn, operands);"
15986   [(set (attr "type")
15987         (if_then_else (match_operand:DF 3 "mult_operator" "")
15988            (const_string "ssemul")
15989            (const_string "sseadd")))
15990    (set_attr "mode" "DF")])
15991
15992 (define_insn "*fop_df_comm_i387"
15993   [(set (match_operand:DF 0 "register_operand" "=f")
15994         (match_operator:DF 3 "binary_fp_operator"
15995                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15996                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15997   "TARGET_80387
15998    && COMMUTATIVE_ARITH_P (operands[3])
15999    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16000   "* return output_387_binary_op (insn, operands);"
16001   [(set (attr "type")
16002         (if_then_else (match_operand:DF 3 "mult_operator" "")
16003            (const_string "fmul")
16004            (const_string "fop")))
16005    (set_attr "mode" "DF")])
16006
16007 (define_insn "*fop_df_1_mixed"
16008   [(set (match_operand:DF 0 "register_operand" "=f,f,x")
16009         (match_operator:DF 3 "binary_fp_operator"
16010           [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
16011            (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
16012   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
16013    && !COMMUTATIVE_ARITH_P (operands[3])
16014    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16015   "* return output_387_binary_op (insn, operands);"
16016   [(set (attr "type")
16017         (cond [(and (eq_attr "alternative" "2")
16018                     (match_operand:DF 3 "mult_operator" ""))
16019                  (const_string "ssemul")
16020                (and (eq_attr "alternative" "2")
16021                     (match_operand:DF 3 "div_operator" ""))
16022                  (const_string "ssediv")
16023                (eq_attr "alternative" "2")
16024                  (const_string "sseadd")
16025                (match_operand:DF 3 "mult_operator" "")
16026                  (const_string "fmul")
16027                (match_operand:DF 3 "div_operator" "")
16028                  (const_string "fdiv")
16029               ]
16030               (const_string "fop")))
16031    (set_attr "mode" "DF")])
16032
16033 (define_insn "*fop_df_1_sse"
16034   [(set (match_operand:DF 0 "register_operand" "=x")
16035         (match_operator:DF 3 "binary_fp_operator"
16036           [(match_operand:DF 1 "register_operand" "0")
16037            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16038   "TARGET_SSE2 && TARGET_SSE_MATH
16039    && !COMMUTATIVE_ARITH_P (operands[3])"
16040   "* return output_387_binary_op (insn, operands);"
16041   [(set_attr "mode" "DF")
16042    (set (attr "type")
16043         (cond [(match_operand:DF 3 "mult_operator" "")
16044                  (const_string "ssemul")
16045                (match_operand:DF 3 "div_operator" "")
16046                  (const_string "ssediv")
16047               ]
16048               (const_string "sseadd")))])
16049
16050 ;; This pattern is not fully shadowed by the pattern above.
16051 (define_insn "*fop_df_1_i387"
16052   [(set (match_operand:DF 0 "register_operand" "=f,f")
16053         (match_operator:DF 3 "binary_fp_operator"
16054                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
16055                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
16056   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16057    && !COMMUTATIVE_ARITH_P (operands[3])
16058    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16059   "* return output_387_binary_op (insn, operands);"
16060   [(set (attr "type")
16061         (cond [(match_operand:DF 3 "mult_operator" "")
16062                  (const_string "fmul")
16063                (match_operand:DF 3 "div_operator" "")
16064                  (const_string "fdiv")
16065               ]
16066               (const_string "fop")))
16067    (set_attr "mode" "DF")])
16068
16069 ;; ??? Add SSE splitters for these!
16070 (define_insn "*fop_df_2<mode>_i387"
16071   [(set (match_operand:DF 0 "register_operand" "=f,f")
16072         (match_operator:DF 3 "binary_fp_operator"
16073            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16074             (match_operand:DF 2 "register_operand" "0,0")]))]
16075   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16076    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16077   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16078   [(set (attr "type")
16079         (cond [(match_operand:DF 3 "mult_operator" "")
16080                  (const_string "fmul")
16081                (match_operand:DF 3 "div_operator" "")
16082                  (const_string "fdiv")
16083               ]
16084               (const_string "fop")))
16085    (set_attr "fp_int_src" "true")
16086    (set_attr "mode" "<MODE>")])
16087
16088 (define_insn "*fop_df_3<mode>_i387"
16089   [(set (match_operand:DF 0 "register_operand" "=f,f")
16090         (match_operator:DF 3 "binary_fp_operator"
16091            [(match_operand:DF 1 "register_operand" "0,0")
16092             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16093   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16094    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16095   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16096   [(set (attr "type")
16097         (cond [(match_operand:DF 3 "mult_operator" "")
16098                  (const_string "fmul")
16099                (match_operand:DF 3 "div_operator" "")
16100                  (const_string "fdiv")
16101               ]
16102               (const_string "fop")))
16103    (set_attr "fp_int_src" "true")
16104    (set_attr "mode" "<MODE>")])
16105
16106 (define_insn "*fop_df_4_i387"
16107   [(set (match_operand:DF 0 "register_operand" "=f,f")
16108         (match_operator:DF 3 "binary_fp_operator"
16109            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16110             (match_operand:DF 2 "register_operand" "0,f")]))]
16111   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16112    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16113   "* return output_387_binary_op (insn, operands);"
16114   [(set (attr "type")
16115         (cond [(match_operand:DF 3 "mult_operator" "")
16116                  (const_string "fmul")
16117                (match_operand:DF 3 "div_operator" "")
16118                  (const_string "fdiv")
16119               ]
16120               (const_string "fop")))
16121    (set_attr "mode" "SF")])
16122
16123 (define_insn "*fop_df_5_i387"
16124   [(set (match_operand:DF 0 "register_operand" "=f,f")
16125         (match_operator:DF 3 "binary_fp_operator"
16126           [(match_operand:DF 1 "register_operand" "0,f")
16127            (float_extend:DF
16128             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16129   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16130   "* return output_387_binary_op (insn, operands);"
16131   [(set (attr "type")
16132         (cond [(match_operand:DF 3 "mult_operator" "")
16133                  (const_string "fmul")
16134                (match_operand:DF 3 "div_operator" "")
16135                  (const_string "fdiv")
16136               ]
16137               (const_string "fop")))
16138    (set_attr "mode" "SF")])
16139
16140 (define_insn "*fop_df_6_i387"
16141   [(set (match_operand:DF 0 "register_operand" "=f,f")
16142         (match_operator:DF 3 "binary_fp_operator"
16143           [(float_extend:DF
16144             (match_operand:SF 1 "register_operand" "0,f"))
16145            (float_extend:DF
16146             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16147   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16148   "* return output_387_binary_op (insn, operands);"
16149   [(set (attr "type")
16150         (cond [(match_operand:DF 3 "mult_operator" "")
16151                  (const_string "fmul")
16152                (match_operand:DF 3 "div_operator" "")
16153                  (const_string "fdiv")
16154               ]
16155               (const_string "fop")))
16156    (set_attr "mode" "SF")])
16157
16158 (define_insn "*fop_xf_comm_i387"
16159   [(set (match_operand:XF 0 "register_operand" "=f")
16160         (match_operator:XF 3 "binary_fp_operator"
16161                         [(match_operand:XF 1 "register_operand" "%0")
16162                          (match_operand:XF 2 "register_operand" "f")]))]
16163   "TARGET_80387
16164    && COMMUTATIVE_ARITH_P (operands[3])"
16165   "* return output_387_binary_op (insn, operands);"
16166   [(set (attr "type")
16167         (if_then_else (match_operand:XF 3 "mult_operator" "")
16168            (const_string "fmul")
16169            (const_string "fop")))
16170    (set_attr "mode" "XF")])
16171
16172 (define_insn "*fop_xf_1_i387"
16173   [(set (match_operand:XF 0 "register_operand" "=f,f")
16174         (match_operator:XF 3 "binary_fp_operator"
16175                         [(match_operand:XF 1 "register_operand" "0,f")
16176                          (match_operand:XF 2 "register_operand" "f,0")]))]
16177   "TARGET_80387
16178    && !COMMUTATIVE_ARITH_P (operands[3])"
16179   "* return output_387_binary_op (insn, operands);"
16180   [(set (attr "type")
16181         (cond [(match_operand:XF 3 "mult_operator" "")
16182                  (const_string "fmul")
16183                (match_operand:XF 3 "div_operator" "")
16184                  (const_string "fdiv")
16185               ]
16186               (const_string "fop")))
16187    (set_attr "mode" "XF")])
16188
16189 (define_insn "*fop_xf_2<mode>_i387"
16190   [(set (match_operand:XF 0 "register_operand" "=f,f")
16191         (match_operator:XF 3 "binary_fp_operator"
16192            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16193             (match_operand:XF 2 "register_operand" "0,0")]))]
16194   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16195   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16196   [(set (attr "type")
16197         (cond [(match_operand:XF 3 "mult_operator" "")
16198                  (const_string "fmul")
16199                (match_operand:XF 3 "div_operator" "")
16200                  (const_string "fdiv")
16201               ]
16202               (const_string "fop")))
16203    (set_attr "fp_int_src" "true")
16204    (set_attr "mode" "<MODE>")])
16205
16206 (define_insn "*fop_xf_3<mode>_i387"
16207   [(set (match_operand:XF 0 "register_operand" "=f,f")
16208         (match_operator:XF 3 "binary_fp_operator"
16209           [(match_operand:XF 1 "register_operand" "0,0")
16210            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16211   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16212   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16213   [(set (attr "type")
16214         (cond [(match_operand:XF 3 "mult_operator" "")
16215                  (const_string "fmul")
16216                (match_operand:XF 3 "div_operator" "")
16217                  (const_string "fdiv")
16218               ]
16219               (const_string "fop")))
16220    (set_attr "fp_int_src" "true")
16221    (set_attr "mode" "<MODE>")])
16222
16223 (define_insn "*fop_xf_4_i387"
16224   [(set (match_operand:XF 0 "register_operand" "=f,f")
16225         (match_operator:XF 3 "binary_fp_operator"
16226            [(float_extend:XF
16227               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16228             (match_operand:XF 2 "register_operand" "0,f")]))]
16229   "TARGET_80387"
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" "SF")])
16239
16240 (define_insn "*fop_xf_5_i387"
16241   [(set (match_operand:XF 0 "register_operand" "=f,f")
16242         (match_operator:XF 3 "binary_fp_operator"
16243           [(match_operand:XF 1 "register_operand" "0,f")
16244            (float_extend:XF
16245              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16246   "TARGET_80387"
16247   "* return output_387_binary_op (insn, operands);"
16248   [(set (attr "type")
16249         (cond [(match_operand:XF 3 "mult_operator" "")
16250                  (const_string "fmul")
16251                (match_operand:XF 3 "div_operator" "")
16252                  (const_string "fdiv")
16253               ]
16254               (const_string "fop")))
16255    (set_attr "mode" "SF")])
16256
16257 (define_insn "*fop_xf_6_i387"
16258   [(set (match_operand:XF 0 "register_operand" "=f,f")
16259         (match_operator:XF 3 "binary_fp_operator"
16260           [(float_extend:XF
16261              (match_operand:MODEF 1 "register_operand" "0,f"))
16262            (float_extend:XF
16263              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16264   "TARGET_80387"
16265   "* return output_387_binary_op (insn, operands);"
16266   [(set (attr "type")
16267         (cond [(match_operand:XF 3 "mult_operator" "")
16268                  (const_string "fmul")
16269                (match_operand:XF 3 "div_operator" "")
16270                  (const_string "fdiv")
16271               ]
16272               (const_string "fop")))
16273    (set_attr "mode" "SF")])
16274
16275 (define_split
16276   [(set (match_operand 0 "register_operand" "")
16277         (match_operator 3 "binary_fp_operator"
16278            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16279             (match_operand 2 "register_operand" "")]))]
16280   "reload_completed
16281    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16282   [(const_int 0)]
16283 {
16284   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16285   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16286   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16287                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16288                                           GET_MODE (operands[3]),
16289                                           operands[4],
16290                                           operands[2])));
16291   ix86_free_from_memory (GET_MODE (operands[1]));
16292   DONE;
16293 })
16294
16295 (define_split
16296   [(set (match_operand 0 "register_operand" "")
16297         (match_operator 3 "binary_fp_operator"
16298            [(match_operand 1 "register_operand" "")
16299             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16300   "reload_completed
16301    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16302   [(const_int 0)]
16303 {
16304   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16305   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16306   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16307                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16308                                           GET_MODE (operands[3]),
16309                                           operands[1],
16310                                           operands[4])));
16311   ix86_free_from_memory (GET_MODE (operands[2]));
16312   DONE;
16313 })
16314 \f
16315 ;; FPU special functions.
16316
16317 ;; This pattern implements a no-op XFmode truncation for
16318 ;; all fancy i386 XFmode math functions.
16319
16320 (define_insn "truncxf<mode>2_i387_noop_unspec"
16321   [(set (match_operand:MODEF 0 "register_operand" "=f")
16322         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16323         UNSPEC_TRUNC_NOOP))]
16324   "TARGET_USE_FANCY_MATH_387"
16325   "* return output_387_reg_move (insn, operands);"
16326   [(set_attr "type" "fmov")
16327    (set_attr "mode" "<MODE>")])
16328
16329 (define_insn "sqrtxf2"
16330   [(set (match_operand:XF 0 "register_operand" "=f")
16331         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16332   "TARGET_USE_FANCY_MATH_387"
16333   "fsqrt"
16334   [(set_attr "type" "fpspc")
16335    (set_attr "mode" "XF")
16336    (set_attr "athlon_decode" "direct")
16337    (set_attr "amdfam10_decode" "direct")])
16338
16339 (define_insn "sqrt_extend<mode>xf2_i387"
16340   [(set (match_operand:XF 0 "register_operand" "=f")
16341         (sqrt:XF
16342           (float_extend:XF
16343             (match_operand:MODEF 1 "register_operand" "0"))))]
16344   "TARGET_USE_FANCY_MATH_387"
16345   "fsqrt"
16346   [(set_attr "type" "fpspc")
16347    (set_attr "mode" "XF")
16348    (set_attr "athlon_decode" "direct")
16349    (set_attr "amdfam10_decode" "direct")])
16350
16351 (define_insn "*rsqrtsf2_sse"
16352   [(set (match_operand:SF 0 "register_operand" "=x")
16353         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16354                    UNSPEC_RSQRT))]
16355   "TARGET_SSE_MATH"
16356   "rsqrtss\t{%1, %0|%0, %1}"
16357   [(set_attr "type" "sse")
16358    (set_attr "mode" "SF")])
16359
16360 (define_expand "rsqrtsf2"
16361   [(set (match_operand:SF 0 "register_operand" "")
16362         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16363                    UNSPEC_RSQRT))]
16364   "TARGET_SSE_MATH"
16365 {
16366   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16367   DONE;
16368 })
16369
16370 (define_insn "*sqrt<mode>2_sse"
16371   [(set (match_operand:MODEF 0 "register_operand" "=x")
16372         (sqrt:MODEF
16373           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16374   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16375   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16376   [(set_attr "type" "sse")
16377    (set_attr "mode" "<MODE>")
16378    (set_attr "athlon_decode" "*")
16379    (set_attr "amdfam10_decode" "*")])
16380
16381 (define_expand "sqrt<mode>2"
16382   [(set (match_operand:MODEF 0 "register_operand" "")
16383         (sqrt:MODEF
16384           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16385   "TARGET_USE_FANCY_MATH_387
16386    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16387 {
16388   if (<MODE>mode == SFmode
16389       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16390       && flag_finite_math_only && !flag_trapping_math
16391       && flag_unsafe_math_optimizations)
16392     {
16393       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16394       DONE;
16395     }
16396
16397   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16398     {
16399       rtx op0 = gen_reg_rtx (XFmode);
16400       rtx op1 = force_reg (<MODE>mode, operands[1]);
16401
16402       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16403       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16404       DONE;
16405    }
16406 })
16407
16408 (define_insn "fpremxf4_i387"
16409   [(set (match_operand:XF 0 "register_operand" "=f")
16410         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16411                     (match_operand:XF 3 "register_operand" "1")]
16412                    UNSPEC_FPREM_F))
16413    (set (match_operand:XF 1 "register_operand" "=u")
16414         (unspec:XF [(match_dup 2) (match_dup 3)]
16415                    UNSPEC_FPREM_U))
16416    (set (reg:CCFP FPSR_REG)
16417         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16418                      UNSPEC_C2_FLAG))]
16419   "TARGET_USE_FANCY_MATH_387"
16420   "fprem"
16421   [(set_attr "type" "fpspc")
16422    (set_attr "mode" "XF")])
16423
16424 (define_expand "fmodxf3"
16425   [(use (match_operand:XF 0 "register_operand" ""))
16426    (use (match_operand:XF 1 "general_operand" ""))
16427    (use (match_operand:XF 2 "general_operand" ""))]
16428   "TARGET_USE_FANCY_MATH_387"
16429 {
16430   rtx label = gen_label_rtx ();
16431
16432   rtx op1 = gen_reg_rtx (XFmode);
16433   rtx op2 = gen_reg_rtx (XFmode);
16434
16435   emit_move_insn (op1, operands[1]);
16436   emit_move_insn (op2, operands[2]);
16437
16438   emit_label (label);
16439   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16440   ix86_emit_fp_unordered_jump (label);
16441   LABEL_NUSES (label) = 1;
16442
16443   emit_move_insn (operands[0], op1);
16444   DONE;
16445 })
16446
16447 (define_expand "fmod<mode>3"
16448   [(use (match_operand:MODEF 0 "register_operand" ""))
16449    (use (match_operand:MODEF 1 "general_operand" ""))
16450    (use (match_operand:MODEF 2 "general_operand" ""))]
16451   "TARGET_USE_FANCY_MATH_387"
16452 {
16453   rtx label = gen_label_rtx ();
16454
16455   rtx op1 = gen_reg_rtx (XFmode);
16456   rtx op2 = gen_reg_rtx (XFmode);
16457
16458   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16459   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16460
16461   emit_label (label);
16462   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16463   ix86_emit_fp_unordered_jump (label);
16464   LABEL_NUSES (label) = 1;
16465
16466   /* Truncate the result properly for strict SSE math.  */
16467   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16468       && !TARGET_MIX_SSE_I387)
16469     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16470   else
16471     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16472
16473   DONE;
16474 })
16475
16476 (define_insn "fprem1xf4_i387"
16477   [(set (match_operand:XF 0 "register_operand" "=f")
16478         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16479                     (match_operand:XF 3 "register_operand" "1")]
16480                    UNSPEC_FPREM1_F))
16481    (set (match_operand:XF 1 "register_operand" "=u")
16482         (unspec:XF [(match_dup 2) (match_dup 3)]
16483                    UNSPEC_FPREM1_U))
16484    (set (reg:CCFP FPSR_REG)
16485         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16486                      UNSPEC_C2_FLAG))]
16487   "TARGET_USE_FANCY_MATH_387"
16488   "fprem1"
16489   [(set_attr "type" "fpspc")
16490    (set_attr "mode" "XF")])
16491
16492 (define_expand "remainderxf3"
16493   [(use (match_operand:XF 0 "register_operand" ""))
16494    (use (match_operand:XF 1 "general_operand" ""))
16495    (use (match_operand:XF 2 "general_operand" ""))]
16496   "TARGET_USE_FANCY_MATH_387"
16497 {
16498   rtx label = gen_label_rtx ();
16499
16500   rtx op1 = gen_reg_rtx (XFmode);
16501   rtx op2 = gen_reg_rtx (XFmode);
16502
16503   emit_move_insn (op1, operands[1]);
16504   emit_move_insn (op2, operands[2]);
16505
16506   emit_label (label);
16507   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16508   ix86_emit_fp_unordered_jump (label);
16509   LABEL_NUSES (label) = 1;
16510
16511   emit_move_insn (operands[0], op1);
16512   DONE;
16513 })
16514
16515 (define_expand "remainder<mode>3"
16516   [(use (match_operand:MODEF 0 "register_operand" ""))
16517    (use (match_operand:MODEF 1 "general_operand" ""))
16518    (use (match_operand:MODEF 2 "general_operand" ""))]
16519   "TARGET_USE_FANCY_MATH_387"
16520 {
16521   rtx label = gen_label_rtx ();
16522
16523   rtx op1 = gen_reg_rtx (XFmode);
16524   rtx op2 = gen_reg_rtx (XFmode);
16525
16526   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16527   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16528
16529   emit_label (label);
16530
16531   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16532   ix86_emit_fp_unordered_jump (label);
16533   LABEL_NUSES (label) = 1;
16534
16535   /* Truncate the result properly for strict SSE math.  */
16536   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16537       && !TARGET_MIX_SSE_I387)
16538     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16539   else
16540     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16541
16542   DONE;
16543 })
16544
16545 (define_insn "*sinxf2_i387"
16546   [(set (match_operand:XF 0 "register_operand" "=f")
16547         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16548   "TARGET_USE_FANCY_MATH_387
16549    && flag_unsafe_math_optimizations"
16550   "fsin"
16551   [(set_attr "type" "fpspc")
16552    (set_attr "mode" "XF")])
16553
16554 (define_insn "*sin_extend<mode>xf2_i387"
16555   [(set (match_operand:XF 0 "register_operand" "=f")
16556         (unspec:XF [(float_extend:XF
16557                       (match_operand:MODEF 1 "register_operand" "0"))]
16558                    UNSPEC_SIN))]
16559   "TARGET_USE_FANCY_MATH_387
16560    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16561        || TARGET_MIX_SSE_I387)
16562    && flag_unsafe_math_optimizations"
16563   "fsin"
16564   [(set_attr "type" "fpspc")
16565    (set_attr "mode" "XF")])
16566
16567 (define_insn "*cosxf2_i387"
16568   [(set (match_operand:XF 0 "register_operand" "=f")
16569         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16570   "TARGET_USE_FANCY_MATH_387
16571    && flag_unsafe_math_optimizations"
16572   "fcos"
16573   [(set_attr "type" "fpspc")
16574    (set_attr "mode" "XF")])
16575
16576 (define_insn "*cos_extend<mode>xf2_i387"
16577   [(set (match_operand:XF 0 "register_operand" "=f")
16578         (unspec:XF [(float_extend:XF
16579                       (match_operand:MODEF 1 "register_operand" "0"))]
16580                    UNSPEC_COS))]
16581   "TARGET_USE_FANCY_MATH_387
16582    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16583        || TARGET_MIX_SSE_I387)
16584    && flag_unsafe_math_optimizations"
16585   "fcos"
16586   [(set_attr "type" "fpspc")
16587    (set_attr "mode" "XF")])
16588
16589 ;; When sincos pattern is defined, sin and cos builtin functions will be
16590 ;; expanded to sincos pattern with one of its outputs left unused.
16591 ;; CSE pass will figure out if two sincos patterns can be combined,
16592 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16593 ;; depending on the unused output.
16594
16595 (define_insn "sincosxf3"
16596   [(set (match_operand:XF 0 "register_operand" "=f")
16597         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16598                    UNSPEC_SINCOS_COS))
16599    (set (match_operand:XF 1 "register_operand" "=u")
16600         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16601   "TARGET_USE_FANCY_MATH_387
16602    && flag_unsafe_math_optimizations"
16603   "fsincos"
16604   [(set_attr "type" "fpspc")
16605    (set_attr "mode" "XF")])
16606
16607 (define_split
16608   [(set (match_operand:XF 0 "register_operand" "")
16609         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16610                    UNSPEC_SINCOS_COS))
16611    (set (match_operand:XF 1 "register_operand" "")
16612         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16613   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16614    && !(reload_completed || reload_in_progress)"
16615   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16616   "")
16617
16618 (define_split
16619   [(set (match_operand:XF 0 "register_operand" "")
16620         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16621                    UNSPEC_SINCOS_COS))
16622    (set (match_operand:XF 1 "register_operand" "")
16623         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16624   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16625    && !(reload_completed || reload_in_progress)"
16626   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16627   "")
16628
16629 (define_insn "sincos_extend<mode>xf3_i387"
16630   [(set (match_operand:XF 0 "register_operand" "=f")
16631         (unspec:XF [(float_extend:XF
16632                       (match_operand:MODEF 2 "register_operand" "0"))]
16633                    UNSPEC_SINCOS_COS))
16634    (set (match_operand:XF 1 "register_operand" "=u")
16635         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16636   "TARGET_USE_FANCY_MATH_387
16637    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16638        || TARGET_MIX_SSE_I387)
16639    && flag_unsafe_math_optimizations"
16640   "fsincos"
16641   [(set_attr "type" "fpspc")
16642    (set_attr "mode" "XF")])
16643
16644 (define_split
16645   [(set (match_operand:XF 0 "register_operand" "")
16646         (unspec:XF [(float_extend:XF
16647                       (match_operand:MODEF 2 "register_operand" ""))]
16648                    UNSPEC_SINCOS_COS))
16649    (set (match_operand:XF 1 "register_operand" "")
16650         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16651   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16652    && !(reload_completed || reload_in_progress)"
16653   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16654   "")
16655
16656 (define_split
16657   [(set (match_operand:XF 0 "register_operand" "")
16658         (unspec:XF [(float_extend:XF
16659                       (match_operand:MODEF 2 "register_operand" ""))]
16660                    UNSPEC_SINCOS_COS))
16661    (set (match_operand:XF 1 "register_operand" "")
16662         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16663   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16664    && !(reload_completed || reload_in_progress)"
16665   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16666   "")
16667
16668 (define_expand "sincos<mode>3"
16669   [(use (match_operand:MODEF 0 "register_operand" ""))
16670    (use (match_operand:MODEF 1 "register_operand" ""))
16671    (use (match_operand:MODEF 2 "register_operand" ""))]
16672   "TARGET_USE_FANCY_MATH_387
16673    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16674        || TARGET_MIX_SSE_I387)
16675    && flag_unsafe_math_optimizations"
16676 {
16677   rtx op0 = gen_reg_rtx (XFmode);
16678   rtx op1 = gen_reg_rtx (XFmode);
16679
16680   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16681   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16682   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16683   DONE;
16684 })
16685
16686 (define_insn "fptanxf4_i387"
16687   [(set (match_operand:XF 0 "register_operand" "=f")
16688         (match_operand:XF 3 "const_double_operand" "F"))
16689    (set (match_operand:XF 1 "register_operand" "=u")
16690         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16691                    UNSPEC_TAN))]
16692   "TARGET_USE_FANCY_MATH_387
16693    && flag_unsafe_math_optimizations
16694    && standard_80387_constant_p (operands[3]) == 2"
16695   "fptan"
16696   [(set_attr "type" "fpspc")
16697    (set_attr "mode" "XF")])
16698
16699 (define_insn "fptan_extend<mode>xf4_i387"
16700   [(set (match_operand:MODEF 0 "register_operand" "=f")
16701         (match_operand:MODEF 3 "const_double_operand" "F"))
16702    (set (match_operand:XF 1 "register_operand" "=u")
16703         (unspec:XF [(float_extend:XF
16704                       (match_operand:MODEF 2 "register_operand" "0"))]
16705                    UNSPEC_TAN))]
16706   "TARGET_USE_FANCY_MATH_387
16707    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16708        || TARGET_MIX_SSE_I387)
16709    && flag_unsafe_math_optimizations
16710    && standard_80387_constant_p (operands[3]) == 2"
16711   "fptan"
16712   [(set_attr "type" "fpspc")
16713    (set_attr "mode" "XF")])
16714
16715 (define_expand "tanxf2"
16716   [(use (match_operand:XF 0 "register_operand" ""))
16717    (use (match_operand:XF 1 "register_operand" ""))]
16718   "TARGET_USE_FANCY_MATH_387
16719    && flag_unsafe_math_optimizations"
16720 {
16721   rtx one = gen_reg_rtx (XFmode);
16722   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16723
16724   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16725   DONE;
16726 })
16727
16728 (define_expand "tan<mode>2"
16729   [(use (match_operand:MODEF 0 "register_operand" ""))
16730    (use (match_operand:MODEF 1 "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
16738   rtx one = gen_reg_rtx (<MODE>mode);
16739   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16740
16741   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16742                                              operands[1], op2));
16743   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16744   DONE;
16745 })
16746
16747 (define_insn "*fpatanxf3_i387"
16748   [(set (match_operand:XF 0 "register_operand" "=f")
16749         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16750                     (match_operand:XF 2 "register_operand" "u")]
16751                    UNSPEC_FPATAN))
16752    (clobber (match_scratch:XF 3 "=2"))]
16753   "TARGET_USE_FANCY_MATH_387
16754    && flag_unsafe_math_optimizations"
16755   "fpatan"
16756   [(set_attr "type" "fpspc")
16757    (set_attr "mode" "XF")])
16758
16759 (define_insn "fpatan_extend<mode>xf3_i387"
16760   [(set (match_operand:XF 0 "register_operand" "=f")
16761         (unspec:XF [(float_extend:XF
16762                       (match_operand:MODEF 1 "register_operand" "0"))
16763                     (float_extend:XF
16764                       (match_operand:MODEF 2 "register_operand" "u"))]
16765                    UNSPEC_FPATAN))
16766    (clobber (match_scratch:XF 3 "=2"))]
16767   "TARGET_USE_FANCY_MATH_387
16768    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16769        || TARGET_MIX_SSE_I387)
16770    && flag_unsafe_math_optimizations"
16771   "fpatan"
16772   [(set_attr "type" "fpspc")
16773    (set_attr "mode" "XF")])
16774
16775 (define_expand "atan2xf3"
16776   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16777                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16778                                (match_operand:XF 1 "register_operand" "")]
16779                               UNSPEC_FPATAN))
16780               (clobber (match_scratch:XF 3 ""))])]
16781   "TARGET_USE_FANCY_MATH_387
16782    && flag_unsafe_math_optimizations"
16783   "")
16784
16785 (define_expand "atan2<mode>3"
16786   [(use (match_operand:MODEF 0 "register_operand" ""))
16787    (use (match_operand:MODEF 1 "register_operand" ""))
16788    (use (match_operand:MODEF 2 "register_operand" ""))]
16789   "TARGET_USE_FANCY_MATH_387
16790    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16791        || TARGET_MIX_SSE_I387)
16792    && flag_unsafe_math_optimizations"
16793 {
16794   rtx op0 = gen_reg_rtx (XFmode);
16795
16796   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16797   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16798   DONE;
16799 })
16800
16801 (define_expand "atanxf2"
16802   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16803                    (unspec:XF [(match_dup 2)
16804                                (match_operand:XF 1 "register_operand" "")]
16805                               UNSPEC_FPATAN))
16806               (clobber (match_scratch:XF 3 ""))])]
16807   "TARGET_USE_FANCY_MATH_387
16808    && flag_unsafe_math_optimizations"
16809 {
16810   operands[2] = gen_reg_rtx (XFmode);
16811   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16812 })
16813
16814 (define_expand "atan<mode>2"
16815   [(use (match_operand:MODEF 0 "register_operand" ""))
16816    (use (match_operand:MODEF 1 "register_operand" ""))]
16817   "TARGET_USE_FANCY_MATH_387
16818    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16819        || TARGET_MIX_SSE_I387)
16820    && flag_unsafe_math_optimizations"
16821 {
16822   rtx op0 = gen_reg_rtx (XFmode);
16823
16824   rtx op2 = gen_reg_rtx (<MODE>mode);
16825   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16826
16827   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16828   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16829   DONE;
16830 })
16831
16832 (define_expand "asinxf2"
16833   [(set (match_dup 2)
16834         (mult:XF (match_operand:XF 1 "register_operand" "")
16835                  (match_dup 1)))
16836    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16837    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16838    (parallel [(set (match_operand:XF 0 "register_operand" "")
16839                    (unspec:XF [(match_dup 5) (match_dup 1)]
16840                               UNSPEC_FPATAN))
16841               (clobber (match_scratch:XF 6 ""))])]
16842   "TARGET_USE_FANCY_MATH_387
16843    && flag_unsafe_math_optimizations && !optimize_size"
16844 {
16845   int i;
16846
16847   for (i = 2; i < 6; i++)
16848     operands[i] = gen_reg_rtx (XFmode);
16849
16850   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16851 })
16852
16853 (define_expand "asin<mode>2"
16854   [(use (match_operand:MODEF 0 "register_operand" ""))
16855    (use (match_operand:MODEF 1 "general_operand" ""))]
16856  "TARGET_USE_FANCY_MATH_387
16857    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16858        || TARGET_MIX_SSE_I387)
16859    && flag_unsafe_math_optimizations && !optimize_size"
16860 {
16861   rtx op0 = gen_reg_rtx (XFmode);
16862   rtx op1 = gen_reg_rtx (XFmode);
16863
16864   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16865   emit_insn (gen_asinxf2 (op0, op1));
16866   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16867   DONE;
16868 })
16869
16870 (define_expand "acosxf2"
16871   [(set (match_dup 2)
16872         (mult:XF (match_operand:XF 1 "register_operand" "")
16873                  (match_dup 1)))
16874    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16875    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16876    (parallel [(set (match_operand:XF 0 "register_operand" "")
16877                    (unspec:XF [(match_dup 1) (match_dup 5)]
16878                               UNSPEC_FPATAN))
16879               (clobber (match_scratch:XF 6 ""))])]
16880   "TARGET_USE_FANCY_MATH_387
16881    && flag_unsafe_math_optimizations && !optimize_size"
16882 {
16883   int i;
16884
16885   for (i = 2; i < 6; i++)
16886     operands[i] = gen_reg_rtx (XFmode);
16887
16888   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16889 })
16890
16891 (define_expand "acos<mode>2"
16892   [(use (match_operand:MODEF 0 "register_operand" ""))
16893    (use (match_operand:MODEF 1 "general_operand" ""))]
16894  "TARGET_USE_FANCY_MATH_387
16895    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16896        || TARGET_MIX_SSE_I387)
16897    && flag_unsafe_math_optimizations && !optimize_size"
16898 {
16899   rtx op0 = gen_reg_rtx (XFmode);
16900   rtx op1 = gen_reg_rtx (XFmode);
16901
16902   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16903   emit_insn (gen_acosxf2 (op0, op1));
16904   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16905   DONE;
16906 })
16907
16908 (define_insn "fyl2xxf3_i387"
16909   [(set (match_operand:XF 0 "register_operand" "=f")
16910         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16911                     (match_operand:XF 2 "register_operand" "u")]
16912                    UNSPEC_FYL2X))
16913    (clobber (match_scratch:XF 3 "=2"))]
16914   "TARGET_USE_FANCY_MATH_387
16915    && flag_unsafe_math_optimizations"
16916   "fyl2x"
16917   [(set_attr "type" "fpspc")
16918    (set_attr "mode" "XF")])
16919
16920 (define_insn "fyl2x_extend<mode>xf3_i387"
16921   [(set (match_operand:XF 0 "register_operand" "=f")
16922         (unspec:XF [(float_extend:XF
16923                       (match_operand:MODEF 1 "register_operand" "0"))
16924                     (match_operand:XF 2 "register_operand" "u")]
16925                    UNSPEC_FYL2X))
16926    (clobber (match_scratch:XF 3 "=2"))]
16927   "TARGET_USE_FANCY_MATH_387
16928    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16929        || TARGET_MIX_SSE_I387)
16930    && flag_unsafe_math_optimizations"
16931   "fyl2x"
16932   [(set_attr "type" "fpspc")
16933    (set_attr "mode" "XF")])
16934
16935 (define_expand "logxf2"
16936   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16937                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16938                                (match_dup 2)] UNSPEC_FYL2X))
16939               (clobber (match_scratch:XF 3 ""))])]
16940   "TARGET_USE_FANCY_MATH_387
16941    && flag_unsafe_math_optimizations"
16942 {
16943   operands[2] = gen_reg_rtx (XFmode);
16944   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16945 })
16946
16947 (define_expand "log<mode>2"
16948   [(use (match_operand:MODEF 0 "register_operand" ""))
16949    (use (match_operand:MODEF 1 "register_operand" ""))]
16950   "TARGET_USE_FANCY_MATH_387
16951    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16952        || TARGET_MIX_SSE_I387)
16953    && flag_unsafe_math_optimizations"
16954 {
16955   rtx op0 = gen_reg_rtx (XFmode);
16956
16957   rtx op2 = gen_reg_rtx (XFmode);
16958   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16959
16960   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16961   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16962   DONE;
16963 })
16964
16965 (define_expand "log10xf2"
16966   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16967                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16968                                (match_dup 2)] UNSPEC_FYL2X))
16969               (clobber (match_scratch:XF 3 ""))])]
16970   "TARGET_USE_FANCY_MATH_387
16971    && flag_unsafe_math_optimizations"
16972 {
16973   operands[2] = gen_reg_rtx (XFmode);
16974   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16975 })
16976
16977 (define_expand "log10<mode>2"
16978   [(use (match_operand:MODEF 0 "register_operand" ""))
16979    (use (match_operand:MODEF 1 "register_operand" ""))]
16980   "TARGET_USE_FANCY_MATH_387
16981    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16982        || TARGET_MIX_SSE_I387)
16983    && flag_unsafe_math_optimizations"
16984 {
16985   rtx op0 = gen_reg_rtx (XFmode);
16986
16987   rtx op2 = gen_reg_rtx (XFmode);
16988   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16989
16990   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16991   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16992   DONE;
16993 })
16994
16995 (define_expand "log2xf2"
16996   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16997                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16998                                (match_dup 2)] UNSPEC_FYL2X))
16999               (clobber (match_scratch:XF 3 ""))])]
17000   "TARGET_USE_FANCY_MATH_387
17001    && flag_unsafe_math_optimizations"
17002 {
17003   operands[2] = gen_reg_rtx (XFmode);
17004   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17005 })
17006
17007 (define_expand "log2<mode>2"
17008   [(use (match_operand:MODEF 0 "register_operand" ""))
17009    (use (match_operand:MODEF 1 "register_operand" ""))]
17010   "TARGET_USE_FANCY_MATH_387
17011    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17012        || TARGET_MIX_SSE_I387)
17013    && flag_unsafe_math_optimizations"
17014 {
17015   rtx op0 = gen_reg_rtx (XFmode);
17016
17017   rtx op2 = gen_reg_rtx (XFmode);
17018   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17019
17020   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17021   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17022   DONE;
17023 })
17024
17025 (define_insn "fyl2xp1xf3_i387"
17026   [(set (match_operand:XF 0 "register_operand" "=f")
17027         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17028                     (match_operand:XF 2 "register_operand" "u")]
17029                    UNSPEC_FYL2XP1))
17030    (clobber (match_scratch:XF 3 "=2"))]
17031   "TARGET_USE_FANCY_MATH_387
17032    && flag_unsafe_math_optimizations"
17033   "fyl2xp1"
17034   [(set_attr "type" "fpspc")
17035    (set_attr "mode" "XF")])
17036
17037 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17038   [(set (match_operand:XF 0 "register_operand" "=f")
17039         (unspec:XF [(float_extend:XF
17040                       (match_operand:MODEF 1 "register_operand" "0"))
17041                     (match_operand:XF 2 "register_operand" "u")]
17042                    UNSPEC_FYL2XP1))
17043    (clobber (match_scratch:XF 3 "=2"))]
17044   "TARGET_USE_FANCY_MATH_387
17045    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17046        || TARGET_MIX_SSE_I387)
17047    && flag_unsafe_math_optimizations"
17048   "fyl2xp1"
17049   [(set_attr "type" "fpspc")
17050    (set_attr "mode" "XF")])
17051
17052 (define_expand "log1pxf2"
17053   [(use (match_operand:XF 0 "register_operand" ""))
17054    (use (match_operand:XF 1 "register_operand" ""))]
17055   "TARGET_USE_FANCY_MATH_387
17056    && flag_unsafe_math_optimizations && !optimize_size"
17057 {
17058   ix86_emit_i387_log1p (operands[0], operands[1]);
17059   DONE;
17060 })
17061
17062 (define_expand "log1p<mode>2"
17063   [(use (match_operand:MODEF 0 "register_operand" ""))
17064    (use (match_operand:MODEF 1 "register_operand" ""))]
17065   "TARGET_USE_FANCY_MATH_387
17066    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17067        || TARGET_MIX_SSE_I387)
17068    && flag_unsafe_math_optimizations && !optimize_size"
17069 {
17070   rtx op0 = gen_reg_rtx (XFmode);
17071
17072   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17073
17074   ix86_emit_i387_log1p (op0, operands[1]);
17075   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17076   DONE;
17077 })
17078
17079 (define_insn "fxtractxf3_i387"
17080   [(set (match_operand:XF 0 "register_operand" "=f")
17081         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17082                    UNSPEC_XTRACT_FRACT))
17083    (set (match_operand:XF 1 "register_operand" "=u")
17084         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17085   "TARGET_USE_FANCY_MATH_387
17086    && flag_unsafe_math_optimizations"
17087   "fxtract"
17088   [(set_attr "type" "fpspc")
17089    (set_attr "mode" "XF")])
17090
17091 (define_insn "fxtract_extend<mode>xf3_i387"
17092   [(set (match_operand:XF 0 "register_operand" "=f")
17093         (unspec:XF [(float_extend:XF
17094                       (match_operand:MODEF 2 "register_operand" "0"))]
17095                    UNSPEC_XTRACT_FRACT))
17096    (set (match_operand:XF 1 "register_operand" "=u")
17097         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17098   "TARGET_USE_FANCY_MATH_387
17099    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17100        || TARGET_MIX_SSE_I387)
17101    && flag_unsafe_math_optimizations"
17102   "fxtract"
17103   [(set_attr "type" "fpspc")
17104    (set_attr "mode" "XF")])
17105
17106 (define_expand "logbxf2"
17107   [(parallel [(set (match_dup 2)
17108                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17109                               UNSPEC_XTRACT_FRACT))
17110               (set (match_operand:XF 0 "register_operand" "")
17111                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17112   "TARGET_USE_FANCY_MATH_387
17113    && flag_unsafe_math_optimizations"
17114 {
17115   operands[2] = gen_reg_rtx (XFmode);
17116 })
17117
17118 (define_expand "logb<mode>2"
17119   [(use (match_operand:MODEF 0 "register_operand" ""))
17120    (use (match_operand:MODEF 1 "register_operand" ""))]
17121   "TARGET_USE_FANCY_MATH_387
17122    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17123        || TARGET_MIX_SSE_I387)
17124    && flag_unsafe_math_optimizations"
17125 {
17126   rtx op0 = gen_reg_rtx (XFmode);
17127   rtx op1 = gen_reg_rtx (XFmode);
17128
17129   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17130   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17131   DONE;
17132 })
17133
17134 (define_expand "ilogbxf2"
17135   [(use (match_operand:SI 0 "register_operand" ""))
17136    (use (match_operand:XF 1 "register_operand" ""))]
17137   "TARGET_USE_FANCY_MATH_387
17138    && flag_unsafe_math_optimizations && !optimize_size"
17139 {
17140   rtx op0 = gen_reg_rtx (XFmode);
17141   rtx op1 = gen_reg_rtx (XFmode);
17142
17143   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17144   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17145   DONE;
17146 })
17147
17148 (define_expand "ilogb<mode>2"
17149   [(use (match_operand:SI 0 "register_operand" ""))
17150    (use (match_operand:MODEF 1 "register_operand" ""))]
17151   "TARGET_USE_FANCY_MATH_387
17152    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17153        || TARGET_MIX_SSE_I387)
17154    && flag_unsafe_math_optimizations && !optimize_size"
17155 {
17156   rtx op0 = gen_reg_rtx (XFmode);
17157   rtx op1 = gen_reg_rtx (XFmode);
17158
17159   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17160   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17161   DONE;
17162 })
17163
17164 (define_insn "*f2xm1xf2_i387"
17165   [(set (match_operand:XF 0 "register_operand" "=f")
17166         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17167                    UNSPEC_F2XM1))]
17168   "TARGET_USE_FANCY_MATH_387
17169    && flag_unsafe_math_optimizations"
17170   "f2xm1"
17171   [(set_attr "type" "fpspc")
17172    (set_attr "mode" "XF")])
17173
17174 (define_insn "*fscalexf4_i387"
17175   [(set (match_operand:XF 0 "register_operand" "=f")
17176         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17177                     (match_operand:XF 3 "register_operand" "1")]
17178                    UNSPEC_FSCALE_FRACT))
17179    (set (match_operand:XF 1 "register_operand" "=u")
17180         (unspec:XF [(match_dup 2) (match_dup 3)]
17181                    UNSPEC_FSCALE_EXP))]
17182   "TARGET_USE_FANCY_MATH_387
17183    && flag_unsafe_math_optimizations"
17184   "fscale"
17185   [(set_attr "type" "fpspc")
17186    (set_attr "mode" "XF")])
17187
17188 (define_expand "expNcorexf3"
17189   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17190                                (match_operand:XF 2 "register_operand" "")))
17191    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17192    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17193    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17194    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17195    (parallel [(set (match_operand:XF 0 "register_operand" "")
17196                    (unspec:XF [(match_dup 8) (match_dup 4)]
17197                               UNSPEC_FSCALE_FRACT))
17198               (set (match_dup 9)
17199                    (unspec:XF [(match_dup 8) (match_dup 4)]
17200                               UNSPEC_FSCALE_EXP))])]
17201   "TARGET_USE_FANCY_MATH_387
17202    && flag_unsafe_math_optimizations && !optimize_size"
17203 {
17204   int i;
17205
17206   for (i = 3; i < 10; i++)
17207     operands[i] = gen_reg_rtx (XFmode);
17208
17209   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17210 })
17211
17212 (define_expand "expxf2"
17213   [(use (match_operand:XF 0 "register_operand" ""))
17214    (use (match_operand:XF 1 "register_operand" ""))]
17215   "TARGET_USE_FANCY_MATH_387
17216    && flag_unsafe_math_optimizations && !optimize_size"
17217 {
17218   rtx op2 = gen_reg_rtx (XFmode);
17219   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17220
17221   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17222   DONE;
17223 })
17224
17225 (define_expand "exp<mode>2"
17226   [(use (match_operand:MODEF 0 "register_operand" ""))
17227    (use (match_operand:MODEF 1 "general_operand" ""))]
17228  "TARGET_USE_FANCY_MATH_387
17229    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17230        || TARGET_MIX_SSE_I387)
17231    && flag_unsafe_math_optimizations && !optimize_size"
17232 {
17233   rtx op0 = gen_reg_rtx (XFmode);
17234   rtx op1 = gen_reg_rtx (XFmode);
17235
17236   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17237   emit_insn (gen_expxf2 (op0, op1));
17238   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17239   DONE;
17240 })
17241
17242 (define_expand "exp10xf2"
17243   [(use (match_operand:XF 0 "register_operand" ""))
17244    (use (match_operand:XF 1 "register_operand" ""))]
17245   "TARGET_USE_FANCY_MATH_387
17246    && flag_unsafe_math_optimizations && !optimize_size"
17247 {
17248   rtx op2 = gen_reg_rtx (XFmode);
17249   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17250
17251   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17252   DONE;
17253 })
17254
17255 (define_expand "exp10<mode>2"
17256   [(use (match_operand:MODEF 0 "register_operand" ""))
17257    (use (match_operand:MODEF 1 "general_operand" ""))]
17258  "TARGET_USE_FANCY_MATH_387
17259    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17260        || TARGET_MIX_SSE_I387)
17261    && flag_unsafe_math_optimizations && !optimize_size"
17262 {
17263   rtx op0 = gen_reg_rtx (XFmode);
17264   rtx op1 = gen_reg_rtx (XFmode);
17265
17266   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17267   emit_insn (gen_exp10xf2 (op0, op1));
17268   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17269   DONE;
17270 })
17271
17272 (define_expand "exp2xf2"
17273   [(use (match_operand:XF 0 "register_operand" ""))
17274    (use (match_operand:XF 1 "register_operand" ""))]
17275   "TARGET_USE_FANCY_MATH_387
17276    && flag_unsafe_math_optimizations && !optimize_size"
17277 {
17278   rtx op2 = gen_reg_rtx (XFmode);
17279   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17280
17281   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17282   DONE;
17283 })
17284
17285 (define_expand "exp2<mode>2"
17286   [(use (match_operand:MODEF 0 "register_operand" ""))
17287    (use (match_operand:MODEF 1 "general_operand" ""))]
17288  "TARGET_USE_FANCY_MATH_387
17289    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17290        || TARGET_MIX_SSE_I387)
17291    && flag_unsafe_math_optimizations && !optimize_size"
17292 {
17293   rtx op0 = gen_reg_rtx (XFmode);
17294   rtx op1 = gen_reg_rtx (XFmode);
17295
17296   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17297   emit_insn (gen_exp2xf2 (op0, op1));
17298   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17299   DONE;
17300 })
17301
17302 (define_expand "expm1xf2"
17303   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17304                                (match_dup 2)))
17305    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17306    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17307    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17308    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17309    (parallel [(set (match_dup 7)
17310                    (unspec:XF [(match_dup 6) (match_dup 4)]
17311                               UNSPEC_FSCALE_FRACT))
17312               (set (match_dup 8)
17313                    (unspec:XF [(match_dup 6) (match_dup 4)]
17314                               UNSPEC_FSCALE_EXP))])
17315    (parallel [(set (match_dup 10)
17316                    (unspec:XF [(match_dup 9) (match_dup 8)]
17317                               UNSPEC_FSCALE_FRACT))
17318               (set (match_dup 11)
17319                    (unspec:XF [(match_dup 9) (match_dup 8)]
17320                               UNSPEC_FSCALE_EXP))])
17321    (set (match_dup 12) (minus:XF (match_dup 10)
17322                                  (float_extend:XF (match_dup 13))))
17323    (set (match_operand:XF 0 "register_operand" "")
17324         (plus:XF (match_dup 12) (match_dup 7)))]
17325   "TARGET_USE_FANCY_MATH_387
17326    && flag_unsafe_math_optimizations && !optimize_size"
17327 {
17328   int i;
17329
17330   for (i = 2; i < 13; i++)
17331     operands[i] = gen_reg_rtx (XFmode);
17332
17333   operands[13]
17334     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17335
17336   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17337 })
17338
17339 (define_expand "expm1<mode>2"
17340   [(use (match_operand:MODEF 0 "register_operand" ""))
17341    (use (match_operand:MODEF 1 "general_operand" ""))]
17342  "TARGET_USE_FANCY_MATH_387
17343    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17344        || TARGET_MIX_SSE_I387)
17345    && flag_unsafe_math_optimizations && !optimize_size"
17346 {
17347   rtx op0 = gen_reg_rtx (XFmode);
17348   rtx op1 = gen_reg_rtx (XFmode);
17349
17350   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17351   emit_insn (gen_expm1xf2 (op0, op1));
17352   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17353   DONE;
17354 })
17355
17356 (define_expand "ldexpxf3"
17357   [(set (match_dup 3)
17358         (float:XF (match_operand:SI 2 "register_operand" "")))
17359    (parallel [(set (match_operand:XF 0 " register_operand" "")
17360                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17361                                (match_dup 3)]
17362                               UNSPEC_FSCALE_FRACT))
17363               (set (match_dup 4)
17364                    (unspec:XF [(match_dup 1) (match_dup 3)]
17365                               UNSPEC_FSCALE_EXP))])]
17366   "TARGET_USE_FANCY_MATH_387
17367    && flag_unsafe_math_optimizations && !optimize_size"
17368 {
17369   operands[3] = gen_reg_rtx (XFmode);
17370   operands[4] = gen_reg_rtx (XFmode);
17371 })
17372
17373 (define_expand "ldexp<mode>3"
17374   [(use (match_operand:MODEF 0 "register_operand" ""))
17375    (use (match_operand:MODEF 1 "general_operand" ""))
17376    (use (match_operand:SI 2 "register_operand" ""))]
17377  "TARGET_USE_FANCY_MATH_387
17378    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17379        || TARGET_MIX_SSE_I387)
17380    && flag_unsafe_math_optimizations && !optimize_size"
17381 {
17382   rtx op0 = gen_reg_rtx (XFmode);
17383   rtx op1 = gen_reg_rtx (XFmode);
17384
17385   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17386   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17387   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17388   DONE;
17389 })
17390
17391 (define_expand "scalbxf3"
17392   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17393                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17394                                (match_operand:XF 2 "register_operand" "")]
17395                               UNSPEC_FSCALE_FRACT))
17396               (set (match_dup 3)
17397                    (unspec:XF [(match_dup 1) (match_dup 2)]
17398                               UNSPEC_FSCALE_EXP))])]
17399   "TARGET_USE_FANCY_MATH_387
17400    && flag_unsafe_math_optimizations && !optimize_size"
17401 {
17402   operands[3] = gen_reg_rtx (XFmode);
17403 })
17404
17405 (define_expand "scalb<mode>3"
17406   [(use (match_operand:MODEF 0 "register_operand" ""))
17407    (use (match_operand:MODEF 1 "general_operand" ""))
17408    (use (match_operand:MODEF 2 "register_operand" ""))]
17409  "TARGET_USE_FANCY_MATH_387
17410    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17411        || TARGET_MIX_SSE_I387)
17412    && flag_unsafe_math_optimizations && !optimize_size"
17413 {
17414   rtx op0 = gen_reg_rtx (XFmode);
17415   rtx op1 = gen_reg_rtx (XFmode);
17416   rtx op2 = gen_reg_rtx (XFmode);
17417
17418   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17419   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17420   emit_insn (gen_scalbxf3 (op0, op1, op2));
17421   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17422   DONE;
17423 })
17424 \f
17425
17426 (define_insn "sse4_1_round<mode>2"
17427   [(set (match_operand:MODEF 0 "register_operand" "=x")
17428         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17429                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
17430                       UNSPEC_ROUND))]
17431   "TARGET_ROUND"
17432   "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17433   [(set_attr "type" "ssecvt")
17434    (set_attr "prefix_extra" "1")
17435    (set_attr "mode" "<MODE>")])
17436
17437 (define_insn "rintxf2"
17438   [(set (match_operand:XF 0 "register_operand" "=f")
17439         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17440                    UNSPEC_FRNDINT))]
17441   "TARGET_USE_FANCY_MATH_387
17442    && flag_unsafe_math_optimizations"
17443   "frndint"
17444   [(set_attr "type" "fpspc")
17445    (set_attr "mode" "XF")])
17446
17447 (define_expand "rint<mode>2"
17448   [(use (match_operand:MODEF 0 "register_operand" ""))
17449    (use (match_operand:MODEF 1 "register_operand" ""))]
17450   "(TARGET_USE_FANCY_MATH_387
17451     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17452         || TARGET_MIX_SSE_I387)
17453     && flag_unsafe_math_optimizations)
17454    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17455        && !flag_trapping_math
17456        && (TARGET_ROUND || !optimize_size))"
17457 {
17458   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17459       && !flag_trapping_math
17460       && (TARGET_ROUND || !optimize_size))
17461     {
17462       if (TARGET_ROUND)
17463         emit_insn (gen_sse4_1_round<mode>2
17464                    (operands[0], operands[1], GEN_INT (0x04)));
17465       else
17466         ix86_expand_rint (operand0, operand1);
17467     }
17468   else
17469     {
17470       rtx op0 = gen_reg_rtx (XFmode);
17471       rtx op1 = gen_reg_rtx (XFmode);
17472
17473       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17474       emit_insn (gen_rintxf2 (op0, op1));
17475
17476       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17477     }
17478   DONE;
17479 })
17480
17481 (define_expand "round<mode>2"
17482   [(match_operand:MODEF 0 "register_operand" "")
17483    (match_operand:MODEF 1 "nonimmediate_operand" "")]
17484   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17485    && !flag_trapping_math && !flag_rounding_math
17486    && !optimize_size"
17487 {
17488   if (TARGET_64BIT || (<MODE>mode != DFmode))
17489     ix86_expand_round (operand0, operand1);
17490   else
17491     ix86_expand_rounddf_32 (operand0, operand1);
17492   DONE;
17493 })
17494
17495 (define_insn_and_split "*fistdi2_1"
17496   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17497         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17498                    UNSPEC_FIST))]
17499   "TARGET_USE_FANCY_MATH_387
17500    && !(reload_completed || reload_in_progress)"
17501   "#"
17502   "&& 1"
17503   [(const_int 0)]
17504 {
17505   if (memory_operand (operands[0], VOIDmode))
17506     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17507   else
17508     {
17509       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17510       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17511                                          operands[2]));
17512     }
17513   DONE;
17514 }
17515   [(set_attr "type" "fpspc")
17516    (set_attr "mode" "DI")])
17517
17518 (define_insn "fistdi2"
17519   [(set (match_operand:DI 0 "memory_operand" "=m")
17520         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17521                    UNSPEC_FIST))
17522    (clobber (match_scratch:XF 2 "=&1f"))]
17523   "TARGET_USE_FANCY_MATH_387"
17524   "* return output_fix_trunc (insn, operands, 0);"
17525   [(set_attr "type" "fpspc")
17526    (set_attr "mode" "DI")])
17527
17528 (define_insn "fistdi2_with_temp"
17529   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17530         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17531                    UNSPEC_FIST))
17532    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17533    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17534   "TARGET_USE_FANCY_MATH_387"
17535   "#"
17536   [(set_attr "type" "fpspc")
17537    (set_attr "mode" "DI")])
17538
17539 (define_split
17540   [(set (match_operand:DI 0 "register_operand" "")
17541         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17542                    UNSPEC_FIST))
17543    (clobber (match_operand:DI 2 "memory_operand" ""))
17544    (clobber (match_scratch 3 ""))]
17545   "reload_completed"
17546   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17547               (clobber (match_dup 3))])
17548    (set (match_dup 0) (match_dup 2))]
17549   "")
17550
17551 (define_split
17552   [(set (match_operand:DI 0 "memory_operand" "")
17553         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17554                    UNSPEC_FIST))
17555    (clobber (match_operand:DI 2 "memory_operand" ""))
17556    (clobber (match_scratch 3 ""))]
17557   "reload_completed"
17558   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17559               (clobber (match_dup 3))])]
17560   "")
17561
17562 (define_insn_and_split "*fist<mode>2_1"
17563   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17564         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17565                            UNSPEC_FIST))]
17566   "TARGET_USE_FANCY_MATH_387
17567    && !(reload_completed || reload_in_progress)"
17568   "#"
17569   "&& 1"
17570   [(const_int 0)]
17571 {
17572   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17573   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17574                                         operands[2]));
17575   DONE;
17576 }
17577   [(set_attr "type" "fpspc")
17578    (set_attr "mode" "<MODE>")])
17579
17580 (define_insn "fist<mode>2"
17581   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17582         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17583                            UNSPEC_FIST))]
17584   "TARGET_USE_FANCY_MATH_387"
17585   "* return output_fix_trunc (insn, operands, 0);"
17586   [(set_attr "type" "fpspc")
17587    (set_attr "mode" "<MODE>")])
17588
17589 (define_insn "fist<mode>2_with_temp"
17590   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17591         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17592                            UNSPEC_FIST))
17593    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17594   "TARGET_USE_FANCY_MATH_387"
17595   "#"
17596   [(set_attr "type" "fpspc")
17597    (set_attr "mode" "<MODE>")])
17598
17599 (define_split
17600   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17601         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17602                            UNSPEC_FIST))
17603    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17604   "reload_completed"
17605   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17606    (set (match_dup 0) (match_dup 2))]
17607   "")
17608
17609 (define_split
17610   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17611         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17612                            UNSPEC_FIST))
17613    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17614   "reload_completed"
17615   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17616   "")
17617
17618 (define_expand "lrintxf<mode>2"
17619   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17620      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17621                       UNSPEC_FIST))]
17622   "TARGET_USE_FANCY_MATH_387"
17623   "")
17624
17625 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17626   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17627      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17628                         UNSPEC_FIX_NOTRUNC))]
17629   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17630    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17631   "")
17632
17633 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17634   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17635    (match_operand:MODEF 1 "register_operand" "")]
17636   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17637    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17638    && !flag_trapping_math && !flag_rounding_math
17639    && !optimize_size"
17640 {
17641   ix86_expand_lround (operand0, operand1);
17642   DONE;
17643 })
17644
17645 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17646 (define_insn_and_split "frndintxf2_floor"
17647   [(set (match_operand:XF 0 "register_operand" "")
17648         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17649          UNSPEC_FRNDINT_FLOOR))
17650    (clobber (reg:CC FLAGS_REG))]
17651   "TARGET_USE_FANCY_MATH_387
17652    && flag_unsafe_math_optimizations
17653    && !(reload_completed || reload_in_progress)"
17654   "#"
17655   "&& 1"
17656   [(const_int 0)]
17657 {
17658   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17659
17660   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17661   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17662
17663   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17664                                         operands[2], operands[3]));
17665   DONE;
17666 }
17667   [(set_attr "type" "frndint")
17668    (set_attr "i387_cw" "floor")
17669    (set_attr "mode" "XF")])
17670
17671 (define_insn "frndintxf2_floor_i387"
17672   [(set (match_operand:XF 0 "register_operand" "=f")
17673         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17674          UNSPEC_FRNDINT_FLOOR))
17675    (use (match_operand:HI 2 "memory_operand" "m"))
17676    (use (match_operand:HI 3 "memory_operand" "m"))]
17677   "TARGET_USE_FANCY_MATH_387
17678    && flag_unsafe_math_optimizations"
17679   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17680   [(set_attr "type" "frndint")
17681    (set_attr "i387_cw" "floor")
17682    (set_attr "mode" "XF")])
17683
17684 (define_expand "floorxf2"
17685   [(use (match_operand:XF 0 "register_operand" ""))
17686    (use (match_operand:XF 1 "register_operand" ""))]
17687   "TARGET_USE_FANCY_MATH_387
17688    && flag_unsafe_math_optimizations && !optimize_size"
17689 {
17690   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17691   DONE;
17692 })
17693
17694 (define_expand "floor<mode>2"
17695   [(use (match_operand:MODEF 0 "register_operand" ""))
17696    (use (match_operand:MODEF 1 "register_operand" ""))]
17697   "(TARGET_USE_FANCY_MATH_387
17698     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17699         || TARGET_MIX_SSE_I387)
17700     && flag_unsafe_math_optimizations && !optimize_size)
17701    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17702        && !flag_trapping_math
17703        && (TARGET_ROUND || !optimize_size))"
17704 {
17705   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17706       && !flag_trapping_math
17707       && (TARGET_ROUND || !optimize_size))
17708     {
17709       if (TARGET_ROUND)
17710         emit_insn (gen_sse4_1_round<mode>2
17711                    (operands[0], operands[1], GEN_INT (0x01)));
17712       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17713         ix86_expand_floorceil (operand0, operand1, true);
17714       else
17715         ix86_expand_floorceildf_32 (operand0, operand1, true);
17716     }
17717   else
17718     {
17719       rtx op0 = gen_reg_rtx (XFmode);
17720       rtx op1 = gen_reg_rtx (XFmode);
17721
17722       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17723       emit_insn (gen_frndintxf2_floor (op0, op1));
17724
17725       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17726     }
17727   DONE;
17728 })
17729
17730 (define_insn_and_split "*fist<mode>2_floor_1"
17731   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17732         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17733          UNSPEC_FIST_FLOOR))
17734    (clobber (reg:CC FLAGS_REG))]
17735   "TARGET_USE_FANCY_MATH_387
17736    && flag_unsafe_math_optimizations
17737    && !(reload_completed || reload_in_progress)"
17738   "#"
17739   "&& 1"
17740   [(const_int 0)]
17741 {
17742   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17743
17744   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17745   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17746   if (memory_operand (operands[0], VOIDmode))
17747     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17748                                       operands[2], operands[3]));
17749   else
17750     {
17751       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17752       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17753                                                   operands[2], operands[3],
17754                                                   operands[4]));
17755     }
17756   DONE;
17757 }
17758   [(set_attr "type" "fistp")
17759    (set_attr "i387_cw" "floor")
17760    (set_attr "mode" "<MODE>")])
17761
17762 (define_insn "fistdi2_floor"
17763   [(set (match_operand:DI 0 "memory_operand" "=m")
17764         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17765          UNSPEC_FIST_FLOOR))
17766    (use (match_operand:HI 2 "memory_operand" "m"))
17767    (use (match_operand:HI 3 "memory_operand" "m"))
17768    (clobber (match_scratch:XF 4 "=&1f"))]
17769   "TARGET_USE_FANCY_MATH_387
17770    && flag_unsafe_math_optimizations"
17771   "* return output_fix_trunc (insn, operands, 0);"
17772   [(set_attr "type" "fistp")
17773    (set_attr "i387_cw" "floor")
17774    (set_attr "mode" "DI")])
17775
17776 (define_insn "fistdi2_floor_with_temp"
17777   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17778         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17779          UNSPEC_FIST_FLOOR))
17780    (use (match_operand:HI 2 "memory_operand" "m,m"))
17781    (use (match_operand:HI 3 "memory_operand" "m,m"))
17782    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17783    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17784   "TARGET_USE_FANCY_MATH_387
17785    && flag_unsafe_math_optimizations"
17786   "#"
17787   [(set_attr "type" "fistp")
17788    (set_attr "i387_cw" "floor")
17789    (set_attr "mode" "DI")])
17790
17791 (define_split
17792   [(set (match_operand:DI 0 "register_operand" "")
17793         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17794          UNSPEC_FIST_FLOOR))
17795    (use (match_operand:HI 2 "memory_operand" ""))
17796    (use (match_operand:HI 3 "memory_operand" ""))
17797    (clobber (match_operand:DI 4 "memory_operand" ""))
17798    (clobber (match_scratch 5 ""))]
17799   "reload_completed"
17800   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17801               (use (match_dup 2))
17802               (use (match_dup 3))
17803               (clobber (match_dup 5))])
17804    (set (match_dup 0) (match_dup 4))]
17805   "")
17806
17807 (define_split
17808   [(set (match_operand:DI 0 "memory_operand" "")
17809         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17810          UNSPEC_FIST_FLOOR))
17811    (use (match_operand:HI 2 "memory_operand" ""))
17812    (use (match_operand:HI 3 "memory_operand" ""))
17813    (clobber (match_operand:DI 4 "memory_operand" ""))
17814    (clobber (match_scratch 5 ""))]
17815   "reload_completed"
17816   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17817               (use (match_dup 2))
17818               (use (match_dup 3))
17819               (clobber (match_dup 5))])]
17820   "")
17821
17822 (define_insn "fist<mode>2_floor"
17823   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17824         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17825          UNSPEC_FIST_FLOOR))
17826    (use (match_operand:HI 2 "memory_operand" "m"))
17827    (use (match_operand:HI 3 "memory_operand" "m"))]
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" "<MODE>")])
17834
17835 (define_insn "fist<mode>2_floor_with_temp"
17836   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17837         (unspec:X87MODEI12 [(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:X87MODEI12 4 "memory_operand" "=X,m"))]
17842   "TARGET_USE_FANCY_MATH_387
17843    && flag_unsafe_math_optimizations"
17844   "#"
17845   [(set_attr "type" "fistp")
17846    (set_attr "i387_cw" "floor")
17847    (set_attr "mode" "<MODE>")])
17848
17849 (define_split
17850   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17851         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17852          UNSPEC_FIST_FLOOR))
17853    (use (match_operand:HI 2 "memory_operand" ""))
17854    (use (match_operand:HI 3 "memory_operand" ""))
17855    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17856   "reload_completed"
17857   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17858                                   UNSPEC_FIST_FLOOR))
17859               (use (match_dup 2))
17860               (use (match_dup 3))])
17861    (set (match_dup 0) (match_dup 4))]
17862   "")
17863
17864 (define_split
17865   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17866         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17867          UNSPEC_FIST_FLOOR))
17868    (use (match_operand:HI 2 "memory_operand" ""))
17869    (use (match_operand:HI 3 "memory_operand" ""))
17870    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17871   "reload_completed"
17872   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17873                                   UNSPEC_FIST_FLOOR))
17874               (use (match_dup 2))
17875               (use (match_dup 3))])]
17876   "")
17877
17878 (define_expand "lfloorxf<mode>2"
17879   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17880                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17881                     UNSPEC_FIST_FLOOR))
17882               (clobber (reg:CC FLAGS_REG))])]
17883   "TARGET_USE_FANCY_MATH_387
17884    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17885    && flag_unsafe_math_optimizations"
17886   "")
17887
17888 (define_expand "lfloor<mode>di2"
17889   [(match_operand:DI 0 "nonimmediate_operand" "")
17890    (match_operand:MODEF 1 "register_operand" "")]
17891   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17892    && !flag_trapping_math
17893    && !optimize_size"
17894 {
17895   ix86_expand_lfloorceil (operand0, operand1, true);
17896   DONE;
17897 })
17898
17899 (define_expand "lfloor<mode>si2"
17900   [(match_operand:SI 0 "nonimmediate_operand" "")
17901    (match_operand:MODEF 1 "register_operand" "")]
17902   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17903    && !flag_trapping_math
17904    && (!optimize_size || !TARGET_64BIT)"
17905 {
17906   ix86_expand_lfloorceil (operand0, operand1, true);
17907   DONE;
17908 })
17909
17910 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17911 (define_insn_and_split "frndintxf2_ceil"
17912   [(set (match_operand:XF 0 "register_operand" "")
17913         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17914          UNSPEC_FRNDINT_CEIL))
17915    (clobber (reg:CC FLAGS_REG))]
17916   "TARGET_USE_FANCY_MATH_387
17917    && flag_unsafe_math_optimizations
17918    && !(reload_completed || reload_in_progress)"
17919   "#"
17920   "&& 1"
17921   [(const_int 0)]
17922 {
17923   ix86_optimize_mode_switching[I387_CEIL] = 1;
17924
17925   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17926   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17927
17928   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17929                                        operands[2], operands[3]));
17930   DONE;
17931 }
17932   [(set_attr "type" "frndint")
17933    (set_attr "i387_cw" "ceil")
17934    (set_attr "mode" "XF")])
17935
17936 (define_insn "frndintxf2_ceil_i387"
17937   [(set (match_operand:XF 0 "register_operand" "=f")
17938         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17939          UNSPEC_FRNDINT_CEIL))
17940    (use (match_operand:HI 2 "memory_operand" "m"))
17941    (use (match_operand:HI 3 "memory_operand" "m"))]
17942   "TARGET_USE_FANCY_MATH_387
17943    && flag_unsafe_math_optimizations"
17944   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17945   [(set_attr "type" "frndint")
17946    (set_attr "i387_cw" "ceil")
17947    (set_attr "mode" "XF")])
17948
17949 (define_expand "ceilxf2"
17950   [(use (match_operand:XF 0 "register_operand" ""))
17951    (use (match_operand:XF 1 "register_operand" ""))]
17952   "TARGET_USE_FANCY_MATH_387
17953    && flag_unsafe_math_optimizations && !optimize_size"
17954 {
17955   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17956   DONE;
17957 })
17958
17959 (define_expand "ceil<mode>2"
17960   [(use (match_operand:MODEF 0 "register_operand" ""))
17961    (use (match_operand:MODEF 1 "register_operand" ""))]
17962   "(TARGET_USE_FANCY_MATH_387
17963     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17964         || TARGET_MIX_SSE_I387)
17965     && flag_unsafe_math_optimizations && !optimize_size)
17966    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17967        && !flag_trapping_math
17968        && (TARGET_ROUND || !optimize_size))"
17969 {
17970   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17971       && !flag_trapping_math
17972       && (TARGET_ROUND || !optimize_size))
17973     {
17974       if (TARGET_ROUND)
17975         emit_insn (gen_sse4_1_round<mode>2
17976                    (operands[0], operands[1], GEN_INT (0x02)));
17977       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17978         ix86_expand_floorceil (operand0, operand1, false);
17979       else
17980         ix86_expand_floorceildf_32 (operand0, operand1, false);
17981     }
17982   else
17983     {
17984       rtx op0 = gen_reg_rtx (XFmode);
17985       rtx op1 = gen_reg_rtx (XFmode);
17986
17987       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17988       emit_insn (gen_frndintxf2_ceil (op0, op1));
17989
17990       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17991     }
17992   DONE;
17993 })
17994
17995 (define_insn_and_split "*fist<mode>2_ceil_1"
17996   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17997         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17998          UNSPEC_FIST_CEIL))
17999    (clobber (reg:CC FLAGS_REG))]
18000   "TARGET_USE_FANCY_MATH_387
18001    && flag_unsafe_math_optimizations
18002    && !(reload_completed || reload_in_progress)"
18003   "#"
18004   "&& 1"
18005   [(const_int 0)]
18006 {
18007   ix86_optimize_mode_switching[I387_CEIL] = 1;
18008
18009   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18010   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18011   if (memory_operand (operands[0], VOIDmode))
18012     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18013                                      operands[2], operands[3]));
18014   else
18015     {
18016       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18017       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18018                                                  operands[2], operands[3],
18019                                                  operands[4]));
18020     }
18021   DONE;
18022 }
18023   [(set_attr "type" "fistp")
18024    (set_attr "i387_cw" "ceil")
18025    (set_attr "mode" "<MODE>")])
18026
18027 (define_insn "fistdi2_ceil"
18028   [(set (match_operand:DI 0 "memory_operand" "=m")
18029         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18030          UNSPEC_FIST_CEIL))
18031    (use (match_operand:HI 2 "memory_operand" "m"))
18032    (use (match_operand:HI 3 "memory_operand" "m"))
18033    (clobber (match_scratch:XF 4 "=&1f"))]
18034   "TARGET_USE_FANCY_MATH_387
18035    && flag_unsafe_math_optimizations"
18036   "* return output_fix_trunc (insn, operands, 0);"
18037   [(set_attr "type" "fistp")
18038    (set_attr "i387_cw" "ceil")
18039    (set_attr "mode" "DI")])
18040
18041 (define_insn "fistdi2_ceil_with_temp"
18042   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18043         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18044          UNSPEC_FIST_CEIL))
18045    (use (match_operand:HI 2 "memory_operand" "m,m"))
18046    (use (match_operand:HI 3 "memory_operand" "m,m"))
18047    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18048    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18049   "TARGET_USE_FANCY_MATH_387
18050    && flag_unsafe_math_optimizations"
18051   "#"
18052   [(set_attr "type" "fistp")
18053    (set_attr "i387_cw" "ceil")
18054    (set_attr "mode" "DI")])
18055
18056 (define_split
18057   [(set (match_operand:DI 0 "register_operand" "")
18058         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18059          UNSPEC_FIST_CEIL))
18060    (use (match_operand:HI 2 "memory_operand" ""))
18061    (use (match_operand:HI 3 "memory_operand" ""))
18062    (clobber (match_operand:DI 4 "memory_operand" ""))
18063    (clobber (match_scratch 5 ""))]
18064   "reload_completed"
18065   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18066               (use (match_dup 2))
18067               (use (match_dup 3))
18068               (clobber (match_dup 5))])
18069    (set (match_dup 0) (match_dup 4))]
18070   "")
18071
18072 (define_split
18073   [(set (match_operand:DI 0 "memory_operand" "")
18074         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18075          UNSPEC_FIST_CEIL))
18076    (use (match_operand:HI 2 "memory_operand" ""))
18077    (use (match_operand:HI 3 "memory_operand" ""))
18078    (clobber (match_operand:DI 4 "memory_operand" ""))
18079    (clobber (match_scratch 5 ""))]
18080   "reload_completed"
18081   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18082               (use (match_dup 2))
18083               (use (match_dup 3))
18084               (clobber (match_dup 5))])]
18085   "")
18086
18087 (define_insn "fist<mode>2_ceil"
18088   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18089         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18090          UNSPEC_FIST_CEIL))
18091    (use (match_operand:HI 2 "memory_operand" "m"))
18092    (use (match_operand:HI 3 "memory_operand" "m"))]
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" "<MODE>")])
18099
18100 (define_insn "fist<mode>2_ceil_with_temp"
18101   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18102         (unspec:X87MODEI12 [(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:X87MODEI12 4 "memory_operand" "=X,m"))]
18107   "TARGET_USE_FANCY_MATH_387
18108    && flag_unsafe_math_optimizations"
18109   "#"
18110   [(set_attr "type" "fistp")
18111    (set_attr "i387_cw" "ceil")
18112    (set_attr "mode" "<MODE>")])
18113
18114 (define_split
18115   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18116         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18117          UNSPEC_FIST_CEIL))
18118    (use (match_operand:HI 2 "memory_operand" ""))
18119    (use (match_operand:HI 3 "memory_operand" ""))
18120    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18121   "reload_completed"
18122   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18123                                   UNSPEC_FIST_CEIL))
18124               (use (match_dup 2))
18125               (use (match_dup 3))])
18126    (set (match_dup 0) (match_dup 4))]
18127   "")
18128
18129 (define_split
18130   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18131         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18132          UNSPEC_FIST_CEIL))
18133    (use (match_operand:HI 2 "memory_operand" ""))
18134    (use (match_operand:HI 3 "memory_operand" ""))
18135    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18136   "reload_completed"
18137   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18138                                   UNSPEC_FIST_CEIL))
18139               (use (match_dup 2))
18140               (use (match_dup 3))])]
18141   "")
18142
18143 (define_expand "lceilxf<mode>2"
18144   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18145                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18146                     UNSPEC_FIST_CEIL))
18147               (clobber (reg:CC FLAGS_REG))])]
18148   "TARGET_USE_FANCY_MATH_387
18149    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18150    && flag_unsafe_math_optimizations"
18151   "")
18152
18153 (define_expand "lceil<mode>di2"
18154   [(match_operand:DI 0 "nonimmediate_operand" "")
18155    (match_operand:MODEF 1 "register_operand" "")]
18156   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18157    && !flag_trapping_math"
18158 {
18159   ix86_expand_lfloorceil (operand0, operand1, false);
18160   DONE;
18161 })
18162
18163 (define_expand "lceil<mode>si2"
18164   [(match_operand:SI 0 "nonimmediate_operand" "")
18165    (match_operand:MODEF 1 "register_operand" "")]
18166   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18167    && !flag_trapping_math"
18168 {
18169   ix86_expand_lfloorceil (operand0, operand1, false);
18170   DONE;
18171 })
18172
18173 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18174 (define_insn_and_split "frndintxf2_trunc"
18175   [(set (match_operand:XF 0 "register_operand" "")
18176         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18177          UNSPEC_FRNDINT_TRUNC))
18178    (clobber (reg:CC FLAGS_REG))]
18179   "TARGET_USE_FANCY_MATH_387
18180    && flag_unsafe_math_optimizations
18181    && !(reload_completed || reload_in_progress)"
18182   "#"
18183   "&& 1"
18184   [(const_int 0)]
18185 {
18186   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18187
18188   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18189   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18190
18191   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18192                                         operands[2], operands[3]));
18193   DONE;
18194 }
18195   [(set_attr "type" "frndint")
18196    (set_attr "i387_cw" "trunc")
18197    (set_attr "mode" "XF")])
18198
18199 (define_insn "frndintxf2_trunc_i387"
18200   [(set (match_operand:XF 0 "register_operand" "=f")
18201         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18202          UNSPEC_FRNDINT_TRUNC))
18203    (use (match_operand:HI 2 "memory_operand" "m"))
18204    (use (match_operand:HI 3 "memory_operand" "m"))]
18205   "TARGET_USE_FANCY_MATH_387
18206    && flag_unsafe_math_optimizations"
18207   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18208   [(set_attr "type" "frndint")
18209    (set_attr "i387_cw" "trunc")
18210    (set_attr "mode" "XF")])
18211
18212 (define_expand "btruncxf2"
18213   [(use (match_operand:XF 0 "register_operand" ""))
18214    (use (match_operand:XF 1 "register_operand" ""))]
18215   "TARGET_USE_FANCY_MATH_387
18216    && flag_unsafe_math_optimizations && !optimize_size"
18217 {
18218   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18219   DONE;
18220 })
18221
18222 (define_expand "btrunc<mode>2"
18223   [(use (match_operand:MODEF 0 "register_operand" ""))
18224    (use (match_operand:MODEF 1 "register_operand" ""))]
18225   "(TARGET_USE_FANCY_MATH_387
18226     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18227         || TARGET_MIX_SSE_I387)
18228     && flag_unsafe_math_optimizations && !optimize_size)
18229    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18230        && !flag_trapping_math
18231        && (TARGET_ROUND || !optimize_size))"
18232 {
18233   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18234       && !flag_trapping_math
18235       && (TARGET_ROUND || !optimize_size))
18236     {
18237       if (TARGET_ROUND)
18238         emit_insn (gen_sse4_1_round<mode>2
18239                    (operands[0], operands[1], GEN_INT (0x03)));
18240       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18241         ix86_expand_trunc (operand0, operand1);
18242       else
18243         ix86_expand_truncdf_32 (operand0, operand1);
18244     }
18245   else
18246     {
18247       rtx op0 = gen_reg_rtx (XFmode);
18248       rtx op1 = gen_reg_rtx (XFmode);
18249
18250       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18251       emit_insn (gen_frndintxf2_trunc (op0, op1));
18252
18253       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18254     }
18255   DONE;
18256 })
18257
18258 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18259 (define_insn_and_split "frndintxf2_mask_pm"
18260   [(set (match_operand:XF 0 "register_operand" "")
18261         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18262          UNSPEC_FRNDINT_MASK_PM))
18263    (clobber (reg:CC FLAGS_REG))]
18264   "TARGET_USE_FANCY_MATH_387
18265    && flag_unsafe_math_optimizations
18266    && !(reload_completed || reload_in_progress)"
18267   "#"
18268   "&& 1"
18269   [(const_int 0)]
18270 {
18271   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18272
18273   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18274   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18275
18276   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18277                                           operands[2], operands[3]));
18278   DONE;
18279 }
18280   [(set_attr "type" "frndint")
18281    (set_attr "i387_cw" "mask_pm")
18282    (set_attr "mode" "XF")])
18283
18284 (define_insn "frndintxf2_mask_pm_i387"
18285   [(set (match_operand:XF 0 "register_operand" "=f")
18286         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18287          UNSPEC_FRNDINT_MASK_PM))
18288    (use (match_operand:HI 2 "memory_operand" "m"))
18289    (use (match_operand:HI 3 "memory_operand" "m"))]
18290   "TARGET_USE_FANCY_MATH_387
18291    && flag_unsafe_math_optimizations"
18292   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18293   [(set_attr "type" "frndint")
18294    (set_attr "i387_cw" "mask_pm")
18295    (set_attr "mode" "XF")])
18296
18297 (define_expand "nearbyintxf2"
18298   [(use (match_operand:XF 0 "register_operand" ""))
18299    (use (match_operand:XF 1 "register_operand" ""))]
18300   "TARGET_USE_FANCY_MATH_387
18301    && flag_unsafe_math_optimizations"
18302 {
18303   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18304
18305   DONE;
18306 })
18307
18308 (define_expand "nearbyint<mode>2"
18309   [(use (match_operand:MODEF 0 "register_operand" ""))
18310    (use (match_operand:MODEF 1 "register_operand" ""))]
18311   "TARGET_USE_FANCY_MATH_387
18312    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18313        || TARGET_MIX_SSE_I387)
18314    && flag_unsafe_math_optimizations"
18315 {
18316   rtx op0 = gen_reg_rtx (XFmode);
18317   rtx op1 = gen_reg_rtx (XFmode);
18318
18319   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18320   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18321
18322   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18323   DONE;
18324 })
18325
18326 (define_insn "fxam<mode>2_i387"
18327   [(set (match_operand:HI 0 "register_operand" "=a")
18328         (unspec:HI
18329           [(match_operand:X87MODEF 1 "register_operand" "f")]
18330           UNSPEC_FXAM))]
18331   "TARGET_USE_FANCY_MATH_387"
18332   "fxam\n\tfnstsw\t%0"
18333   [(set_attr "type" "multi")
18334    (set_attr "unit" "i387")
18335    (set_attr "mode" "<MODE>")])
18336
18337 (define_expand "isinf<mode>2"
18338   [(use (match_operand:SI 0 "register_operand" ""))
18339    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18340   "TARGET_USE_FANCY_MATH_387
18341    && TARGET_C99_FUNCTIONS
18342    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18343 {
18344   rtx mask = GEN_INT (0x45);
18345   rtx val = GEN_INT (0x05);
18346
18347   rtx cond;
18348
18349   rtx scratch = gen_reg_rtx (HImode);
18350   rtx res = gen_reg_rtx (QImode);
18351
18352   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18353   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18354   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18355   cond = gen_rtx_fmt_ee (EQ, QImode,
18356                          gen_rtx_REG (CCmode, FLAGS_REG),
18357                          const0_rtx);
18358   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18359   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18360   DONE;
18361 })
18362
18363 (define_expand "signbit<mode>2"
18364   [(use (match_operand:SI 0 "register_operand" ""))
18365    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18366   "TARGET_USE_FANCY_MATH_387
18367    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18368 {
18369   rtx mask = GEN_INT (0x0200);
18370
18371   rtx scratch = gen_reg_rtx (HImode);
18372
18373   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18374   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18375   DONE;
18376 })
18377 \f
18378 ;; Block operation instructions
18379
18380 (define_expand "movmemsi"
18381   [(use (match_operand:BLK 0 "memory_operand" ""))
18382    (use (match_operand:BLK 1 "memory_operand" ""))
18383    (use (match_operand:SI 2 "nonmemory_operand" ""))
18384    (use (match_operand:SI 3 "const_int_operand" ""))
18385    (use (match_operand:SI 4 "const_int_operand" ""))
18386    (use (match_operand:SI 5 "const_int_operand" ""))]
18387   ""
18388 {
18389  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18390                          operands[4], operands[5]))
18391    DONE;
18392  else
18393    FAIL;
18394 })
18395
18396 (define_expand "movmemdi"
18397   [(use (match_operand:BLK 0 "memory_operand" ""))
18398    (use (match_operand:BLK 1 "memory_operand" ""))
18399    (use (match_operand:DI 2 "nonmemory_operand" ""))
18400    (use (match_operand:DI 3 "const_int_operand" ""))
18401    (use (match_operand:SI 4 "const_int_operand" ""))
18402    (use (match_operand:SI 5 "const_int_operand" ""))]
18403   "TARGET_64BIT"
18404 {
18405  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18406                          operands[4], operands[5]))
18407    DONE;
18408  else
18409    FAIL;
18410 })
18411
18412 ;; Most CPUs don't like single string operations
18413 ;; Handle this case here to simplify previous expander.
18414
18415 (define_expand "strmov"
18416   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18417    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18418    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18419               (clobber (reg:CC FLAGS_REG))])
18420    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18421               (clobber (reg:CC FLAGS_REG))])]
18422   ""
18423 {
18424   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18425
18426   /* If .md ever supports :P for Pmode, these can be directly
18427      in the pattern above.  */
18428   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18429   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18430
18431   /* Can't use this if the user has appropriated esi or edi.  */
18432   if ((TARGET_SINGLE_STRINGOP || optimize_size)
18433       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18434     {
18435       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18436                                       operands[2], operands[3],
18437                                       operands[5], operands[6]));
18438       DONE;
18439     }
18440
18441   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18442 })
18443
18444 (define_expand "strmov_singleop"
18445   [(parallel [(set (match_operand 1 "memory_operand" "")
18446                    (match_operand 3 "memory_operand" ""))
18447               (set (match_operand 0 "register_operand" "")
18448                    (match_operand 4 "" ""))
18449               (set (match_operand 2 "register_operand" "")
18450                    (match_operand 5 "" ""))])]
18451   "TARGET_SINGLE_STRINGOP || optimize_size"
18452   "")
18453
18454 (define_insn "*strmovdi_rex_1"
18455   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18456         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18457    (set (match_operand:DI 0 "register_operand" "=D")
18458         (plus:DI (match_dup 2)
18459                  (const_int 8)))
18460    (set (match_operand:DI 1 "register_operand" "=S")
18461         (plus:DI (match_dup 3)
18462                  (const_int 8)))]
18463   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18464   "movsq"
18465   [(set_attr "type" "str")
18466    (set_attr "mode" "DI")
18467    (set_attr "memory" "both")])
18468
18469 (define_insn "*strmovsi_1"
18470   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18471         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18472    (set (match_operand:SI 0 "register_operand" "=D")
18473         (plus:SI (match_dup 2)
18474                  (const_int 4)))
18475    (set (match_operand:SI 1 "register_operand" "=S")
18476         (plus:SI (match_dup 3)
18477                  (const_int 4)))]
18478   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18479   "{movsl|movsd}"
18480   [(set_attr "type" "str")
18481    (set_attr "mode" "SI")
18482    (set_attr "memory" "both")])
18483
18484 (define_insn "*strmovsi_rex_1"
18485   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18486         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18487    (set (match_operand:DI 0 "register_operand" "=D")
18488         (plus:DI (match_dup 2)
18489                  (const_int 4)))
18490    (set (match_operand:DI 1 "register_operand" "=S")
18491         (plus:DI (match_dup 3)
18492                  (const_int 4)))]
18493   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18494   "{movsl|movsd}"
18495   [(set_attr "type" "str")
18496    (set_attr "mode" "SI")
18497    (set_attr "memory" "both")])
18498
18499 (define_insn "*strmovhi_1"
18500   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18501         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18502    (set (match_operand:SI 0 "register_operand" "=D")
18503         (plus:SI (match_dup 2)
18504                  (const_int 2)))
18505    (set (match_operand:SI 1 "register_operand" "=S")
18506         (plus:SI (match_dup 3)
18507                  (const_int 2)))]
18508   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18509   "movsw"
18510   [(set_attr "type" "str")
18511    (set_attr "memory" "both")
18512    (set_attr "mode" "HI")])
18513
18514 (define_insn "*strmovhi_rex_1"
18515   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18516         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18517    (set (match_operand:DI 0 "register_operand" "=D")
18518         (plus:DI (match_dup 2)
18519                  (const_int 2)))
18520    (set (match_operand:DI 1 "register_operand" "=S")
18521         (plus:DI (match_dup 3)
18522                  (const_int 2)))]
18523   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18524   "movsw"
18525   [(set_attr "type" "str")
18526    (set_attr "memory" "both")
18527    (set_attr "mode" "HI")])
18528
18529 (define_insn "*strmovqi_1"
18530   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18531         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18532    (set (match_operand:SI 0 "register_operand" "=D")
18533         (plus:SI (match_dup 2)
18534                  (const_int 1)))
18535    (set (match_operand:SI 1 "register_operand" "=S")
18536         (plus:SI (match_dup 3)
18537                  (const_int 1)))]
18538   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18539   "movsb"
18540   [(set_attr "type" "str")
18541    (set_attr "memory" "both")
18542    (set_attr "mode" "QI")])
18543
18544 (define_insn "*strmovqi_rex_1"
18545   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18546         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18547    (set (match_operand:DI 0 "register_operand" "=D")
18548         (plus:DI (match_dup 2)
18549                  (const_int 1)))
18550    (set (match_operand:DI 1 "register_operand" "=S")
18551         (plus:DI (match_dup 3)
18552                  (const_int 1)))]
18553   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18554   "movsb"
18555   [(set_attr "type" "str")
18556    (set_attr "memory" "both")
18557    (set_attr "mode" "QI")])
18558
18559 (define_expand "rep_mov"
18560   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18561               (set (match_operand 0 "register_operand" "")
18562                    (match_operand 5 "" ""))
18563               (set (match_operand 2 "register_operand" "")
18564                    (match_operand 6 "" ""))
18565               (set (match_operand 1 "memory_operand" "")
18566                    (match_operand 3 "memory_operand" ""))
18567               (use (match_dup 4))])]
18568   ""
18569   "")
18570
18571 (define_insn "*rep_movdi_rex64"
18572   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18573    (set (match_operand:DI 0 "register_operand" "=D")
18574         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18575                             (const_int 3))
18576                  (match_operand:DI 3 "register_operand" "0")))
18577    (set (match_operand:DI 1 "register_operand" "=S")
18578         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18579                  (match_operand:DI 4 "register_operand" "1")))
18580    (set (mem:BLK (match_dup 3))
18581         (mem:BLK (match_dup 4)))
18582    (use (match_dup 5))]
18583   "TARGET_64BIT"
18584   "rep movsq"
18585   [(set_attr "type" "str")
18586    (set_attr "prefix_rep" "1")
18587    (set_attr "memory" "both")
18588    (set_attr "mode" "DI")])
18589
18590 (define_insn "*rep_movsi"
18591   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18592    (set (match_operand:SI 0 "register_operand" "=D")
18593         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18594                             (const_int 2))
18595                  (match_operand:SI 3 "register_operand" "0")))
18596    (set (match_operand:SI 1 "register_operand" "=S")
18597         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18598                  (match_operand:SI 4 "register_operand" "1")))
18599    (set (mem:BLK (match_dup 3))
18600         (mem:BLK (match_dup 4)))
18601    (use (match_dup 5))]
18602   "!TARGET_64BIT"
18603   "rep movs{l|d}"
18604   [(set_attr "type" "str")
18605    (set_attr "prefix_rep" "1")
18606    (set_attr "memory" "both")
18607    (set_attr "mode" "SI")])
18608
18609 (define_insn "*rep_movsi_rex64"
18610   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18611    (set (match_operand:DI 0 "register_operand" "=D")
18612         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18613                             (const_int 2))
18614                  (match_operand:DI 3 "register_operand" "0")))
18615    (set (match_operand:DI 1 "register_operand" "=S")
18616         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18617                  (match_operand:DI 4 "register_operand" "1")))
18618    (set (mem:BLK (match_dup 3))
18619         (mem:BLK (match_dup 4)))
18620    (use (match_dup 5))]
18621   "TARGET_64BIT"
18622   "rep movs{l|d}"
18623   [(set_attr "type" "str")
18624    (set_attr "prefix_rep" "1")
18625    (set_attr "memory" "both")
18626    (set_attr "mode" "SI")])
18627
18628 (define_insn "*rep_movqi"
18629   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18630    (set (match_operand:SI 0 "register_operand" "=D")
18631         (plus:SI (match_operand:SI 3 "register_operand" "0")
18632                  (match_operand:SI 5 "register_operand" "2")))
18633    (set (match_operand:SI 1 "register_operand" "=S")
18634         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18635    (set (mem:BLK (match_dup 3))
18636         (mem:BLK (match_dup 4)))
18637    (use (match_dup 5))]
18638   "!TARGET_64BIT"
18639   "rep movsb"
18640   [(set_attr "type" "str")
18641    (set_attr "prefix_rep" "1")
18642    (set_attr "memory" "both")
18643    (set_attr "mode" "SI")])
18644
18645 (define_insn "*rep_movqi_rex64"
18646   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18647    (set (match_operand:DI 0 "register_operand" "=D")
18648         (plus:DI (match_operand:DI 3 "register_operand" "0")
18649                  (match_operand:DI 5 "register_operand" "2")))
18650    (set (match_operand:DI 1 "register_operand" "=S")
18651         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18652    (set (mem:BLK (match_dup 3))
18653         (mem:BLK (match_dup 4)))
18654    (use (match_dup 5))]
18655   "TARGET_64BIT"
18656   "rep movsb"
18657   [(set_attr "type" "str")
18658    (set_attr "prefix_rep" "1")
18659    (set_attr "memory" "both")
18660    (set_attr "mode" "SI")])
18661
18662 (define_expand "setmemsi"
18663    [(use (match_operand:BLK 0 "memory_operand" ""))
18664     (use (match_operand:SI 1 "nonmemory_operand" ""))
18665     (use (match_operand 2 "const_int_operand" ""))
18666     (use (match_operand 3 "const_int_operand" ""))
18667     (use (match_operand:SI 4 "const_int_operand" ""))
18668     (use (match_operand:SI 5 "const_int_operand" ""))]
18669   ""
18670 {
18671  if (ix86_expand_setmem (operands[0], operands[1],
18672                          operands[2], operands[3],
18673                          operands[4], operands[5]))
18674    DONE;
18675  else
18676    FAIL;
18677 })
18678
18679 (define_expand "setmemdi"
18680    [(use (match_operand:BLK 0 "memory_operand" ""))
18681     (use (match_operand:DI 1 "nonmemory_operand" ""))
18682     (use (match_operand 2 "const_int_operand" ""))
18683     (use (match_operand 3 "const_int_operand" ""))
18684     (use (match_operand 4 "const_int_operand" ""))
18685     (use (match_operand 5 "const_int_operand" ""))]
18686   "TARGET_64BIT"
18687 {
18688  if (ix86_expand_setmem (operands[0], operands[1],
18689                          operands[2], operands[3],
18690                          operands[4], operands[5]))
18691    DONE;
18692  else
18693    FAIL;
18694 })
18695
18696 ;; Most CPUs don't like single string operations
18697 ;; Handle this case here to simplify previous expander.
18698
18699 (define_expand "strset"
18700   [(set (match_operand 1 "memory_operand" "")
18701         (match_operand 2 "register_operand" ""))
18702    (parallel [(set (match_operand 0 "register_operand" "")
18703                    (match_dup 3))
18704               (clobber (reg:CC FLAGS_REG))])]
18705   ""
18706 {
18707   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18708     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18709
18710   /* If .md ever supports :P for Pmode, this can be directly
18711      in the pattern above.  */
18712   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18713                               GEN_INT (GET_MODE_SIZE (GET_MODE
18714                                                       (operands[2]))));
18715   if (TARGET_SINGLE_STRINGOP || optimize_size)
18716     {
18717       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18718                                       operands[3]));
18719       DONE;
18720     }
18721 })
18722
18723 (define_expand "strset_singleop"
18724   [(parallel [(set (match_operand 1 "memory_operand" "")
18725                    (match_operand 2 "register_operand" ""))
18726               (set (match_operand 0 "register_operand" "")
18727                    (match_operand 3 "" ""))])]
18728   "TARGET_SINGLE_STRINGOP || optimize_size"
18729   "")
18730
18731 (define_insn "*strsetdi_rex_1"
18732   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18733         (match_operand:DI 2 "register_operand" "a"))
18734    (set (match_operand:DI 0 "register_operand" "=D")
18735         (plus:DI (match_dup 1)
18736                  (const_int 8)))]
18737   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18738   "stosq"
18739   [(set_attr "type" "str")
18740    (set_attr "memory" "store")
18741    (set_attr "mode" "DI")])
18742
18743 (define_insn "*strsetsi_1"
18744   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18745         (match_operand:SI 2 "register_operand" "a"))
18746    (set (match_operand:SI 0 "register_operand" "=D")
18747         (plus:SI (match_dup 1)
18748                  (const_int 4)))]
18749   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18750   "{stosl|stosd}"
18751   [(set_attr "type" "str")
18752    (set_attr "memory" "store")
18753    (set_attr "mode" "SI")])
18754
18755 (define_insn "*strsetsi_rex_1"
18756   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18757         (match_operand:SI 2 "register_operand" "a"))
18758    (set (match_operand:DI 0 "register_operand" "=D")
18759         (plus:DI (match_dup 1)
18760                  (const_int 4)))]
18761   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18762   "{stosl|stosd}"
18763   [(set_attr "type" "str")
18764    (set_attr "memory" "store")
18765    (set_attr "mode" "SI")])
18766
18767 (define_insn "*strsethi_1"
18768   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18769         (match_operand:HI 2 "register_operand" "a"))
18770    (set (match_operand:SI 0 "register_operand" "=D")
18771         (plus:SI (match_dup 1)
18772                  (const_int 2)))]
18773   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18774   "stosw"
18775   [(set_attr "type" "str")
18776    (set_attr "memory" "store")
18777    (set_attr "mode" "HI")])
18778
18779 (define_insn "*strsethi_rex_1"
18780   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18781         (match_operand:HI 2 "register_operand" "a"))
18782    (set (match_operand:DI 0 "register_operand" "=D")
18783         (plus:DI (match_dup 1)
18784                  (const_int 2)))]
18785   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18786   "stosw"
18787   [(set_attr "type" "str")
18788    (set_attr "memory" "store")
18789    (set_attr "mode" "HI")])
18790
18791 (define_insn "*strsetqi_1"
18792   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18793         (match_operand:QI 2 "register_operand" "a"))
18794    (set (match_operand:SI 0 "register_operand" "=D")
18795         (plus:SI (match_dup 1)
18796                  (const_int 1)))]
18797   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18798   "stosb"
18799   [(set_attr "type" "str")
18800    (set_attr "memory" "store")
18801    (set_attr "mode" "QI")])
18802
18803 (define_insn "*strsetqi_rex_1"
18804   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18805         (match_operand:QI 2 "register_operand" "a"))
18806    (set (match_operand:DI 0 "register_operand" "=D")
18807         (plus:DI (match_dup 1)
18808                  (const_int 1)))]
18809   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18810   "stosb"
18811   [(set_attr "type" "str")
18812    (set_attr "memory" "store")
18813    (set_attr "mode" "QI")])
18814
18815 (define_expand "rep_stos"
18816   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18817               (set (match_operand 0 "register_operand" "")
18818                    (match_operand 4 "" ""))
18819               (set (match_operand 2 "memory_operand" "") (const_int 0))
18820               (use (match_operand 3 "register_operand" ""))
18821               (use (match_dup 1))])]
18822   ""
18823   "")
18824
18825 (define_insn "*rep_stosdi_rex64"
18826   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18827    (set (match_operand:DI 0 "register_operand" "=D")
18828         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18829                             (const_int 3))
18830                  (match_operand:DI 3 "register_operand" "0")))
18831    (set (mem:BLK (match_dup 3))
18832         (const_int 0))
18833    (use (match_operand:DI 2 "register_operand" "a"))
18834    (use (match_dup 4))]
18835   "TARGET_64BIT"
18836   "rep stosq"
18837   [(set_attr "type" "str")
18838    (set_attr "prefix_rep" "1")
18839    (set_attr "memory" "store")
18840    (set_attr "mode" "DI")])
18841
18842 (define_insn "*rep_stossi"
18843   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18844    (set (match_operand:SI 0 "register_operand" "=D")
18845         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18846                             (const_int 2))
18847                  (match_operand:SI 3 "register_operand" "0")))
18848    (set (mem:BLK (match_dup 3))
18849         (const_int 0))
18850    (use (match_operand:SI 2 "register_operand" "a"))
18851    (use (match_dup 4))]
18852   "!TARGET_64BIT"
18853   "rep stos{l|d}"
18854   [(set_attr "type" "str")
18855    (set_attr "prefix_rep" "1")
18856    (set_attr "memory" "store")
18857    (set_attr "mode" "SI")])
18858
18859 (define_insn "*rep_stossi_rex64"
18860   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18861    (set (match_operand:DI 0 "register_operand" "=D")
18862         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18863                             (const_int 2))
18864                  (match_operand:DI 3 "register_operand" "0")))
18865    (set (mem:BLK (match_dup 3))
18866         (const_int 0))
18867    (use (match_operand:SI 2 "register_operand" "a"))
18868    (use (match_dup 4))]
18869   "TARGET_64BIT"
18870   "rep stos{l|d}"
18871   [(set_attr "type" "str")
18872    (set_attr "prefix_rep" "1")
18873    (set_attr "memory" "store")
18874    (set_attr "mode" "SI")])
18875
18876 (define_insn "*rep_stosqi"
18877   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18878    (set (match_operand:SI 0 "register_operand" "=D")
18879         (plus:SI (match_operand:SI 3 "register_operand" "0")
18880                  (match_operand:SI 4 "register_operand" "1")))
18881    (set (mem:BLK (match_dup 3))
18882         (const_int 0))
18883    (use (match_operand:QI 2 "register_operand" "a"))
18884    (use (match_dup 4))]
18885   "!TARGET_64BIT"
18886   "rep stosb"
18887   [(set_attr "type" "str")
18888    (set_attr "prefix_rep" "1")
18889    (set_attr "memory" "store")
18890    (set_attr "mode" "QI")])
18891
18892 (define_insn "*rep_stosqi_rex64"
18893   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18894    (set (match_operand:DI 0 "register_operand" "=D")
18895         (plus:DI (match_operand:DI 3 "register_operand" "0")
18896                  (match_operand:DI 4 "register_operand" "1")))
18897    (set (mem:BLK (match_dup 3))
18898         (const_int 0))
18899    (use (match_operand:QI 2 "register_operand" "a"))
18900    (use (match_dup 4))]
18901   "TARGET_64BIT"
18902   "rep stosb"
18903   [(set_attr "type" "str")
18904    (set_attr "prefix_rep" "1")
18905    (set_attr "memory" "store")
18906    (set_attr "mode" "QI")])
18907
18908 (define_expand "cmpstrnsi"
18909   [(set (match_operand:SI 0 "register_operand" "")
18910         (compare:SI (match_operand:BLK 1 "general_operand" "")
18911                     (match_operand:BLK 2 "general_operand" "")))
18912    (use (match_operand 3 "general_operand" ""))
18913    (use (match_operand 4 "immediate_operand" ""))]
18914   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18915 {
18916   rtx addr1, addr2, out, outlow, count, countreg, align;
18917
18918   /* Can't use this if the user has appropriated esi or edi.  */
18919   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18920     FAIL;
18921
18922   out = operands[0];
18923   if (!REG_P (out))
18924     out = gen_reg_rtx (SImode);
18925
18926   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18927   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18928   if (addr1 != XEXP (operands[1], 0))
18929     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18930   if (addr2 != XEXP (operands[2], 0))
18931     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18932
18933   count = operands[3];
18934   countreg = ix86_zero_extend_to_Pmode (count);
18935
18936   /* %%% Iff we are testing strict equality, we can use known alignment
18937      to good advantage.  This may be possible with combine, particularly
18938      once cc0 is dead.  */
18939   align = operands[4];
18940
18941   if (CONST_INT_P (count))
18942     {
18943       if (INTVAL (count) == 0)
18944         {
18945           emit_move_insn (operands[0], const0_rtx);
18946           DONE;
18947         }
18948       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18949                                      operands[1], operands[2]));
18950     }
18951   else
18952     {
18953       if (TARGET_64BIT)
18954         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18955       else
18956         emit_insn (gen_cmpsi_1 (countreg, countreg));
18957       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18958                                   operands[1], operands[2]));
18959     }
18960
18961   outlow = gen_lowpart (QImode, out);
18962   emit_insn (gen_cmpintqi (outlow));
18963   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18964
18965   if (operands[0] != out)
18966     emit_move_insn (operands[0], out);
18967
18968   DONE;
18969 })
18970
18971 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18972
18973 (define_expand "cmpintqi"
18974   [(set (match_dup 1)
18975         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18976    (set (match_dup 2)
18977         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18978    (parallel [(set (match_operand:QI 0 "register_operand" "")
18979                    (minus:QI (match_dup 1)
18980                              (match_dup 2)))
18981               (clobber (reg:CC FLAGS_REG))])]
18982   ""
18983   "operands[1] = gen_reg_rtx (QImode);
18984    operands[2] = gen_reg_rtx (QImode);")
18985
18986 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18987 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18988
18989 (define_expand "cmpstrnqi_nz_1"
18990   [(parallel [(set (reg:CC FLAGS_REG)
18991                    (compare:CC (match_operand 4 "memory_operand" "")
18992                                (match_operand 5 "memory_operand" "")))
18993               (use (match_operand 2 "register_operand" ""))
18994               (use (match_operand:SI 3 "immediate_operand" ""))
18995               (clobber (match_operand 0 "register_operand" ""))
18996               (clobber (match_operand 1 "register_operand" ""))
18997               (clobber (match_dup 2))])]
18998   ""
18999   "")
19000
19001 (define_insn "*cmpstrnqi_nz_1"
19002   [(set (reg:CC FLAGS_REG)
19003         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19004                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19005    (use (match_operand:SI 6 "register_operand" "2"))
19006    (use (match_operand:SI 3 "immediate_operand" "i"))
19007    (clobber (match_operand:SI 0 "register_operand" "=S"))
19008    (clobber (match_operand:SI 1 "register_operand" "=D"))
19009    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19010   "!TARGET_64BIT"
19011   "repz cmpsb"
19012   [(set_attr "type" "str")
19013    (set_attr "mode" "QI")
19014    (set_attr "prefix_rep" "1")])
19015
19016 (define_insn "*cmpstrnqi_nz_rex_1"
19017   [(set (reg:CC FLAGS_REG)
19018         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19019                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19020    (use (match_operand:DI 6 "register_operand" "2"))
19021    (use (match_operand:SI 3 "immediate_operand" "i"))
19022    (clobber (match_operand:DI 0 "register_operand" "=S"))
19023    (clobber (match_operand:DI 1 "register_operand" "=D"))
19024    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19025   "TARGET_64BIT"
19026   "repz cmpsb"
19027   [(set_attr "type" "str")
19028    (set_attr "mode" "QI")
19029    (set_attr "prefix_rep" "1")])
19030
19031 ;; The same, but the count is not known to not be zero.
19032
19033 (define_expand "cmpstrnqi_1"
19034   [(parallel [(set (reg:CC FLAGS_REG)
19035                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19036                                      (const_int 0))
19037                   (compare:CC (match_operand 4 "memory_operand" "")
19038                               (match_operand 5 "memory_operand" ""))
19039                   (const_int 0)))
19040               (use (match_operand:SI 3 "immediate_operand" ""))
19041               (use (reg:CC FLAGS_REG))
19042               (clobber (match_operand 0 "register_operand" ""))
19043               (clobber (match_operand 1 "register_operand" ""))
19044               (clobber (match_dup 2))])]
19045   ""
19046   "")
19047
19048 (define_insn "*cmpstrnqi_1"
19049   [(set (reg:CC FLAGS_REG)
19050         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19051                              (const_int 0))
19052           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19053                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19054           (const_int 0)))
19055    (use (match_operand:SI 3 "immediate_operand" "i"))
19056    (use (reg:CC FLAGS_REG))
19057    (clobber (match_operand:SI 0 "register_operand" "=S"))
19058    (clobber (match_operand:SI 1 "register_operand" "=D"))
19059    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19060   "!TARGET_64BIT"
19061   "repz cmpsb"
19062   [(set_attr "type" "str")
19063    (set_attr "mode" "QI")
19064    (set_attr "prefix_rep" "1")])
19065
19066 (define_insn "*cmpstrnqi_rex_1"
19067   [(set (reg:CC FLAGS_REG)
19068         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19069                              (const_int 0))
19070           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19071                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19072           (const_int 0)))
19073    (use (match_operand:SI 3 "immediate_operand" "i"))
19074    (use (reg:CC FLAGS_REG))
19075    (clobber (match_operand:DI 0 "register_operand" "=S"))
19076    (clobber (match_operand:DI 1 "register_operand" "=D"))
19077    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19078   "TARGET_64BIT"
19079   "repz cmpsb"
19080   [(set_attr "type" "str")
19081    (set_attr "mode" "QI")
19082    (set_attr "prefix_rep" "1")])
19083
19084 (define_expand "strlensi"
19085   [(set (match_operand:SI 0 "register_operand" "")
19086         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19087                     (match_operand:QI 2 "immediate_operand" "")
19088                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19089   ""
19090 {
19091  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19092    DONE;
19093  else
19094    FAIL;
19095 })
19096
19097 (define_expand "strlendi"
19098   [(set (match_operand:DI 0 "register_operand" "")
19099         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19100                     (match_operand:QI 2 "immediate_operand" "")
19101                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19102   ""
19103 {
19104  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19105    DONE;
19106  else
19107    FAIL;
19108 })
19109
19110 (define_expand "strlenqi_1"
19111   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19112               (clobber (match_operand 1 "register_operand" ""))
19113               (clobber (reg:CC FLAGS_REG))])]
19114   ""
19115   "")
19116
19117 (define_insn "*strlenqi_1"
19118   [(set (match_operand:SI 0 "register_operand" "=&c")
19119         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19120                     (match_operand:QI 2 "register_operand" "a")
19121                     (match_operand:SI 3 "immediate_operand" "i")
19122                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19123    (clobber (match_operand:SI 1 "register_operand" "=D"))
19124    (clobber (reg:CC FLAGS_REG))]
19125   "!TARGET_64BIT"
19126   "repnz scasb"
19127   [(set_attr "type" "str")
19128    (set_attr "mode" "QI")
19129    (set_attr "prefix_rep" "1")])
19130
19131 (define_insn "*strlenqi_rex_1"
19132   [(set (match_operand:DI 0 "register_operand" "=&c")
19133         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19134                     (match_operand:QI 2 "register_operand" "a")
19135                     (match_operand:DI 3 "immediate_operand" "i")
19136                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19137    (clobber (match_operand:DI 1 "register_operand" "=D"))
19138    (clobber (reg:CC FLAGS_REG))]
19139   "TARGET_64BIT"
19140   "repnz scasb"
19141   [(set_attr "type" "str")
19142    (set_attr "mode" "QI")
19143    (set_attr "prefix_rep" "1")])
19144
19145 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19146 ;; handled in combine, but it is not currently up to the task.
19147 ;; When used for their truth value, the cmpstrn* expanders generate
19148 ;; code like this:
19149 ;;
19150 ;;   repz cmpsb
19151 ;;   seta       %al
19152 ;;   setb       %dl
19153 ;;   cmpb       %al, %dl
19154 ;;   jcc        label
19155 ;;
19156 ;; The intermediate three instructions are unnecessary.
19157
19158 ;; This one handles cmpstrn*_nz_1...
19159 (define_peephole2
19160   [(parallel[
19161      (set (reg:CC FLAGS_REG)
19162           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19163                       (mem:BLK (match_operand 5 "register_operand" ""))))
19164      (use (match_operand 6 "register_operand" ""))
19165      (use (match_operand:SI 3 "immediate_operand" ""))
19166      (clobber (match_operand 0 "register_operand" ""))
19167      (clobber (match_operand 1 "register_operand" ""))
19168      (clobber (match_operand 2 "register_operand" ""))])
19169    (set (match_operand:QI 7 "register_operand" "")
19170         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19171    (set (match_operand:QI 8 "register_operand" "")
19172         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19173    (set (reg FLAGS_REG)
19174         (compare (match_dup 7) (match_dup 8)))
19175   ]
19176   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19177   [(parallel[
19178      (set (reg:CC FLAGS_REG)
19179           (compare:CC (mem:BLK (match_dup 4))
19180                       (mem:BLK (match_dup 5))))
19181      (use (match_dup 6))
19182      (use (match_dup 3))
19183      (clobber (match_dup 0))
19184      (clobber (match_dup 1))
19185      (clobber (match_dup 2))])]
19186   "")
19187
19188 ;; ...and this one handles cmpstrn*_1.
19189 (define_peephole2
19190   [(parallel[
19191      (set (reg:CC FLAGS_REG)
19192           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19193                                (const_int 0))
19194             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19195                         (mem:BLK (match_operand 5 "register_operand" "")))
19196             (const_int 0)))
19197      (use (match_operand:SI 3 "immediate_operand" ""))
19198      (use (reg:CC FLAGS_REG))
19199      (clobber (match_operand 0 "register_operand" ""))
19200      (clobber (match_operand 1 "register_operand" ""))
19201      (clobber (match_operand 2 "register_operand" ""))])
19202    (set (match_operand:QI 7 "register_operand" "")
19203         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19204    (set (match_operand:QI 8 "register_operand" "")
19205         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19206    (set (reg FLAGS_REG)
19207         (compare (match_dup 7) (match_dup 8)))
19208   ]
19209   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19210   [(parallel[
19211      (set (reg:CC FLAGS_REG)
19212           (if_then_else:CC (ne (match_dup 6)
19213                                (const_int 0))
19214             (compare:CC (mem:BLK (match_dup 4))
19215                         (mem:BLK (match_dup 5)))
19216             (const_int 0)))
19217      (use (match_dup 3))
19218      (use (reg:CC FLAGS_REG))
19219      (clobber (match_dup 0))
19220      (clobber (match_dup 1))
19221      (clobber (match_dup 2))])]
19222   "")
19223
19224
19225 \f
19226 ;; Conditional move instructions.
19227
19228 (define_expand "movdicc"
19229   [(set (match_operand:DI 0 "register_operand" "")
19230         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19231                          (match_operand:DI 2 "general_operand" "")
19232                          (match_operand:DI 3 "general_operand" "")))]
19233   "TARGET_64BIT"
19234   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19235
19236 (define_insn "x86_movdicc_0_m1_rex64"
19237   [(set (match_operand:DI 0 "register_operand" "=r")
19238         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19239           (const_int -1)
19240           (const_int 0)))
19241    (clobber (reg:CC FLAGS_REG))]
19242   "TARGET_64BIT"
19243   "sbb{q}\t%0, %0"
19244   ; Since we don't have the proper number of operands for an alu insn,
19245   ; fill in all the blanks.
19246   [(set_attr "type" "alu")
19247    (set_attr "pent_pair" "pu")
19248    (set_attr "memory" "none")
19249    (set_attr "imm_disp" "false")
19250    (set_attr "mode" "DI")
19251    (set_attr "length_immediate" "0")])
19252
19253 (define_insn "*x86_movdicc_0_m1_se"
19254   [(set (match_operand:DI 0 "register_operand" "=r")
19255         (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19256                          (const_int 1)
19257                          (const_int 0)))
19258    (clobber (reg:CC FLAGS_REG))]
19259   ""
19260   "sbb{q}\t%0, %0"
19261   [(set_attr "type" "alu")
19262    (set_attr "pent_pair" "pu")
19263    (set_attr "memory" "none")
19264    (set_attr "imm_disp" "false")
19265    (set_attr "mode" "DI")
19266    (set_attr "length_immediate" "0")])
19267
19268 (define_insn "*movdicc_c_rex64"
19269   [(set (match_operand:DI 0 "register_operand" "=r,r")
19270         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19271                                 [(reg FLAGS_REG) (const_int 0)])
19272                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19273                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19274   "TARGET_64BIT && TARGET_CMOVE
19275    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19276   "@
19277    cmov%O2%C1\t{%2, %0|%0, %2}
19278    cmov%O2%c1\t{%3, %0|%0, %3}"
19279   [(set_attr "type" "icmov")
19280    (set_attr "mode" "DI")])
19281
19282 (define_expand "movsicc"
19283   [(set (match_operand:SI 0 "register_operand" "")
19284         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19285                          (match_operand:SI 2 "general_operand" "")
19286                          (match_operand:SI 3 "general_operand" "")))]
19287   ""
19288   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19289
19290 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19291 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19292 ;; So just document what we're doing explicitly.
19293
19294 (define_insn "x86_movsicc_0_m1"
19295   [(set (match_operand:SI 0 "register_operand" "=r")
19296         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19297           (const_int -1)
19298           (const_int 0)))
19299    (clobber (reg:CC FLAGS_REG))]
19300   ""
19301   "sbb{l}\t%0, %0"
19302   ; Since we don't have the proper number of operands for an alu insn,
19303   ; fill in all the blanks.
19304   [(set_attr "type" "alu")
19305    (set_attr "pent_pair" "pu")
19306    (set_attr "memory" "none")
19307    (set_attr "imm_disp" "false")
19308    (set_attr "mode" "SI")
19309    (set_attr "length_immediate" "0")])
19310
19311 (define_insn "*x86_movsicc_0_m1_se"
19312   [(set (match_operand:SI 0 "register_operand" "=r")
19313         (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19314                          (const_int 1)
19315                          (const_int 0)))
19316    (clobber (reg:CC FLAGS_REG))]
19317   ""
19318   "sbb{l}\t%0, %0"
19319   [(set_attr "type" "alu")
19320    (set_attr "pent_pair" "pu")
19321    (set_attr "memory" "none")
19322    (set_attr "imm_disp" "false")
19323    (set_attr "mode" "SI")
19324    (set_attr "length_immediate" "0")])
19325
19326 (define_insn "*movsicc_noc"
19327   [(set (match_operand:SI 0 "register_operand" "=r,r")
19328         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19329                                 [(reg FLAGS_REG) (const_int 0)])
19330                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19331                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19332   "TARGET_CMOVE
19333    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19334   "@
19335    cmov%O2%C1\t{%2, %0|%0, %2}
19336    cmov%O2%c1\t{%3, %0|%0, %3}"
19337   [(set_attr "type" "icmov")
19338    (set_attr "mode" "SI")])
19339
19340 (define_expand "movhicc"
19341   [(set (match_operand:HI 0 "register_operand" "")
19342         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19343                          (match_operand:HI 2 "general_operand" "")
19344                          (match_operand:HI 3 "general_operand" "")))]
19345   "TARGET_HIMODE_MATH"
19346   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19347
19348 (define_insn "*movhicc_noc"
19349   [(set (match_operand:HI 0 "register_operand" "=r,r")
19350         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19351                                 [(reg FLAGS_REG) (const_int 0)])
19352                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19353                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19354   "TARGET_CMOVE
19355    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19356   "@
19357    cmov%O2%C1\t{%2, %0|%0, %2}
19358    cmov%O2%c1\t{%3, %0|%0, %3}"
19359   [(set_attr "type" "icmov")
19360    (set_attr "mode" "HI")])
19361
19362 (define_expand "movqicc"
19363   [(set (match_operand:QI 0 "register_operand" "")
19364         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19365                          (match_operand:QI 2 "general_operand" "")
19366                          (match_operand:QI 3 "general_operand" "")))]
19367   "TARGET_QIMODE_MATH"
19368   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19369
19370 (define_insn_and_split "*movqicc_noc"
19371   [(set (match_operand:QI 0 "register_operand" "=r,r")
19372         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19373                                 [(match_operand 4 "flags_reg_operand" "")
19374                                  (const_int 0)])
19375                       (match_operand:QI 2 "register_operand" "r,0")
19376                       (match_operand:QI 3 "register_operand" "0,r")))]
19377   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19378   "#"
19379   "&& reload_completed"
19380   [(set (match_dup 0)
19381         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19382                       (match_dup 2)
19383                       (match_dup 3)))]
19384   "operands[0] = gen_lowpart (SImode, operands[0]);
19385    operands[2] = gen_lowpart (SImode, operands[2]);
19386    operands[3] = gen_lowpart (SImode, operands[3]);"
19387   [(set_attr "type" "icmov")
19388    (set_attr "mode" "SI")])
19389
19390 (define_expand "mov<mode>cc"
19391   [(set (match_operand:X87MODEF 0 "register_operand" "")
19392         (if_then_else:X87MODEF
19393           (match_operand 1 "comparison_operator" "")
19394           (match_operand:X87MODEF 2 "register_operand" "")
19395           (match_operand:X87MODEF 3 "register_operand" "")))]
19396   "(TARGET_80387 && TARGET_CMOVE)
19397    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19398   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19399
19400 (define_insn "*movsfcc_1_387"
19401   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19402         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19403                                 [(reg FLAGS_REG) (const_int 0)])
19404                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19405                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19406   "TARGET_80387 && TARGET_CMOVE
19407    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19408   "@
19409    fcmov%F1\t{%2, %0|%0, %2}
19410    fcmov%f1\t{%3, %0|%0, %3}
19411    cmov%O2%C1\t{%2, %0|%0, %2}
19412    cmov%O2%c1\t{%3, %0|%0, %3}"
19413   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19414    (set_attr "mode" "SF,SF,SI,SI")])
19415
19416 (define_insn "*movdfcc_1"
19417   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19418         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19419                                 [(reg FLAGS_REG) (const_int 0)])
19420                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19421                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19422   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19423    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19424   "@
19425    fcmov%F1\t{%2, %0|%0, %2}
19426    fcmov%f1\t{%3, %0|%0, %3}
19427    #
19428    #"
19429   [(set_attr "type" "fcmov,fcmov,multi,multi")
19430    (set_attr "mode" "DF")])
19431
19432 (define_insn "*movdfcc_1_rex64"
19433   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19434         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19435                                 [(reg FLAGS_REG) (const_int 0)])
19436                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19437                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19438   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19439    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19440   "@
19441    fcmov%F1\t{%2, %0|%0, %2}
19442    fcmov%f1\t{%3, %0|%0, %3}
19443    cmov%O2%C1\t{%2, %0|%0, %2}
19444    cmov%O2%c1\t{%3, %0|%0, %3}"
19445   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19446    (set_attr "mode" "DF")])
19447
19448 (define_split
19449   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19450         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19451                                 [(match_operand 4 "flags_reg_operand" "")
19452                                  (const_int 0)])
19453                       (match_operand:DF 2 "nonimmediate_operand" "")
19454                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19455   "!TARGET_64BIT && reload_completed"
19456   [(set (match_dup 2)
19457         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19458                       (match_dup 5)
19459                       (match_dup 6)))
19460    (set (match_dup 3)
19461         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19462                       (match_dup 7)
19463                       (match_dup 8)))]
19464   "split_di (&operands[2], 2, &operands[5], &operands[7]);
19465    split_di (&operands[0], 1, &operands[2], &operands[3]);")
19466
19467 (define_insn "*movxfcc_1"
19468   [(set (match_operand:XF 0 "register_operand" "=f,f")
19469         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19470                                 [(reg FLAGS_REG) (const_int 0)])
19471                       (match_operand:XF 2 "register_operand" "f,0")
19472                       (match_operand:XF 3 "register_operand" "0,f")))]
19473   "TARGET_80387 && TARGET_CMOVE"
19474   "@
19475    fcmov%F1\t{%2, %0|%0, %2}
19476    fcmov%f1\t{%3, %0|%0, %3}"
19477   [(set_attr "type" "fcmov")
19478    (set_attr "mode" "XF")])
19479
19480 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19481 ;; the scalar versions to have only XMM registers as operands.
19482
19483 ;; SSE5 conditional move
19484 (define_insn "*sse5_pcmov_<mode>"
19485   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19486         (if_then_else:MODEF
19487           (match_operand:MODEF 1 "register_operand" "x,0")
19488           (match_operand:MODEF 2 "register_operand" "0,x")
19489           (match_operand:MODEF 3 "register_operand" "x,x")))]
19490   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19491   "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19492   [(set_attr "type" "sse4arg")])
19493
19494 ;; These versions of the min/max patterns are intentionally ignorant of
19495 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19496 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19497 ;; are undefined in this condition, we're certain this is correct.
19498
19499 (define_insn "<code><mode>3"
19500   [(set (match_operand:MODEF 0 "register_operand" "=x")
19501         (smaxmin:MODEF
19502           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19503           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19504   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19505   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19506   [(set_attr "type" "sseadd")
19507    (set_attr "mode" "<MODE>")])
19508
19509 ;; These versions of the min/max patterns implement exactly the operations
19510 ;;   min = (op1 < op2 ? op1 : op2)
19511 ;;   max = (!(op1 < op2) ? op1 : op2)
19512 ;; Their operands are not commutative, and thus they may be used in the
19513 ;; presence of -0.0 and NaN.
19514
19515 (define_insn "*ieee_smin<mode>3"
19516   [(set (match_operand:MODEF 0 "register_operand" "=x")
19517         (unspec:MODEF
19518           [(match_operand:MODEF 1 "register_operand" "0")
19519            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19520          UNSPEC_IEEE_MIN))]
19521   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19522   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19523   [(set_attr "type" "sseadd")
19524    (set_attr "mode" "<MODE>")])
19525
19526 (define_insn "*ieee_smax<mode>3"
19527   [(set (match_operand:MODEF 0 "register_operand" "=x")
19528         (unspec:MODEF
19529           [(match_operand:MODEF 1 "register_operand" "0")
19530            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19531          UNSPEC_IEEE_MAX))]
19532   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19533   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19534   [(set_attr "type" "sseadd")
19535    (set_attr "mode" "<MODE>")])
19536
19537 ;; Make two stack loads independent:
19538 ;;   fld aa              fld aa
19539 ;;   fld %st(0)     ->   fld bb
19540 ;;   fmul bb             fmul %st(1), %st
19541 ;;
19542 ;; Actually we only match the last two instructions for simplicity.
19543 (define_peephole2
19544   [(set (match_operand 0 "fp_register_operand" "")
19545         (match_operand 1 "fp_register_operand" ""))
19546    (set (match_dup 0)
19547         (match_operator 2 "binary_fp_operator"
19548            [(match_dup 0)
19549             (match_operand 3 "memory_operand" "")]))]
19550   "REGNO (operands[0]) != REGNO (operands[1])"
19551   [(set (match_dup 0) (match_dup 3))
19552    (set (match_dup 0) (match_dup 4))]
19553
19554   ;; The % modifier is not operational anymore in peephole2's, so we have to
19555   ;; swap the operands manually in the case of addition and multiplication.
19556   "if (COMMUTATIVE_ARITH_P (operands[2]))
19557      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19558                                  operands[0], operands[1]);
19559    else
19560      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19561                                  operands[1], operands[0]);")
19562
19563 ;; Conditional addition patterns
19564 (define_expand "addqicc"
19565   [(match_operand:QI 0 "register_operand" "")
19566    (match_operand 1 "comparison_operator" "")
19567    (match_operand:QI 2 "register_operand" "")
19568    (match_operand:QI 3 "const_int_operand" "")]
19569   ""
19570   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19571
19572 (define_expand "addhicc"
19573   [(match_operand:HI 0 "register_operand" "")
19574    (match_operand 1 "comparison_operator" "")
19575    (match_operand:HI 2 "register_operand" "")
19576    (match_operand:HI 3 "const_int_operand" "")]
19577   ""
19578   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19579
19580 (define_expand "addsicc"
19581   [(match_operand:SI 0 "register_operand" "")
19582    (match_operand 1 "comparison_operator" "")
19583    (match_operand:SI 2 "register_operand" "")
19584    (match_operand:SI 3 "const_int_operand" "")]
19585   ""
19586   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19587
19588 (define_expand "adddicc"
19589   [(match_operand:DI 0 "register_operand" "")
19590    (match_operand 1 "comparison_operator" "")
19591    (match_operand:DI 2 "register_operand" "")
19592    (match_operand:DI 3 "const_int_operand" "")]
19593   "TARGET_64BIT"
19594   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19595
19596 \f
19597 ;; Misc patterns (?)
19598
19599 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19600 ;; Otherwise there will be nothing to keep
19601 ;;
19602 ;; [(set (reg ebp) (reg esp))]
19603 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19604 ;;  (clobber (eflags)]
19605 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19606 ;;
19607 ;; in proper program order.
19608 (define_insn "pro_epilogue_adjust_stack_1"
19609   [(set (match_operand:SI 0 "register_operand" "=r,r")
19610         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19611                  (match_operand:SI 2 "immediate_operand" "i,i")))
19612    (clobber (reg:CC FLAGS_REG))
19613    (clobber (mem:BLK (scratch)))]
19614   "!TARGET_64BIT"
19615 {
19616   switch (get_attr_type (insn))
19617     {
19618     case TYPE_IMOV:
19619       return "mov{l}\t{%1, %0|%0, %1}";
19620
19621     case TYPE_ALU:
19622       if (CONST_INT_P (operands[2])
19623           && (INTVAL (operands[2]) == 128
19624               || (INTVAL (operands[2]) < 0
19625                   && INTVAL (operands[2]) != -128)))
19626         {
19627           operands[2] = GEN_INT (-INTVAL (operands[2]));
19628           return "sub{l}\t{%2, %0|%0, %2}";
19629         }
19630       return "add{l}\t{%2, %0|%0, %2}";
19631
19632     case TYPE_LEA:
19633       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19634       return "lea{l}\t{%a2, %0|%0, %a2}";
19635
19636     default:
19637       gcc_unreachable ();
19638     }
19639 }
19640   [(set (attr "type")
19641         (cond [(eq_attr "alternative" "0")
19642                  (const_string "alu")
19643                (match_operand:SI 2 "const0_operand" "")
19644                  (const_string "imov")
19645               ]
19646               (const_string "lea")))
19647    (set_attr "mode" "SI")])
19648
19649 (define_insn "pro_epilogue_adjust_stack_rex64"
19650   [(set (match_operand:DI 0 "register_operand" "=r,r")
19651         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19652                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19653    (clobber (reg:CC FLAGS_REG))
19654    (clobber (mem:BLK (scratch)))]
19655   "TARGET_64BIT"
19656 {
19657   switch (get_attr_type (insn))
19658     {
19659     case TYPE_IMOV:
19660       return "mov{q}\t{%1, %0|%0, %1}";
19661
19662     case TYPE_ALU:
19663       if (CONST_INT_P (operands[2])
19664           /* Avoid overflows.  */
19665           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19666           && (INTVAL (operands[2]) == 128
19667               || (INTVAL (operands[2]) < 0
19668                   && INTVAL (operands[2]) != -128)))
19669         {
19670           operands[2] = GEN_INT (-INTVAL (operands[2]));
19671           return "sub{q}\t{%2, %0|%0, %2}";
19672         }
19673       return "add{q}\t{%2, %0|%0, %2}";
19674
19675     case TYPE_LEA:
19676       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19677       return "lea{q}\t{%a2, %0|%0, %a2}";
19678
19679     default:
19680       gcc_unreachable ();
19681     }
19682 }
19683   [(set (attr "type")
19684         (cond [(eq_attr "alternative" "0")
19685                  (const_string "alu")
19686                (match_operand:DI 2 "const0_operand" "")
19687                  (const_string "imov")
19688               ]
19689               (const_string "lea")))
19690    (set_attr "mode" "DI")])
19691
19692 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19693   [(set (match_operand:DI 0 "register_operand" "=r,r")
19694         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19695                  (match_operand:DI 3 "immediate_operand" "i,i")))
19696    (use (match_operand:DI 2 "register_operand" "r,r"))
19697    (clobber (reg:CC FLAGS_REG))
19698    (clobber (mem:BLK (scratch)))]
19699   "TARGET_64BIT"
19700 {
19701   switch (get_attr_type (insn))
19702     {
19703     case TYPE_ALU:
19704       return "add{q}\t{%2, %0|%0, %2}";
19705
19706     case TYPE_LEA:
19707       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19708       return "lea{q}\t{%a2, %0|%0, %a2}";
19709
19710     default:
19711       gcc_unreachable ();
19712     }
19713 }
19714   [(set_attr "type" "alu,lea")
19715    (set_attr "mode" "DI")])
19716
19717 (define_insn "allocate_stack_worker_32"
19718   [(set (match_operand:SI 0 "register_operand" "+a")
19719         (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19720    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19721    (clobber (reg:CC FLAGS_REG))]
19722   "!TARGET_64BIT && TARGET_STACK_PROBE"
19723   "call\t___chkstk"
19724   [(set_attr "type" "multi")
19725    (set_attr "length" "5")])
19726
19727 (define_insn "allocate_stack_worker_64"
19728   [(set (match_operand:DI 0 "register_operand" "=a")
19729         (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19730    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19731    (clobber (reg:DI R10_REG))
19732    (clobber (reg:DI R11_REG))
19733    (clobber (reg:CC FLAGS_REG))]
19734   "TARGET_64BIT && TARGET_STACK_PROBE"
19735   "call\t___chkstk"
19736   [(set_attr "type" "multi")
19737    (set_attr "length" "5")])
19738
19739 (define_expand "allocate_stack"
19740   [(match_operand 0 "register_operand" "")
19741    (match_operand 1 "general_operand" "")]
19742   "TARGET_STACK_PROBE"
19743 {
19744   rtx x;
19745
19746 #ifndef CHECK_STACK_LIMIT
19747 #define CHECK_STACK_LIMIT 0
19748 #endif
19749
19750   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19751       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19752     {
19753       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19754                                stack_pointer_rtx, 0, OPTAB_DIRECT);
19755       if (x != stack_pointer_rtx)
19756         emit_move_insn (stack_pointer_rtx, x);
19757     }
19758   else
19759     {
19760       x = copy_to_mode_reg (Pmode, operands[1]);
19761       if (TARGET_64BIT)
19762         x = gen_allocate_stack_worker_64 (x);
19763       else
19764         x = gen_allocate_stack_worker_32 (x);
19765       emit_insn (x);
19766     }
19767
19768   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19769   DONE;
19770 })
19771
19772 (define_expand "builtin_setjmp_receiver"
19773   [(label_ref (match_operand 0 "" ""))]
19774   "!TARGET_64BIT && flag_pic"
19775 {
19776   if (TARGET_MACHO)
19777     {
19778       rtx xops[3];
19779       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19780       rtx label_rtx = gen_label_rtx ();
19781       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19782       xops[0] = xops[1] = picreg;
19783       xops[2] = gen_rtx_CONST (SImode,
19784                   gen_rtx_MINUS (SImode,
19785                     gen_rtx_LABEL_REF (SImode, label_rtx),
19786                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19787       ix86_expand_binary_operator (MINUS, SImode, xops);
19788     }
19789   else
19790     emit_insn (gen_set_got (pic_offset_table_rtx));
19791   DONE;
19792 })
19793 \f
19794 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19795
19796 (define_split
19797   [(set (match_operand 0 "register_operand" "")
19798         (match_operator 3 "promotable_binary_operator"
19799            [(match_operand 1 "register_operand" "")
19800             (match_operand 2 "aligned_operand" "")]))
19801    (clobber (reg:CC FLAGS_REG))]
19802   "! TARGET_PARTIAL_REG_STALL && reload_completed
19803    && ((GET_MODE (operands[0]) == HImode
19804         && ((!optimize_size && !TARGET_FAST_PREFIX)
19805             /* ??? next two lines just !satisfies_constraint_K (...) */
19806             || !CONST_INT_P (operands[2])
19807             || satisfies_constraint_K (operands[2])))
19808        || (GET_MODE (operands[0]) == QImode
19809            && (TARGET_PROMOTE_QImode || optimize_size)))"
19810   [(parallel [(set (match_dup 0)
19811                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19812               (clobber (reg:CC FLAGS_REG))])]
19813   "operands[0] = gen_lowpart (SImode, operands[0]);
19814    operands[1] = gen_lowpart (SImode, operands[1]);
19815    if (GET_CODE (operands[3]) != ASHIFT)
19816      operands[2] = gen_lowpart (SImode, operands[2]);
19817    PUT_MODE (operands[3], SImode);")
19818
19819 ; Promote the QImode tests, as i386 has encoding of the AND
19820 ; instruction with 32-bit sign-extended immediate and thus the
19821 ; instruction size is unchanged, except in the %eax case for
19822 ; which it is increased by one byte, hence the ! optimize_size.
19823 (define_split
19824   [(set (match_operand 0 "flags_reg_operand" "")
19825         (match_operator 2 "compare_operator"
19826           [(and (match_operand 3 "aligned_operand" "")
19827                 (match_operand 4 "const_int_operand" ""))
19828            (const_int 0)]))
19829    (set (match_operand 1 "register_operand" "")
19830         (and (match_dup 3) (match_dup 4)))]
19831   "! TARGET_PARTIAL_REG_STALL && reload_completed
19832    && ! optimize_size
19833    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19834        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19835    /* Ensure that the operand will remain sign-extended immediate.  */
19836    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19837   [(parallel [(set (match_dup 0)
19838                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19839                                     (const_int 0)]))
19840               (set (match_dup 1)
19841                    (and:SI (match_dup 3) (match_dup 4)))])]
19842 {
19843   operands[4]
19844     = gen_int_mode (INTVAL (operands[4])
19845                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19846   operands[1] = gen_lowpart (SImode, operands[1]);
19847   operands[3] = gen_lowpart (SImode, operands[3]);
19848 })
19849
19850 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19851 ; the TEST instruction with 32-bit sign-extended immediate and thus
19852 ; the instruction size would at least double, which is not what we
19853 ; want even with ! optimize_size.
19854 (define_split
19855   [(set (match_operand 0 "flags_reg_operand" "")
19856         (match_operator 1 "compare_operator"
19857           [(and (match_operand:HI 2 "aligned_operand" "")
19858                 (match_operand:HI 3 "const_int_operand" ""))
19859            (const_int 0)]))]
19860   "! TARGET_PARTIAL_REG_STALL && reload_completed
19861    && ! TARGET_FAST_PREFIX
19862    && ! optimize_size
19863    /* Ensure that the operand will remain sign-extended immediate.  */
19864    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19865   [(set (match_dup 0)
19866         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19867                          (const_int 0)]))]
19868 {
19869   operands[3]
19870     = gen_int_mode (INTVAL (operands[3])
19871                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19872   operands[2] = gen_lowpart (SImode, operands[2]);
19873 })
19874
19875 (define_split
19876   [(set (match_operand 0 "register_operand" "")
19877         (neg (match_operand 1 "register_operand" "")))
19878    (clobber (reg:CC FLAGS_REG))]
19879   "! TARGET_PARTIAL_REG_STALL && reload_completed
19880    && (GET_MODE (operands[0]) == HImode
19881        || (GET_MODE (operands[0]) == QImode
19882            && (TARGET_PROMOTE_QImode || optimize_size)))"
19883   [(parallel [(set (match_dup 0)
19884                    (neg:SI (match_dup 1)))
19885               (clobber (reg:CC FLAGS_REG))])]
19886   "operands[0] = gen_lowpart (SImode, operands[0]);
19887    operands[1] = gen_lowpart (SImode, operands[1]);")
19888
19889 (define_split
19890   [(set (match_operand 0 "register_operand" "")
19891         (not (match_operand 1 "register_operand" "")))]
19892   "! TARGET_PARTIAL_REG_STALL && reload_completed
19893    && (GET_MODE (operands[0]) == HImode
19894        || (GET_MODE (operands[0]) == QImode
19895            && (TARGET_PROMOTE_QImode || optimize_size)))"
19896   [(set (match_dup 0)
19897         (not:SI (match_dup 1)))]
19898   "operands[0] = gen_lowpart (SImode, operands[0]);
19899    operands[1] = gen_lowpart (SImode, operands[1]);")
19900
19901 (define_split
19902   [(set (match_operand 0 "register_operand" "")
19903         (if_then_else (match_operator 1 "comparison_operator"
19904                                 [(reg FLAGS_REG) (const_int 0)])
19905                       (match_operand 2 "register_operand" "")
19906                       (match_operand 3 "register_operand" "")))]
19907   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19908    && (GET_MODE (operands[0]) == HImode
19909        || (GET_MODE (operands[0]) == QImode
19910            && (TARGET_PROMOTE_QImode || optimize_size)))"
19911   [(set (match_dup 0)
19912         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19913   "operands[0] = gen_lowpart (SImode, operands[0]);
19914    operands[2] = gen_lowpart (SImode, operands[2]);
19915    operands[3] = gen_lowpart (SImode, operands[3]);")
19916
19917 \f
19918 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19919 ;; transform a complex memory operation into two memory to register operations.
19920
19921 ;; Don't push memory operands
19922 (define_peephole2
19923   [(set (match_operand:SI 0 "push_operand" "")
19924         (match_operand:SI 1 "memory_operand" ""))
19925    (match_scratch:SI 2 "r")]
19926   "!optimize_size && !TARGET_PUSH_MEMORY
19927    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19928   [(set (match_dup 2) (match_dup 1))
19929    (set (match_dup 0) (match_dup 2))]
19930   "")
19931
19932 (define_peephole2
19933   [(set (match_operand:DI 0 "push_operand" "")
19934         (match_operand:DI 1 "memory_operand" ""))
19935    (match_scratch:DI 2 "r")]
19936   "!optimize_size && !TARGET_PUSH_MEMORY
19937    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19938   [(set (match_dup 2) (match_dup 1))
19939    (set (match_dup 0) (match_dup 2))]
19940   "")
19941
19942 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19943 ;; SImode pushes.
19944 (define_peephole2
19945   [(set (match_operand:SF 0 "push_operand" "")
19946         (match_operand:SF 1 "memory_operand" ""))
19947    (match_scratch:SF 2 "r")]
19948   "!optimize_size && !TARGET_PUSH_MEMORY
19949    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19950   [(set (match_dup 2) (match_dup 1))
19951    (set (match_dup 0) (match_dup 2))]
19952   "")
19953
19954 (define_peephole2
19955   [(set (match_operand:HI 0 "push_operand" "")
19956         (match_operand:HI 1 "memory_operand" ""))
19957    (match_scratch:HI 2 "r")]
19958   "!optimize_size && !TARGET_PUSH_MEMORY
19959    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19960   [(set (match_dup 2) (match_dup 1))
19961    (set (match_dup 0) (match_dup 2))]
19962   "")
19963
19964 (define_peephole2
19965   [(set (match_operand:QI 0 "push_operand" "")
19966         (match_operand:QI 1 "memory_operand" ""))
19967    (match_scratch:QI 2 "q")]
19968   "!optimize_size && !TARGET_PUSH_MEMORY
19969    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19970   [(set (match_dup 2) (match_dup 1))
19971    (set (match_dup 0) (match_dup 2))]
19972   "")
19973
19974 ;; Don't move an immediate directly to memory when the instruction
19975 ;; gets too big.
19976 (define_peephole2
19977   [(match_scratch:SI 1 "r")
19978    (set (match_operand:SI 0 "memory_operand" "")
19979         (const_int 0))]
19980   "! optimize_size
19981    && ! TARGET_USE_MOV0
19982    && TARGET_SPLIT_LONG_MOVES
19983    && get_attr_length (insn) >= ix86_cost->large_insn
19984    && peep2_regno_dead_p (0, FLAGS_REG)"
19985   [(parallel [(set (match_dup 1) (const_int 0))
19986               (clobber (reg:CC FLAGS_REG))])
19987    (set (match_dup 0) (match_dup 1))]
19988   "")
19989
19990 (define_peephole2
19991   [(match_scratch:HI 1 "r")
19992    (set (match_operand:HI 0 "memory_operand" "")
19993         (const_int 0))]
19994   "! optimize_size
19995    && ! TARGET_USE_MOV0
19996    && TARGET_SPLIT_LONG_MOVES
19997    && get_attr_length (insn) >= ix86_cost->large_insn
19998    && peep2_regno_dead_p (0, FLAGS_REG)"
19999   [(parallel [(set (match_dup 2) (const_int 0))
20000               (clobber (reg:CC FLAGS_REG))])
20001    (set (match_dup 0) (match_dup 1))]
20002   "operands[2] = gen_lowpart (SImode, operands[1]);")
20003
20004 (define_peephole2
20005   [(match_scratch:QI 1 "q")
20006    (set (match_operand:QI 0 "memory_operand" "")
20007         (const_int 0))]
20008   "! optimize_size
20009    && ! TARGET_USE_MOV0
20010    && TARGET_SPLIT_LONG_MOVES
20011    && get_attr_length (insn) >= ix86_cost->large_insn
20012    && peep2_regno_dead_p (0, FLAGS_REG)"
20013   [(parallel [(set (match_dup 2) (const_int 0))
20014               (clobber (reg:CC FLAGS_REG))])
20015    (set (match_dup 0) (match_dup 1))]
20016   "operands[2] = gen_lowpart (SImode, operands[1]);")
20017
20018 (define_peephole2
20019   [(match_scratch:SI 2 "r")
20020    (set (match_operand:SI 0 "memory_operand" "")
20021         (match_operand:SI 1 "immediate_operand" ""))]
20022   "! optimize_size
20023    && TARGET_SPLIT_LONG_MOVES
20024    && get_attr_length (insn) >= ix86_cost->large_insn"
20025   [(set (match_dup 2) (match_dup 1))
20026    (set (match_dup 0) (match_dup 2))]
20027   "")
20028
20029 (define_peephole2
20030   [(match_scratch:HI 2 "r")
20031    (set (match_operand:HI 0 "memory_operand" "")
20032         (match_operand:HI 1 "immediate_operand" ""))]
20033   "! optimize_size
20034    && TARGET_SPLIT_LONG_MOVES
20035    && get_attr_length (insn) >= ix86_cost->large_insn"
20036   [(set (match_dup 2) (match_dup 1))
20037    (set (match_dup 0) (match_dup 2))]
20038   "")
20039
20040 (define_peephole2
20041   [(match_scratch:QI 2 "q")
20042    (set (match_operand:QI 0 "memory_operand" "")
20043         (match_operand:QI 1 "immediate_operand" ""))]
20044   "! optimize_size
20045    && TARGET_SPLIT_LONG_MOVES
20046    && get_attr_length (insn) >= ix86_cost->large_insn"
20047   [(set (match_dup 2) (match_dup 1))
20048    (set (match_dup 0) (match_dup 2))]
20049   "")
20050
20051 ;; Don't compare memory with zero, load and use a test instead.
20052 (define_peephole2
20053   [(set (match_operand 0 "flags_reg_operand" "")
20054         (match_operator 1 "compare_operator"
20055           [(match_operand:SI 2 "memory_operand" "")
20056            (const_int 0)]))
20057    (match_scratch:SI 3 "r")]
20058   " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20059   [(set (match_dup 3) (match_dup 2))
20060    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20061   "")
20062
20063 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20064 ;; Don't split NOTs with a displacement operand, because resulting XOR
20065 ;; will not be pairable anyway.
20066 ;;
20067 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20068 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20069 ;; so this split helps here as well.
20070 ;;
20071 ;; Note: Can't do this as a regular split because we can't get proper
20072 ;; lifetime information then.
20073
20074 (define_peephole2
20075   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20076         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20077   "!optimize_size
20078    && ((TARGET_NOT_UNPAIRABLE
20079         && (!MEM_P (operands[0])
20080             || !memory_displacement_operand (operands[0], SImode)))
20081        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20082    && peep2_regno_dead_p (0, FLAGS_REG)"
20083   [(parallel [(set (match_dup 0)
20084                    (xor:SI (match_dup 1) (const_int -1)))
20085               (clobber (reg:CC FLAGS_REG))])]
20086   "")
20087
20088 (define_peephole2
20089   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20090         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20091   "!optimize_size
20092    && ((TARGET_NOT_UNPAIRABLE
20093         && (!MEM_P (operands[0])
20094             || !memory_displacement_operand (operands[0], HImode)))
20095        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20096    && peep2_regno_dead_p (0, FLAGS_REG)"
20097   [(parallel [(set (match_dup 0)
20098                    (xor:HI (match_dup 1) (const_int -1)))
20099               (clobber (reg:CC FLAGS_REG))])]
20100   "")
20101
20102 (define_peephole2
20103   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20104         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20105   "!optimize_size
20106    && ((TARGET_NOT_UNPAIRABLE
20107         && (!MEM_P (operands[0])
20108             || !memory_displacement_operand (operands[0], QImode)))
20109        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20110    && peep2_regno_dead_p (0, FLAGS_REG)"
20111   [(parallel [(set (match_dup 0)
20112                    (xor:QI (match_dup 1) (const_int -1)))
20113               (clobber (reg:CC FLAGS_REG))])]
20114   "")
20115
20116 ;; Non pairable "test imm, reg" instructions can be translated to
20117 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20118 ;; byte opcode instead of two, have a short form for byte operands),
20119 ;; so do it for other CPUs as well.  Given that the value was dead,
20120 ;; this should not create any new dependencies.  Pass on the sub-word
20121 ;; versions if we're concerned about partial register stalls.
20122
20123 (define_peephole2
20124   [(set (match_operand 0 "flags_reg_operand" "")
20125         (match_operator 1 "compare_operator"
20126           [(and:SI (match_operand:SI 2 "register_operand" "")
20127                    (match_operand:SI 3 "immediate_operand" ""))
20128            (const_int 0)]))]
20129   "ix86_match_ccmode (insn, CCNOmode)
20130    && (true_regnum (operands[2]) != AX_REG
20131        || satisfies_constraint_K (operands[3]))
20132    && peep2_reg_dead_p (1, operands[2])"
20133   [(parallel
20134      [(set (match_dup 0)
20135            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20136                             (const_int 0)]))
20137       (set (match_dup 2)
20138            (and:SI (match_dup 2) (match_dup 3)))])]
20139   "")
20140
20141 ;; We don't need to handle HImode case, because it will be promoted to SImode
20142 ;; on ! TARGET_PARTIAL_REG_STALL
20143
20144 (define_peephole2
20145   [(set (match_operand 0 "flags_reg_operand" "")
20146         (match_operator 1 "compare_operator"
20147           [(and:QI (match_operand:QI 2 "register_operand" "")
20148                    (match_operand:QI 3 "immediate_operand" ""))
20149            (const_int 0)]))]
20150   "! TARGET_PARTIAL_REG_STALL
20151    && ix86_match_ccmode (insn, CCNOmode)
20152    && true_regnum (operands[2]) != AX_REG
20153    && peep2_reg_dead_p (1, operands[2])"
20154   [(parallel
20155      [(set (match_dup 0)
20156            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20157                             (const_int 0)]))
20158       (set (match_dup 2)
20159            (and:QI (match_dup 2) (match_dup 3)))])]
20160   "")
20161
20162 (define_peephole2
20163   [(set (match_operand 0 "flags_reg_operand" "")
20164         (match_operator 1 "compare_operator"
20165           [(and:SI
20166              (zero_extract:SI
20167                (match_operand 2 "ext_register_operand" "")
20168                (const_int 8)
20169                (const_int 8))
20170              (match_operand 3 "const_int_operand" ""))
20171            (const_int 0)]))]
20172   "! TARGET_PARTIAL_REG_STALL
20173    && ix86_match_ccmode (insn, CCNOmode)
20174    && true_regnum (operands[2]) != AX_REG
20175    && peep2_reg_dead_p (1, operands[2])"
20176   [(parallel [(set (match_dup 0)
20177                    (match_op_dup 1
20178                      [(and:SI
20179                         (zero_extract:SI
20180                           (match_dup 2)
20181                           (const_int 8)
20182                           (const_int 8))
20183                         (match_dup 3))
20184                       (const_int 0)]))
20185               (set (zero_extract:SI (match_dup 2)
20186                                     (const_int 8)
20187                                     (const_int 8))
20188                    (and:SI
20189                      (zero_extract:SI
20190                        (match_dup 2)
20191                        (const_int 8)
20192                        (const_int 8))
20193                      (match_dup 3)))])]
20194   "")
20195
20196 ;; Don't do logical operations with memory inputs.
20197 (define_peephole2
20198   [(match_scratch:SI 2 "r")
20199    (parallel [(set (match_operand:SI 0 "register_operand" "")
20200                    (match_operator:SI 3 "arith_or_logical_operator"
20201                      [(match_dup 0)
20202                       (match_operand:SI 1 "memory_operand" "")]))
20203               (clobber (reg:CC FLAGS_REG))])]
20204   "! optimize_size && ! TARGET_READ_MODIFY"
20205   [(set (match_dup 2) (match_dup 1))
20206    (parallel [(set (match_dup 0)
20207                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20208               (clobber (reg:CC FLAGS_REG))])]
20209   "")
20210
20211 (define_peephole2
20212   [(match_scratch:SI 2 "r")
20213    (parallel [(set (match_operand:SI 0 "register_operand" "")
20214                    (match_operator:SI 3 "arith_or_logical_operator"
20215                      [(match_operand:SI 1 "memory_operand" "")
20216                       (match_dup 0)]))
20217               (clobber (reg:CC FLAGS_REG))])]
20218   "! optimize_size && ! TARGET_READ_MODIFY"
20219   [(set (match_dup 2) (match_dup 1))
20220    (parallel [(set (match_dup 0)
20221                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20222               (clobber (reg:CC FLAGS_REG))])]
20223   "")
20224
20225 ; Don't do logical operations with memory outputs
20226 ;
20227 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20228 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20229 ; the same decoder scheduling characteristics as the original.
20230
20231 (define_peephole2
20232   [(match_scratch:SI 2 "r")
20233    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20234                    (match_operator:SI 3 "arith_or_logical_operator"
20235                      [(match_dup 0)
20236                       (match_operand:SI 1 "nonmemory_operand" "")]))
20237               (clobber (reg:CC FLAGS_REG))])]
20238   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20239   [(set (match_dup 2) (match_dup 0))
20240    (parallel [(set (match_dup 2)
20241                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20242               (clobber (reg:CC FLAGS_REG))])
20243    (set (match_dup 0) (match_dup 2))]
20244   "")
20245
20246 (define_peephole2
20247   [(match_scratch:SI 2 "r")
20248    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20249                    (match_operator:SI 3 "arith_or_logical_operator"
20250                      [(match_operand:SI 1 "nonmemory_operand" "")
20251                       (match_dup 0)]))
20252               (clobber (reg:CC FLAGS_REG))])]
20253   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20254   [(set (match_dup 2) (match_dup 0))
20255    (parallel [(set (match_dup 2)
20256                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20257               (clobber (reg:CC FLAGS_REG))])
20258    (set (match_dup 0) (match_dup 2))]
20259   "")
20260
20261 ;; Attempt to always use XOR for zeroing registers.
20262 (define_peephole2
20263   [(set (match_operand 0 "register_operand" "")
20264         (match_operand 1 "const0_operand" ""))]
20265   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20266    && (! TARGET_USE_MOV0 || optimize_size)
20267    && GENERAL_REG_P (operands[0])
20268    && peep2_regno_dead_p (0, FLAGS_REG)"
20269   [(parallel [(set (match_dup 0) (const_int 0))
20270               (clobber (reg:CC FLAGS_REG))])]
20271 {
20272   operands[0] = gen_lowpart (word_mode, operands[0]);
20273 })
20274
20275 (define_peephole2
20276   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20277         (const_int 0))]
20278   "(GET_MODE (operands[0]) == QImode
20279     || GET_MODE (operands[0]) == HImode)
20280    && (! TARGET_USE_MOV0 || optimize_size)
20281    && peep2_regno_dead_p (0, FLAGS_REG)"
20282   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20283               (clobber (reg:CC FLAGS_REG))])])
20284
20285 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20286 (define_peephole2
20287   [(set (match_operand 0 "register_operand" "")
20288         (const_int -1))]
20289   "(GET_MODE (operands[0]) == HImode
20290     || GET_MODE (operands[0]) == SImode
20291     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20292    && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20293    && peep2_regno_dead_p (0, FLAGS_REG)"
20294   [(parallel [(set (match_dup 0) (const_int -1))
20295               (clobber (reg:CC FLAGS_REG))])]
20296   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20297                               operands[0]);")
20298
20299 ;; Attempt to convert simple leas to adds. These can be created by
20300 ;; move expanders.
20301 (define_peephole2
20302   [(set (match_operand:SI 0 "register_operand" "")
20303         (plus:SI (match_dup 0)
20304                  (match_operand:SI 1 "nonmemory_operand" "")))]
20305   "peep2_regno_dead_p (0, FLAGS_REG)"
20306   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20307               (clobber (reg:CC FLAGS_REG))])]
20308   "")
20309
20310 (define_peephole2
20311   [(set (match_operand:SI 0 "register_operand" "")
20312         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20313                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20314   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20315   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20316               (clobber (reg:CC FLAGS_REG))])]
20317   "operands[2] = gen_lowpart (SImode, operands[2]);")
20318
20319 (define_peephole2
20320   [(set (match_operand:DI 0 "register_operand" "")
20321         (plus:DI (match_dup 0)
20322                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20323   "peep2_regno_dead_p (0, FLAGS_REG)"
20324   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20325               (clobber (reg:CC FLAGS_REG))])]
20326   "")
20327
20328 (define_peephole2
20329   [(set (match_operand:SI 0 "register_operand" "")
20330         (mult:SI (match_dup 0)
20331                  (match_operand:SI 1 "const_int_operand" "")))]
20332   "exact_log2 (INTVAL (operands[1])) >= 0
20333    && peep2_regno_dead_p (0, FLAGS_REG)"
20334   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20335               (clobber (reg:CC FLAGS_REG))])]
20336   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20337
20338 (define_peephole2
20339   [(set (match_operand:DI 0 "register_operand" "")
20340         (mult:DI (match_dup 0)
20341                  (match_operand:DI 1 "const_int_operand" "")))]
20342   "exact_log2 (INTVAL (operands[1])) >= 0
20343    && peep2_regno_dead_p (0, FLAGS_REG)"
20344   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20345               (clobber (reg:CC FLAGS_REG))])]
20346   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20347
20348 (define_peephole2
20349   [(set (match_operand:SI 0 "register_operand" "")
20350         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20351                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20352   "exact_log2 (INTVAL (operands[2])) >= 0
20353    && REGNO (operands[0]) == REGNO (operands[1])
20354    && peep2_regno_dead_p (0, FLAGS_REG)"
20355   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20356               (clobber (reg:CC FLAGS_REG))])]
20357   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20358
20359 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20360 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20361 ;; many CPUs it is also faster, since special hardware to avoid esp
20362 ;; dependencies is present.
20363
20364 ;; While some of these conversions may be done using splitters, we use peepholes
20365 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20366
20367 ;; Convert prologue esp subtractions to push.
20368 ;; We need register to push.  In order to keep verify_flow_info happy we have
20369 ;; two choices
20370 ;; - use scratch and clobber it in order to avoid dependencies
20371 ;; - use already live register
20372 ;; We can't use the second way right now, since there is no reliable way how to
20373 ;; verify that given register is live.  First choice will also most likely in
20374 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20375 ;; call clobbered registers are dead.  We may want to use base pointer as an
20376 ;; alternative when no register is available later.
20377
20378 (define_peephole2
20379   [(match_scratch:SI 0 "r")
20380    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20381               (clobber (reg:CC FLAGS_REG))
20382               (clobber (mem:BLK (scratch)))])]
20383   "optimize_size || !TARGET_SUB_ESP_4"
20384   [(clobber (match_dup 0))
20385    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20386               (clobber (mem:BLK (scratch)))])])
20387
20388 (define_peephole2
20389   [(match_scratch:SI 0 "r")
20390    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20391               (clobber (reg:CC FLAGS_REG))
20392               (clobber (mem:BLK (scratch)))])]
20393   "optimize_size || !TARGET_SUB_ESP_8"
20394   [(clobber (match_dup 0))
20395    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20396    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20397               (clobber (mem:BLK (scratch)))])])
20398
20399 ;; Convert esp subtractions to push.
20400 (define_peephole2
20401   [(match_scratch:SI 0 "r")
20402    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20403               (clobber (reg:CC FLAGS_REG))])]
20404   "optimize_size || !TARGET_SUB_ESP_4"
20405   [(clobber (match_dup 0))
20406    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20407
20408 (define_peephole2
20409   [(match_scratch:SI 0 "r")
20410    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20411               (clobber (reg:CC FLAGS_REG))])]
20412   "optimize_size || !TARGET_SUB_ESP_8"
20413   [(clobber (match_dup 0))
20414    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20415    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20416
20417 ;; Convert epilogue deallocator to pop.
20418 (define_peephole2
20419   [(match_scratch:SI 0 "r")
20420    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20421               (clobber (reg:CC FLAGS_REG))
20422               (clobber (mem:BLK (scratch)))])]
20423   "optimize_size || !TARGET_ADD_ESP_4"
20424   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20425               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20426               (clobber (mem:BLK (scratch)))])]
20427   "")
20428
20429 ;; Two pops case is tricky, since pop causes dependency on destination register.
20430 ;; We use two registers if available.
20431 (define_peephole2
20432   [(match_scratch:SI 0 "r")
20433    (match_scratch:SI 1 "r")
20434    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20435               (clobber (reg:CC FLAGS_REG))
20436               (clobber (mem:BLK (scratch)))])]
20437   "optimize_size || !TARGET_ADD_ESP_8"
20438   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20439               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20440               (clobber (mem:BLK (scratch)))])
20441    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20442               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20443   "")
20444
20445 (define_peephole2
20446   [(match_scratch:SI 0 "r")
20447    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20448               (clobber (reg:CC FLAGS_REG))
20449               (clobber (mem:BLK (scratch)))])]
20450   "optimize_size"
20451   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20452               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20453               (clobber (mem:BLK (scratch)))])
20454    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20455               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20456   "")
20457
20458 ;; Convert esp additions to pop.
20459 (define_peephole2
20460   [(match_scratch:SI 0 "r")
20461    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20462               (clobber (reg:CC FLAGS_REG))])]
20463   ""
20464   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20465               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20466   "")
20467
20468 ;; Two pops case is tricky, since pop causes dependency on destination register.
20469 ;; We use two registers if available.
20470 (define_peephole2
20471   [(match_scratch:SI 0 "r")
20472    (match_scratch:SI 1 "r")
20473    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20474               (clobber (reg:CC FLAGS_REG))])]
20475   ""
20476   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20477               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20478    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20479               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20480   "")
20481
20482 (define_peephole2
20483   [(match_scratch:SI 0 "r")
20484    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20485               (clobber (reg:CC FLAGS_REG))])]
20486   "optimize_size"
20487   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20488               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20489    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20490               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20491   "")
20492 \f
20493 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20494 ;; required and register dies.  Similarly for 128 to plus -128.
20495 (define_peephole2
20496   [(set (match_operand 0 "flags_reg_operand" "")
20497         (match_operator 1 "compare_operator"
20498           [(match_operand 2 "register_operand" "")
20499            (match_operand 3 "const_int_operand" "")]))]
20500   "(INTVAL (operands[3]) == -1
20501     || INTVAL (operands[3]) == 1
20502     || INTVAL (operands[3]) == 128)
20503    && ix86_match_ccmode (insn, CCGCmode)
20504    && peep2_reg_dead_p (1, operands[2])"
20505   [(parallel [(set (match_dup 0)
20506                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20507               (clobber (match_dup 2))])]
20508   "")
20509 \f
20510 (define_peephole2
20511   [(match_scratch:DI 0 "r")
20512    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20513               (clobber (reg:CC FLAGS_REG))
20514               (clobber (mem:BLK (scratch)))])]
20515   "optimize_size || !TARGET_SUB_ESP_4"
20516   [(clobber (match_dup 0))
20517    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20518               (clobber (mem:BLK (scratch)))])])
20519
20520 (define_peephole2
20521   [(match_scratch:DI 0 "r")
20522    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20523               (clobber (reg:CC FLAGS_REG))
20524               (clobber (mem:BLK (scratch)))])]
20525   "optimize_size || !TARGET_SUB_ESP_8"
20526   [(clobber (match_dup 0))
20527    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20528    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20529               (clobber (mem:BLK (scratch)))])])
20530
20531 ;; Convert esp subtractions to push.
20532 (define_peephole2
20533   [(match_scratch:DI 0 "r")
20534    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20535               (clobber (reg:CC FLAGS_REG))])]
20536   "optimize_size || !TARGET_SUB_ESP_4"
20537   [(clobber (match_dup 0))
20538    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20539
20540 (define_peephole2
20541   [(match_scratch:DI 0 "r")
20542    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20543               (clobber (reg:CC FLAGS_REG))])]
20544   "optimize_size || !TARGET_SUB_ESP_8"
20545   [(clobber (match_dup 0))
20546    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20547    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20548
20549 ;; Convert epilogue deallocator to pop.
20550 (define_peephole2
20551   [(match_scratch:DI 0 "r")
20552    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20553               (clobber (reg:CC FLAGS_REG))
20554               (clobber (mem:BLK (scratch)))])]
20555   "optimize_size || !TARGET_ADD_ESP_4"
20556   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20557               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20558               (clobber (mem:BLK (scratch)))])]
20559   "")
20560
20561 ;; Two pops case is tricky, since pop causes dependency on destination register.
20562 ;; We use two registers if available.
20563 (define_peephole2
20564   [(match_scratch:DI 0 "r")
20565    (match_scratch:DI 1 "r")
20566    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20567               (clobber (reg:CC FLAGS_REG))
20568               (clobber (mem:BLK (scratch)))])]
20569   "optimize_size || !TARGET_ADD_ESP_8"
20570   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20571               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20572               (clobber (mem:BLK (scratch)))])
20573    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20574               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20575   "")
20576
20577 (define_peephole2
20578   [(match_scratch:DI 0 "r")
20579    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20580               (clobber (reg:CC FLAGS_REG))
20581               (clobber (mem:BLK (scratch)))])]
20582   "optimize_size"
20583   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20584               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20585               (clobber (mem:BLK (scratch)))])
20586    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20587               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20588   "")
20589
20590 ;; Convert esp additions to pop.
20591 (define_peephole2
20592   [(match_scratch:DI 0 "r")
20593    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20594               (clobber (reg:CC FLAGS_REG))])]
20595   ""
20596   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20597               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20598   "")
20599
20600 ;; Two pops case is tricky, since pop causes dependency on destination register.
20601 ;; We use two registers if available.
20602 (define_peephole2
20603   [(match_scratch:DI 0 "r")
20604    (match_scratch:DI 1 "r")
20605    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20606               (clobber (reg:CC FLAGS_REG))])]
20607   ""
20608   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20609               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20610    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20611               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20612   "")
20613
20614 (define_peephole2
20615   [(match_scratch:DI 0 "r")
20616    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20617               (clobber (reg:CC FLAGS_REG))])]
20618   "optimize_size"
20619   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20620               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20621    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20622               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20623   "")
20624 \f
20625 ;; Convert imul by three, five and nine into lea
20626 (define_peephole2
20627   [(parallel
20628     [(set (match_operand:SI 0 "register_operand" "")
20629           (mult:SI (match_operand:SI 1 "register_operand" "")
20630                    (match_operand:SI 2 "const_int_operand" "")))
20631      (clobber (reg:CC FLAGS_REG))])]
20632   "INTVAL (operands[2]) == 3
20633    || INTVAL (operands[2]) == 5
20634    || INTVAL (operands[2]) == 9"
20635   [(set (match_dup 0)
20636         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20637                  (match_dup 1)))]
20638   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20639
20640 (define_peephole2
20641   [(parallel
20642     [(set (match_operand:SI 0 "register_operand" "")
20643           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20644                    (match_operand:SI 2 "const_int_operand" "")))
20645      (clobber (reg:CC FLAGS_REG))])]
20646   "!optimize_size
20647    && (INTVAL (operands[2]) == 3
20648        || INTVAL (operands[2]) == 5
20649        || INTVAL (operands[2]) == 9)"
20650   [(set (match_dup 0) (match_dup 1))
20651    (set (match_dup 0)
20652         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20653                  (match_dup 0)))]
20654   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20655
20656 (define_peephole2
20657   [(parallel
20658     [(set (match_operand:DI 0 "register_operand" "")
20659           (mult:DI (match_operand:DI 1 "register_operand" "")
20660                    (match_operand:DI 2 "const_int_operand" "")))
20661      (clobber (reg:CC FLAGS_REG))])]
20662   "TARGET_64BIT
20663    && (INTVAL (operands[2]) == 3
20664        || INTVAL (operands[2]) == 5
20665        || INTVAL (operands[2]) == 9)"
20666   [(set (match_dup 0)
20667         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20668                  (match_dup 1)))]
20669   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20670
20671 (define_peephole2
20672   [(parallel
20673     [(set (match_operand:DI 0 "register_operand" "")
20674           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20675                    (match_operand:DI 2 "const_int_operand" "")))
20676      (clobber (reg:CC FLAGS_REG))])]
20677   "TARGET_64BIT
20678    && !optimize_size
20679    && (INTVAL (operands[2]) == 3
20680        || INTVAL (operands[2]) == 5
20681        || INTVAL (operands[2]) == 9)"
20682   [(set (match_dup 0) (match_dup 1))
20683    (set (match_dup 0)
20684         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20685                  (match_dup 0)))]
20686   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20687
20688 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20689 ;; imul $32bit_imm, reg, reg is direct decoded.
20690 (define_peephole2
20691   [(match_scratch:DI 3 "r")
20692    (parallel [(set (match_operand:DI 0 "register_operand" "")
20693                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20694                             (match_operand:DI 2 "immediate_operand" "")))
20695               (clobber (reg:CC FLAGS_REG))])]
20696   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20697    && !satisfies_constraint_K (operands[2])"
20698   [(set (match_dup 3) (match_dup 1))
20699    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20700               (clobber (reg:CC FLAGS_REG))])]
20701 "")
20702
20703 (define_peephole2
20704   [(match_scratch:SI 3 "r")
20705    (parallel [(set (match_operand:SI 0 "register_operand" "")
20706                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20707                             (match_operand:SI 2 "immediate_operand" "")))
20708               (clobber (reg:CC FLAGS_REG))])]
20709   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20710    && !satisfies_constraint_K (operands[2])"
20711   [(set (match_dup 3) (match_dup 1))
20712    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20713               (clobber (reg:CC FLAGS_REG))])]
20714 "")
20715
20716 (define_peephole2
20717   [(match_scratch:SI 3 "r")
20718    (parallel [(set (match_operand:DI 0 "register_operand" "")
20719                    (zero_extend:DI
20720                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20721                               (match_operand:SI 2 "immediate_operand" ""))))
20722               (clobber (reg:CC FLAGS_REG))])]
20723   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20724    && !satisfies_constraint_K (operands[2])"
20725   [(set (match_dup 3) (match_dup 1))
20726    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20727               (clobber (reg:CC FLAGS_REG))])]
20728 "")
20729
20730 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20731 ;; Convert it into imul reg, reg
20732 ;; It would be better to force assembler to encode instruction using long
20733 ;; immediate, but there is apparently no way to do so.
20734 (define_peephole2
20735   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20736                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20737                             (match_operand:DI 2 "const_int_operand" "")))
20738               (clobber (reg:CC FLAGS_REG))])
20739    (match_scratch:DI 3 "r")]
20740   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20741    && satisfies_constraint_K (operands[2])"
20742   [(set (match_dup 3) (match_dup 2))
20743    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20744               (clobber (reg:CC FLAGS_REG))])]
20745 {
20746   if (!rtx_equal_p (operands[0], operands[1]))
20747     emit_move_insn (operands[0], operands[1]);
20748 })
20749
20750 (define_peephole2
20751   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20752                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20753                             (match_operand:SI 2 "const_int_operand" "")))
20754               (clobber (reg:CC FLAGS_REG))])
20755    (match_scratch:SI 3 "r")]
20756   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20757    && satisfies_constraint_K (operands[2])"
20758   [(set (match_dup 3) (match_dup 2))
20759    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20760               (clobber (reg:CC FLAGS_REG))])]
20761 {
20762   if (!rtx_equal_p (operands[0], operands[1]))
20763     emit_move_insn (operands[0], operands[1]);
20764 })
20765
20766 (define_peephole2
20767   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20768                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20769                             (match_operand:HI 2 "immediate_operand" "")))
20770               (clobber (reg:CC FLAGS_REG))])
20771    (match_scratch:HI 3 "r")]
20772   "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20773   [(set (match_dup 3) (match_dup 2))
20774    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20775               (clobber (reg:CC FLAGS_REG))])]
20776 {
20777   if (!rtx_equal_p (operands[0], operands[1]))
20778     emit_move_insn (operands[0], operands[1]);
20779 })
20780
20781 ;; After splitting up read-modify operations, array accesses with memory
20782 ;; operands might end up in form:
20783 ;;  sall    $2, %eax
20784 ;;  movl    4(%esp), %edx
20785 ;;  addl    %edx, %eax
20786 ;; instead of pre-splitting:
20787 ;;  sall    $2, %eax
20788 ;;  addl    4(%esp), %eax
20789 ;; Turn it into:
20790 ;;  movl    4(%esp), %edx
20791 ;;  leal    (%edx,%eax,4), %eax
20792
20793 (define_peephole2
20794   [(parallel [(set (match_operand 0 "register_operand" "")
20795                    (ashift (match_operand 1 "register_operand" "")
20796                            (match_operand 2 "const_int_operand" "")))
20797                (clobber (reg:CC FLAGS_REG))])
20798    (set (match_operand 3 "register_operand")
20799         (match_operand 4 "x86_64_general_operand" ""))
20800    (parallel [(set (match_operand 5 "register_operand" "")
20801                    (plus (match_operand 6 "register_operand" "")
20802                          (match_operand 7 "register_operand" "")))
20803                    (clobber (reg:CC FLAGS_REG))])]
20804   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20805    /* Validate MODE for lea.  */
20806    && ((!TARGET_PARTIAL_REG_STALL
20807         && (GET_MODE (operands[0]) == QImode
20808             || GET_MODE (operands[0]) == HImode))
20809        || GET_MODE (operands[0]) == SImode
20810        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20811    /* We reorder load and the shift.  */
20812    && !rtx_equal_p (operands[1], operands[3])
20813    && !reg_overlap_mentioned_p (operands[0], operands[4])
20814    /* Last PLUS must consist of operand 0 and 3.  */
20815    && !rtx_equal_p (operands[0], operands[3])
20816    && (rtx_equal_p (operands[3], operands[6])
20817        || rtx_equal_p (operands[3], operands[7]))
20818    && (rtx_equal_p (operands[0], operands[6])
20819        || rtx_equal_p (operands[0], operands[7]))
20820    /* The intermediate operand 0 must die or be same as output.  */
20821    && (rtx_equal_p (operands[0], operands[5])
20822        || peep2_reg_dead_p (3, operands[0]))"
20823   [(set (match_dup 3) (match_dup 4))
20824    (set (match_dup 0) (match_dup 1))]
20825 {
20826   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20827   int scale = 1 << INTVAL (operands[2]);
20828   rtx index = gen_lowpart (Pmode, operands[1]);
20829   rtx base = gen_lowpart (Pmode, operands[3]);
20830   rtx dest = gen_lowpart (mode, operands[5]);
20831
20832   operands[1] = gen_rtx_PLUS (Pmode, base,
20833                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20834   if (mode != Pmode)
20835     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20836   operands[0] = dest;
20837 })
20838 \f
20839 ;; Call-value patterns last so that the wildcard operand does not
20840 ;; disrupt insn-recog's switch tables.
20841
20842 (define_insn "*call_value_pop_0"
20843   [(set (match_operand 0 "" "")
20844         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20845               (match_operand:SI 2 "" "")))
20846    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20847                             (match_operand:SI 3 "immediate_operand" "")))]
20848   "!TARGET_64BIT"
20849 {
20850   if (SIBLING_CALL_P (insn))
20851     return "jmp\t%P1";
20852   else
20853     return "call\t%P1";
20854 }
20855   [(set_attr "type" "callv")])
20856
20857 (define_insn "*call_value_pop_1"
20858   [(set (match_operand 0 "" "")
20859         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20860               (match_operand:SI 2 "" "")))
20861    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20862                             (match_operand:SI 3 "immediate_operand" "i")))]
20863   "!TARGET_64BIT"
20864 {
20865   if (constant_call_address_operand (operands[1], Pmode))
20866     {
20867       if (SIBLING_CALL_P (insn))
20868         return "jmp\t%P1";
20869       else
20870         return "call\t%P1";
20871     }
20872   if (SIBLING_CALL_P (insn))
20873     return "jmp\t%A1";
20874   else
20875     return "call\t%A1";
20876 }
20877   [(set_attr "type" "callv")])
20878
20879 (define_insn "*call_value_0"
20880   [(set (match_operand 0 "" "")
20881         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20882               (match_operand:SI 2 "" "")))]
20883   "!TARGET_64BIT"
20884 {
20885   if (SIBLING_CALL_P (insn))
20886     return "jmp\t%P1";
20887   else
20888     return "call\t%P1";
20889 }
20890   [(set_attr "type" "callv")])
20891
20892 (define_insn "*call_value_0_rex64"
20893   [(set (match_operand 0 "" "")
20894         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20895               (match_operand:DI 2 "const_int_operand" "")))]
20896   "TARGET_64BIT"
20897 {
20898   if (SIBLING_CALL_P (insn))
20899     return "jmp\t%P1";
20900   else
20901     return "call\t%P1";
20902 }
20903   [(set_attr "type" "callv")])
20904
20905 (define_insn "*call_value_1"
20906   [(set (match_operand 0 "" "")
20907         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20908               (match_operand:SI 2 "" "")))]
20909   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20910 {
20911   if (constant_call_address_operand (operands[1], Pmode))
20912     return "call\t%P1";
20913   return "call\t%A1";
20914 }
20915   [(set_attr "type" "callv")])
20916
20917 (define_insn "*sibcall_value_1"
20918   [(set (match_operand 0 "" "")
20919         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20920               (match_operand:SI 2 "" "")))]
20921   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20922 {
20923   if (constant_call_address_operand (operands[1], Pmode))
20924     return "jmp\t%P1";
20925   return "jmp\t%A1";
20926 }
20927   [(set_attr "type" "callv")])
20928
20929 (define_insn "*call_value_1_rex64"
20930   [(set (match_operand 0 "" "")
20931         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20932               (match_operand:DI 2 "" "")))]
20933   "!SIBLING_CALL_P (insn) && TARGET_64BIT
20934    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20935 {
20936   if (constant_call_address_operand (operands[1], Pmode))
20937     return "call\t%P1";
20938   return "call\t%A1";
20939 }
20940   [(set_attr "type" "callv")])
20941
20942 (define_insn "*call_value_1_rex64_large"
20943   [(set (match_operand 0 "" "")
20944         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20945               (match_operand:DI 2 "" "")))]
20946   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20947   "call\t%A1"
20948   [(set_attr "type" "callv")])
20949
20950 (define_insn "*sibcall_value_1_rex64"
20951   [(set (match_operand 0 "" "")
20952         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20953               (match_operand:DI 2 "" "")))]
20954   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20955   "jmp\t%P1"
20956   [(set_attr "type" "callv")])
20957
20958 (define_insn "*sibcall_value_1_rex64_v"
20959   [(set (match_operand 0 "" "")
20960         (call (mem:QI (reg:DI R11_REG))
20961               (match_operand:DI 1 "" "")))]
20962   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20963   "jmp\t{*%%}r11"
20964   [(set_attr "type" "callv")])
20965 \f
20966 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20967 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20968 ;; caught for use by garbage collectors and the like.  Using an insn that
20969 ;; maps to SIGILL makes it more likely the program will rightfully die.
20970 ;; Keeping with tradition, "6" is in honor of #UD.
20971 (define_insn "trap"
20972   [(trap_if (const_int 1) (const_int 6))]
20973   ""
20974   { return ASM_SHORT "0x0b0f"; }
20975   [(set_attr "length" "2")])
20976
20977 (define_expand "sse_prologue_save"
20978   [(parallel [(set (match_operand:BLK 0 "" "")
20979                    (unspec:BLK [(reg:DI 21)
20980                                 (reg:DI 22)
20981                                 (reg:DI 23)
20982                                 (reg:DI 24)
20983                                 (reg:DI 25)
20984                                 (reg:DI 26)
20985                                 (reg:DI 27)
20986                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20987               (use (match_operand:DI 1 "register_operand" ""))
20988               (use (match_operand:DI 2 "immediate_operand" ""))
20989               (use (label_ref:DI (match_operand 3 "" "")))])]
20990   "TARGET_64BIT"
20991   "")
20992
20993 (define_insn "*sse_prologue_save_insn"
20994   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20995                           (match_operand:DI 4 "const_int_operand" "n")))
20996         (unspec:BLK [(reg:DI 21)
20997                      (reg:DI 22)
20998                      (reg:DI 23)
20999                      (reg:DI 24)
21000                      (reg:DI 25)
21001                      (reg:DI 26)
21002                      (reg:DI 27)
21003                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21004    (use (match_operand:DI 1 "register_operand" "r"))
21005    (use (match_operand:DI 2 "const_int_operand" "i"))
21006    (use (label_ref:DI (match_operand 3 "" "X")))]
21007   "TARGET_64BIT
21008    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21009    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21010 {
21011   int i;
21012   operands[0] = gen_rtx_MEM (Pmode,
21013                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21014   output_asm_insn ("jmp\t%A1", operands);
21015   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21016     {
21017       operands[4] = adjust_address (operands[0], DImode, i*16);
21018       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21019       PUT_MODE (operands[4], TImode);
21020       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21021         output_asm_insn ("rex", operands);
21022       output_asm_insn ("movaps\t{%5, %4|%4, %5}", operands);
21023     }
21024   (*targetm.asm_out.internal_label) (asm_out_file, "L",
21025                                      CODE_LABEL_NUMBER (operands[3]));
21026   return "";
21027 }
21028   [(set_attr "type" "other")
21029    (set_attr "length_immediate" "0")
21030    (set_attr "length_address" "0")
21031    (set_attr "length" "135")
21032    (set_attr "memory" "store")
21033    (set_attr "modrm" "0")
21034    (set_attr "mode" "DI")])
21035
21036 (define_expand "prefetch"
21037   [(prefetch (match_operand 0 "address_operand" "")
21038              (match_operand:SI 1 "const_int_operand" "")
21039              (match_operand:SI 2 "const_int_operand" ""))]
21040   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21041 {
21042   int rw = INTVAL (operands[1]);
21043   int locality = INTVAL (operands[2]);
21044
21045   gcc_assert (rw == 0 || rw == 1);
21046   gcc_assert (locality >= 0 && locality <= 3);
21047   gcc_assert (GET_MODE (operands[0]) == Pmode
21048               || GET_MODE (operands[0]) == VOIDmode);
21049
21050   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21051      supported by SSE counterpart or the SSE prefetch is not available
21052      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21053      of locality.  */
21054   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21055     operands[2] = GEN_INT (3);
21056   else
21057     operands[1] = const0_rtx;
21058 })
21059
21060 (define_insn "*prefetch_sse"
21061   [(prefetch (match_operand:SI 0 "address_operand" "p")
21062              (const_int 0)
21063              (match_operand:SI 1 "const_int_operand" ""))]
21064   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21065 {
21066   static const char * const patterns[4] = {
21067    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21068   };
21069
21070   int locality = INTVAL (operands[1]);
21071   gcc_assert (locality >= 0 && locality <= 3);
21072
21073   return patterns[locality];
21074 }
21075   [(set_attr "type" "sse")
21076    (set_attr "memory" "none")])
21077
21078 (define_insn "*prefetch_sse_rex"
21079   [(prefetch (match_operand:DI 0 "address_operand" "p")
21080              (const_int 0)
21081              (match_operand:SI 1 "const_int_operand" ""))]
21082   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21083 {
21084   static const char * const patterns[4] = {
21085    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21086   };
21087
21088   int locality = INTVAL (operands[1]);
21089   gcc_assert (locality >= 0 && locality <= 3);
21090
21091   return patterns[locality];
21092 }
21093   [(set_attr "type" "sse")
21094    (set_attr "memory" "none")])
21095
21096 (define_insn "*prefetch_3dnow"
21097   [(prefetch (match_operand:SI 0 "address_operand" "p")
21098              (match_operand:SI 1 "const_int_operand" "n")
21099              (const_int 3))]
21100   "TARGET_3DNOW && !TARGET_64BIT"
21101 {
21102   if (INTVAL (operands[1]) == 0)
21103     return "prefetch\t%a0";
21104   else
21105     return "prefetchw\t%a0";
21106 }
21107   [(set_attr "type" "mmx")
21108    (set_attr "memory" "none")])
21109
21110 (define_insn "*prefetch_3dnow_rex"
21111   [(prefetch (match_operand:DI 0 "address_operand" "p")
21112              (match_operand:SI 1 "const_int_operand" "n")
21113              (const_int 3))]
21114   "TARGET_3DNOW && TARGET_64BIT"
21115 {
21116   if (INTVAL (operands[1]) == 0)
21117     return "prefetch\t%a0";
21118   else
21119     return "prefetchw\t%a0";
21120 }
21121   [(set_attr "type" "mmx")
21122    (set_attr "memory" "none")])
21123
21124 (define_expand "stack_protect_set"
21125   [(match_operand 0 "memory_operand" "")
21126    (match_operand 1 "memory_operand" "")]
21127   ""
21128 {
21129 #ifdef TARGET_THREAD_SSP_OFFSET
21130   if (TARGET_64BIT)
21131     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21132                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21133   else
21134     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21135                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21136 #else
21137   if (TARGET_64BIT)
21138     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21139   else
21140     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21141 #endif
21142   DONE;
21143 })
21144
21145 (define_insn "stack_protect_set_si"
21146   [(set (match_operand:SI 0 "memory_operand" "=m")
21147         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21148    (set (match_scratch:SI 2 "=&r") (const_int 0))
21149    (clobber (reg:CC FLAGS_REG))]
21150   ""
21151   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21152   [(set_attr "type" "multi")])
21153
21154 (define_insn "stack_protect_set_di"
21155   [(set (match_operand:DI 0 "memory_operand" "=m")
21156         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21157    (set (match_scratch:DI 2 "=&r") (const_int 0))
21158    (clobber (reg:CC FLAGS_REG))]
21159   "TARGET_64BIT"
21160   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21161   [(set_attr "type" "multi")])
21162
21163 (define_insn "stack_tls_protect_set_si"
21164   [(set (match_operand:SI 0 "memory_operand" "=m")
21165         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21166    (set (match_scratch:SI 2 "=&r") (const_int 0))
21167    (clobber (reg:CC FLAGS_REG))]
21168   ""
21169   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21170   [(set_attr "type" "multi")])
21171
21172 (define_insn "stack_tls_protect_set_di"
21173   [(set (match_operand:DI 0 "memory_operand" "=m")
21174         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21175    (set (match_scratch:DI 2 "=&r") (const_int 0))
21176    (clobber (reg:CC FLAGS_REG))]
21177   "TARGET_64BIT"
21178   {
21179      /* The kernel uses a different segment register for performance reasons; a
21180         system call would not have to trash the userspace segment register,
21181         which would be expensive */
21182      if (ix86_cmodel != CM_KERNEL)
21183         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21184      else
21185         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21186   }
21187   [(set_attr "type" "multi")])
21188
21189 (define_expand "stack_protect_test"
21190   [(match_operand 0 "memory_operand" "")
21191    (match_operand 1 "memory_operand" "")
21192    (match_operand 2 "" "")]
21193   ""
21194 {
21195   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21196   ix86_compare_op0 = operands[0];
21197   ix86_compare_op1 = operands[1];
21198   ix86_compare_emitted = flags;
21199
21200 #ifdef TARGET_THREAD_SSP_OFFSET
21201   if (TARGET_64BIT)
21202     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21203                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21204   else
21205     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21206                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21207 #else
21208   if (TARGET_64BIT)
21209     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21210   else
21211     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21212 #endif
21213   emit_jump_insn (gen_beq (operands[2]));
21214   DONE;
21215 })
21216
21217 (define_insn "stack_protect_test_si"
21218   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21219         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21220                      (match_operand:SI 2 "memory_operand" "m")]
21221                     UNSPEC_SP_TEST))
21222    (clobber (match_scratch:SI 3 "=&r"))]
21223   ""
21224   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21225   [(set_attr "type" "multi")])
21226
21227 (define_insn "stack_protect_test_di"
21228   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21229         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21230                      (match_operand:DI 2 "memory_operand" "m")]
21231                     UNSPEC_SP_TEST))
21232    (clobber (match_scratch:DI 3 "=&r"))]
21233   "TARGET_64BIT"
21234   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21235   [(set_attr "type" "multi")])
21236
21237 (define_insn "stack_tls_protect_test_si"
21238   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21239         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21240                      (match_operand:SI 2 "const_int_operand" "i")]
21241                     UNSPEC_SP_TLS_TEST))
21242    (clobber (match_scratch:SI 3 "=r"))]
21243   ""
21244   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21245   [(set_attr "type" "multi")])
21246
21247 (define_insn "stack_tls_protect_test_di"
21248   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21249         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21250                      (match_operand:DI 2 "const_int_operand" "i")]
21251                     UNSPEC_SP_TLS_TEST))
21252    (clobber (match_scratch:DI 3 "=r"))]
21253   "TARGET_64BIT"
21254   {
21255      /* The kernel uses a different segment register for performance reasons; a
21256         system call would not have to trash the userspace segment register,
21257         which would be expensive */
21258      if (ix86_cmodel != CM_KERNEL)
21259         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21260      else
21261         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21262   }
21263   [(set_attr "type" "multi")])
21264
21265 (define_mode_iterator CRC32MODE [QI HI SI])
21266 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21267 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21268
21269 (define_insn "sse4_2_crc32<mode>"
21270   [(set (match_operand:SI 0 "register_operand" "=r")
21271         (unspec:SI
21272           [(match_operand:SI 1 "register_operand" "0")
21273            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21274           UNSPEC_CRC32))]
21275   "TARGET_SSE4_2"
21276   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21277   [(set_attr "type" "sselog1")
21278    (set_attr "prefix_rep" "1")
21279    (set_attr "prefix_extra" "1")
21280    (set_attr "mode" "SI")])
21281
21282 (define_insn "sse4_2_crc32di"
21283   [(set (match_operand:DI 0 "register_operand" "=r")
21284         (unspec:DI
21285           [(match_operand:DI 1 "register_operand" "0")
21286            (match_operand:DI 2 "nonimmediate_operand" "rm")]
21287           UNSPEC_CRC32))]
21288   "TARGET_SSE4_2 && TARGET_64BIT"
21289   "crc32q\t{%2, %0|%0, %2}"
21290   [(set_attr "type" "sselog1")
21291    (set_attr "prefix_rep" "1")
21292    (set_attr "prefix_extra" "1")
21293    (set_attr "mode" "DI")])
21294
21295 (include "mmx.md")
21296 (include "sse.md")
21297 (include "sync.md")