Merged with gcc-4_4-branch@151281.
[official-gcc.git] / gcc / config / i386 / i386.md
bloba1352b7df1e2dba36e3ee3b430d75c8aa4fbd361
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, 2009
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.
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.
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/>.  */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
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.
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.
47 ;; UNSPEC usage:
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    (UNSPEC_MACHOPIC_OFFSET      10)
63    ; Prologue support
64    (UNSPEC_STACK_ALLOC          11)
65    (UNSPEC_SET_GOT              12)
66    (UNSPEC_SSE_PROLOGUE_SAVE    13)
67    (UNSPEC_REG_SAVE             14)
68    (UNSPEC_DEF_CFA              15)
69    (UNSPEC_SET_RIP              16)
70    (UNSPEC_SET_GOT_OFFSET       17)
71    (UNSPEC_MEMORY_BLOCKAGE      18)
73    ; TLS support
74    (UNSPEC_TP                   20)
75    (UNSPEC_TLS_GD               21)
76    (UNSPEC_TLS_LD_BASE          22)
77    (UNSPEC_TLSDESC              23)
79    ; Other random patterns
80    (UNSPEC_SCAS                 30)
81    (UNSPEC_FNSTSW               31)
82    (UNSPEC_SAHF                 32)
83    (UNSPEC_FSTCW                33)
84    (UNSPEC_ADD_CARRY            34)
85    (UNSPEC_FLDCW                35)
86    (UNSPEC_REP                  36)
87    (UNSPEC_EH_RETURN            37)
88    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
89    (UNSPEC_TRUNC_NOOP           39)
91    ; For SSE/MMX support:
92    (UNSPEC_FIX_NOTRUNC          40)
93    (UNSPEC_MASKMOV              41)
94    (UNSPEC_MOVMSK               42)
95    (UNSPEC_MOVNT                43)
96    (UNSPEC_MOVU                 44)
97    (UNSPEC_RCP                  45)
98    (UNSPEC_RSQRT                46)
99    (UNSPEC_SFENCE               47)
100    (UNSPEC_PFRCP                49)
101    (UNSPEC_PFRCPIT1             40)
102    (UNSPEC_PFRCPIT2             41)
103    (UNSPEC_PFRSQRT              42)
104    (UNSPEC_PFRSQIT1             43)
105    (UNSPEC_MFENCE               44)
106    (UNSPEC_LFENCE               45)
107    (UNSPEC_PSADBW               46)
108    (UNSPEC_LDDQU                47)
109    (UNSPEC_MS_TO_SYSV_CALL      48)
111    ; Generic math support
112    (UNSPEC_COPYSIGN             50)
113    (UNSPEC_IEEE_MIN             51)     ; not commutative
114    (UNSPEC_IEEE_MAX             52)     ; not commutative
116    ; x87 Floating point
117    (UNSPEC_SIN                  60)
118    (UNSPEC_COS                  61)
119    (UNSPEC_FPATAN               62)
120    (UNSPEC_FYL2X                63)
121    (UNSPEC_FYL2XP1              64)
122    (UNSPEC_FRNDINT              65)
123    (UNSPEC_FIST                 66)
124    (UNSPEC_F2XM1                67)
125    (UNSPEC_TAN                  68)
126    (UNSPEC_FXAM                 69)
128    ; x87 Rounding
129    (UNSPEC_FRNDINT_FLOOR        70)
130    (UNSPEC_FRNDINT_CEIL         71)
131    (UNSPEC_FRNDINT_TRUNC        72)
132    (UNSPEC_FRNDINT_MASK_PM      73)
133    (UNSPEC_FIST_FLOOR           74)
134    (UNSPEC_FIST_CEIL            75)
136    ; x87 Double output FP
137    (UNSPEC_SINCOS_COS           80)
138    (UNSPEC_SINCOS_SIN           81)
139    (UNSPEC_XTRACT_FRACT         84)
140    (UNSPEC_XTRACT_EXP           85)
141    (UNSPEC_FSCALE_FRACT         86)
142    (UNSPEC_FSCALE_EXP           87)
143    (UNSPEC_FPREM_F              88)
144    (UNSPEC_FPREM_U              89)
145    (UNSPEC_FPREM1_F             90)
146    (UNSPEC_FPREM1_U             91)
148    (UNSPEC_C2_FLAG              95)
149    (UNSPEC_FXAM_MEM             96)
151    ; SSP patterns
152    (UNSPEC_SP_SET               100)
153    (UNSPEC_SP_TEST              101)
154    (UNSPEC_SP_TLS_SET           102)
155    (UNSPEC_SP_TLS_TEST          103)
157    ; SSSE3
158    (UNSPEC_PSHUFB               120)
159    (UNSPEC_PSIGN                121)
160    (UNSPEC_PALIGNR              122)
162    ; For SSE4A support
163    (UNSPEC_EXTRQI               130)
164    (UNSPEC_EXTRQ                131)
165    (UNSPEC_INSERTQI             132)
166    (UNSPEC_INSERTQ              133)
168    ; For SSE4.1 support
169    (UNSPEC_BLENDV               134)
170    (UNSPEC_INSERTPS             135)
171    (UNSPEC_DP                   136)
172    (UNSPEC_MOVNTDQA             137)
173    (UNSPEC_MPSADBW              138)
174    (UNSPEC_PHMINPOSUW           139)
175    (UNSPEC_PTEST                140)
176    (UNSPEC_ROUND                141)
178    ; For SSE4.2 support
179    (UNSPEC_CRC32                143)
180    (UNSPEC_PCMPESTR             144)
181    (UNSPEC_PCMPISTR             145)
183    ;; For SSE5
184    (UNSPEC_SSE5_INTRINSIC       150)
185    (UNSPEC_SSE5_UNSIGNED_CMP    151)
186    (UNSPEC_SSE5_TRUEFALSE       152)
187    (UNSPEC_SSE5_PERMUTE         153)
188    (UNSPEC_FRCZ                 154)
189    (UNSPEC_CVTPH2PS             155)
190    (UNSPEC_CVTPS2PH             156)
192    ; For AES support
193    (UNSPEC_AESENC               159)
194    (UNSPEC_AESENCLAST           160)
195    (UNSPEC_AESDEC               161)
196    (UNSPEC_AESDECLAST           162)
197    (UNSPEC_AESIMC               163)
198    (UNSPEC_AESKEYGENASSIST      164)
200    ; For PCLMUL support
201    (UNSPEC_PCLMUL               165)
203    ; For AVX support
204    (UNSPEC_PCMP                 166)
205    (UNSPEC_VPERMIL              167)
206    (UNSPEC_VPERMIL2F128         168)
207    (UNSPEC_MASKLOAD             169)
208    (UNSPEC_MASKSTORE            170)
209    (UNSPEC_CAST                 171)
210    (UNSPEC_VTESTP               172)
211   ])
213 (define_constants
214   [(UNSPECV_BLOCKAGE            0)
215    (UNSPECV_STACK_PROBE         1)
216    (UNSPECV_EMMS                2)
217    (UNSPECV_LDMXCSR             3)
218    (UNSPECV_STMXCSR             4)
219    (UNSPECV_FEMMS               5)
220    (UNSPECV_CLFLUSH             6)
221    (UNSPECV_ALIGN               7)
222    (UNSPECV_MONITOR             8)
223    (UNSPECV_MWAIT               9)
224    (UNSPECV_CMPXCHG             10)
225    (UNSPECV_XCHG                12)
226    (UNSPECV_LOCK                13)
227    (UNSPECV_PROLOGUE_USE        14)
228    (UNSPECV_CLD                 15)
229    (UNSPECV_VZEROALL            16)
230    (UNSPECV_VZEROUPPER          17)
231   ])
233 ;; Constants to represent pcomtrue/pcomfalse variants
234 (define_constants
235   [(PCOM_FALSE                  0)
236    (PCOM_TRUE                   1)
237    (COM_FALSE_S                 2)
238    (COM_FALSE_P                 3)
239    (COM_TRUE_S                  4)
240    (COM_TRUE_P                  5)
241   ])
243 ;; Constants used in the SSE5 pperm instruction
244 (define_constants
245   [(PPERM_SRC                   0x00)   /* copy source */
246    (PPERM_INVERT                0x20)   /* invert source */
247    (PPERM_REVERSE               0x40)   /* bit reverse source */
248    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
249    (PPERM_ZERO                  0x80)   /* all 0's */
250    (PPERM_ONES                  0xa0)   /* all 1's */
251    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
252    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
253    (PPERM_SRC1                  0x00)   /* use first source byte */
254    (PPERM_SRC2                  0x10)   /* use second source byte */
255    ])
257 ;; Registers by name.
258 (define_constants
259   [(AX_REG                       0)
260    (DX_REG                       1)
261    (CX_REG                       2)
262    (BX_REG                       3)
263    (SI_REG                       4)
264    (DI_REG                       5)
265    (BP_REG                       6)
266    (SP_REG                       7)
267    (ST0_REG                      8)
268    (ST1_REG                      9)
269    (ST2_REG                     10)
270    (ST3_REG                     11)
271    (ST4_REG                     12)
272    (ST5_REG                     13)
273    (ST6_REG                     14)
274    (ST7_REG                     15)
275    (FLAGS_REG                   17)
276    (FPSR_REG                    18)
277    (FPCR_REG                    19)
278    (XMM0_REG                    21)
279    (XMM1_REG                    22)
280    (XMM2_REG                    23)
281    (XMM3_REG                    24)
282    (XMM4_REG                    25)
283    (XMM5_REG                    26)
284    (XMM6_REG                    27)
285    (XMM7_REG                    28)
286    (MM0_REG                     29)
287    (MM1_REG                     30)
288    (MM2_REG                     31)
289    (MM3_REG                     32)
290    (MM4_REG                     33)
291    (MM5_REG                     34)
292    (MM6_REG                     35)
293    (MM7_REG                     36)
294    (R8_REG                      37)
295    (R9_REG                      38)
296    (R10_REG                     39)
297    (R11_REG                     40)
298    (R13_REG                     42)
299    (XMM8_REG                    45)
300    (XMM9_REG                    46)
301    (XMM10_REG                   47)
302    (XMM11_REG                   48)
303    (XMM12_REG                   49)
304    (XMM13_REG                   50)
305    (XMM14_REG                   51)
306    (XMM15_REG                   52)
307   ])
309 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
310 ;; from i386.c.
312 ;; In C guard expressions, put expressions which may be compile-time
313 ;; constants first.  This allows for better optimization.  For
314 ;; example, write "TARGET_64BIT && reload_completed", not
315 ;; "reload_completed && TARGET_64BIT".
318 ;; Processor type.
319 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,
320                     generic64,amdfam10"
321   (const (symbol_ref "ix86_schedule")))
323 ;; A basic instruction type.  Refinements due to arguments to be
324 ;; provided in other attributes.
325 (define_attr "type"
326   "other,multi,
327    alu,alu1,negnot,imov,imovx,lea,
328    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
329    icmp,test,ibr,setcc,icmov,
330    push,pop,call,callv,leave,
331    str,bitmanip,
332    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
333    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
334    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
335    ssemuladd,sse4arg,
336    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
337   (const_string "other"))
339 ;; Main data type used by the insn
340 (define_attr "mode"
341   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
342   (const_string "unknown"))
344 ;; The CPU unit operations uses.
345 (define_attr "unit" "integer,i387,sse,mmx,unknown"
346   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
347            (const_string "i387")
348          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
349                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
350                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
351            (const_string "sse")
352          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
353            (const_string "mmx")
354          (eq_attr "type" "other")
355            (const_string "unknown")]
356          (const_string "integer")))
358 ;; The (bounding maximum) length of an instruction immediate.
359 (define_attr "length_immediate" ""
360   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
361                           bitmanip")
362            (const_int 0)
363          (eq_attr "unit" "i387,sse,mmx")
364            (const_int 0)
365          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
366                           imul,icmp,push,pop")
367            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
368          (eq_attr "type" "imov,test")
369            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
370          (eq_attr "type" "call")
371            (if_then_else (match_operand 0 "constant_call_address_operand" "")
372              (const_int 4)
373              (const_int 0))
374          (eq_attr "type" "callv")
375            (if_then_else (match_operand 1 "constant_call_address_operand" "")
376              (const_int 4)
377              (const_int 0))
378          ;; We don't know the size before shorten_branches.  Expect
379          ;; the instruction to fit for better scheduling.
380          (eq_attr "type" "ibr")
381            (const_int 1)
382          ]
383          (symbol_ref "/* Update immediate_length and other attributes! */
384                       gcc_unreachable (),1")))
386 ;; The (bounding maximum) length of an instruction address.
387 (define_attr "length_address" ""
388   (cond [(eq_attr "type" "str,other,multi,fxch")
389            (const_int 0)
390          (and (eq_attr "type" "call")
391               (match_operand 0 "constant_call_address_operand" ""))
392              (const_int 0)
393          (and (eq_attr "type" "callv")
394               (match_operand 1 "constant_call_address_operand" ""))
395              (const_int 0)
396          ]
397          (symbol_ref "ix86_attr_length_address_default (insn)")))
399 ;; Set when length prefix is used.
400 (define_attr "prefix_data16" ""
401   (if_then_else (ior (eq_attr "mode" "HI")
402                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
403     (const_int 1)
404     (const_int 0)))
406 ;; Set when string REP prefix is used.
407 (define_attr "prefix_rep" ""
408   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
409     (const_int 1)
410     (const_int 0)))
412 ;; Set when 0f opcode prefix is used.
413 (define_attr "prefix_0f" ""
414   (if_then_else
415     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
416          (eq_attr "unit" "sse,mmx"))
417     (const_int 1)
418     (const_int 0)))
420 ;; Set when REX opcode prefix is used.
421 (define_attr "prefix_rex" ""
422   (cond [(and (eq_attr "mode" "DI")
423               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
424            (const_int 1)
425          (and (eq_attr "mode" "QI")
426               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
427                   (const_int 0)))
428            (const_int 1)
429          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
430              (const_int 0))
431            (const_int 1)
432         ]
433         (const_int 0)))
435 ;; There are also additional prefixes in SSSE3.
436 (define_attr "prefix_extra" "" (const_int 0))
438 ;; Prefix used: original, VEX or maybe VEX.
439 (define_attr "prefix" "orig,vex,maybe_vex"
440   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
441     (const_string "vex")
442     (const_string "orig")))
444 ;; There is a 8bit immediate for VEX.
445 (define_attr "prefix_vex_imm8" "" (const_int 0))
447 ;; VEX W bit is used.
448 (define_attr "prefix_vex_w" "" (const_int 0))
450 ;; The length of VEX prefix
451 (define_attr "length_vex" ""
452   (if_then_else (eq_attr "prefix_0f" "1")
453     (if_then_else (eq_attr "prefix_vex_w" "1")
454       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
455       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
456     (if_then_else (eq_attr "prefix_vex_w" "1")
457       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
458       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
460 ;; Set when modrm byte is used.
461 (define_attr "modrm" ""
462   (cond [(eq_attr "type" "str,leave")
463            (const_int 0)
464          (eq_attr "unit" "i387")
465            (const_int 0)
466          (and (eq_attr "type" "incdec")
467               (ior (match_operand:SI 1 "register_operand" "")
468                    (match_operand:HI 1 "register_operand" "")))
469            (const_int 0)
470          (and (eq_attr "type" "push")
471               (not (match_operand 1 "memory_operand" "")))
472            (const_int 0)
473          (and (eq_attr "type" "pop")
474               (not (match_operand 0 "memory_operand" "")))
475            (const_int 0)
476          (and (eq_attr "type" "imov")
477               (ior (and (match_operand 0 "register_operand" "")
478                         (match_operand 1 "immediate_operand" ""))
479                    (ior (and (match_operand 0 "ax_reg_operand" "")
480                              (match_operand 1 "memory_displacement_only_operand" ""))
481                         (and (match_operand 0 "memory_displacement_only_operand" "")
482                              (match_operand 1 "ax_reg_operand" "")))))
483            (const_int 0)
484          (and (eq_attr "type" "call")
485               (match_operand 0 "constant_call_address_operand" ""))
486              (const_int 0)
487          (and (eq_attr "type" "callv")
488               (match_operand 1 "constant_call_address_operand" ""))
489              (const_int 0)
490          ]
491          (const_int 1)))
493 ;; The (bounding maximum) length of an instruction in bytes.
494 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
495 ;; Later we may want to split them and compute proper length as for
496 ;; other insns.
497 (define_attr "length" ""
498   (cond [(eq_attr "type" "other,multi,fistp,frndint")
499            (const_int 16)
500          (eq_attr "type" "fcmp")
501            (const_int 4)
502          (eq_attr "unit" "i387")
503            (plus (const_int 2)
504                  (plus (attr "prefix_data16")
505                        (attr "length_address")))
506          (ior (eq_attr "prefix" "vex")
507               (and (eq_attr "prefix" "maybe_vex")
508                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
509            (plus (attr "length_vex")
510                  (plus (attr "prefix_vex_imm8")
511                        (plus (attr "modrm")
512                              (attr "length_address"))))]
513          (plus (plus (attr "modrm")
514                      (plus (attr "prefix_0f")
515                            (plus (attr "prefix_rex")
516                                  (plus (attr "prefix_extra")
517                                        (const_int 1)))))
518                (plus (attr "prefix_rep")
519                      (plus (attr "prefix_data16")
520                            (plus (attr "length_immediate")
521                                  (attr "length_address")))))))
523 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
524 ;; `store' if there is a simple memory reference therein, or `unknown'
525 ;; if the instruction is complex.
527 (define_attr "memory" "none,load,store,both,unknown"
528   (cond [(eq_attr "type" "other,multi,str")
529            (const_string "unknown")
530          (eq_attr "type" "lea,fcmov,fpspc")
531            (const_string "none")
532          (eq_attr "type" "fistp,leave")
533            (const_string "both")
534          (eq_attr "type" "frndint")
535            (const_string "load")
536          (eq_attr "type" "push")
537            (if_then_else (match_operand 1 "memory_operand" "")
538              (const_string "both")
539              (const_string "store"))
540          (eq_attr "type" "pop")
541            (if_then_else (match_operand 0 "memory_operand" "")
542              (const_string "both")
543              (const_string "load"))
544          (eq_attr "type" "setcc")
545            (if_then_else (match_operand 0 "memory_operand" "")
546              (const_string "store")
547              (const_string "none"))
548          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
549            (if_then_else (ior (match_operand 0 "memory_operand" "")
550                               (match_operand 1 "memory_operand" ""))
551              (const_string "load")
552              (const_string "none"))
553          (eq_attr "type" "ibr")
554            (if_then_else (match_operand 0 "memory_operand" "")
555              (const_string "load")
556              (const_string "none"))
557          (eq_attr "type" "call")
558            (if_then_else (match_operand 0 "constant_call_address_operand" "")
559              (const_string "none")
560              (const_string "load"))
561          (eq_attr "type" "callv")
562            (if_then_else (match_operand 1 "constant_call_address_operand" "")
563              (const_string "none")
564              (const_string "load"))
565          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
566               (match_operand 1 "memory_operand" ""))
567            (const_string "both")
568          (and (match_operand 0 "memory_operand" "")
569               (match_operand 1 "memory_operand" ""))
570            (const_string "both")
571          (match_operand 0 "memory_operand" "")
572            (const_string "store")
573          (match_operand 1 "memory_operand" "")
574            (const_string "load")
575          (and (eq_attr "type"
576                  "!alu1,negnot,ishift1,
577                    imov,imovx,icmp,test,bitmanip,
578                    fmov,fcmp,fsgn,
579                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
580                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
581               (match_operand 2 "memory_operand" ""))
582            (const_string "load")
583          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
584               (match_operand 3 "memory_operand" ""))
585            (const_string "load")
586         ]
587         (const_string "none")))
589 ;; Indicates if an instruction has both an immediate and a displacement.
591 (define_attr "imm_disp" "false,true,unknown"
592   (cond [(eq_attr "type" "other,multi")
593            (const_string "unknown")
594          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
595               (and (match_operand 0 "memory_displacement_operand" "")
596                    (match_operand 1 "immediate_operand" "")))
597            (const_string "true")
598          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
599               (and (match_operand 0 "memory_displacement_operand" "")
600                    (match_operand 2 "immediate_operand" "")))
601            (const_string "true")
602         ]
603         (const_string "false")))
605 ;; Indicates if an FP operation has an integer source.
607 (define_attr "fp_int_src" "false,true"
608   (const_string "false"))
610 ;; Defines rounding mode of an FP operation.
612 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
613   (const_string "any"))
615 ;; Describe a user's asm statement.
616 (define_asm_attributes
617   [(set_attr "length" "128")
618    (set_attr "type" "multi")])
620 ;; All integer comparison codes.
621 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
623 ;; All floating-point comparison codes.
624 (define_code_iterator fp_cond [unordered ordered
625                                uneq unge ungt unle unlt ltgt ])
627 (define_code_iterator plusminus [plus minus])
629 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
631 ;; Base name for define_insn
632 (define_code_attr plusminus_insn
633   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
634    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
636 ;; Base name for insn mnemonic.
637 (define_code_attr plusminus_mnemonic
638   [(plus "add") (ss_plus "adds") (us_plus "addus")
639    (minus "sub") (ss_minus "subs") (us_minus "subus")])
641 ;; Mark commutative operators as such in constraints.
642 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
643                         (minus "") (ss_minus "") (us_minus "")])
645 ;; Mapping of signed max and min
646 (define_code_iterator smaxmin [smax smin])
648 ;; Mapping of unsigned max and min
649 (define_code_iterator umaxmin [umax umin])
651 ;; Mapping of signed/unsigned max and min
652 (define_code_iterator maxmin [smax smin umax umin])
654 ;; Base name for integer and FP insn mnemonic
655 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
656                                  (umax "maxu") (umin "minu")])
657 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
659 ;; Mapping of parallel logic operators
660 (define_code_iterator plogic [and ior xor])
662 ;; Base name for insn mnemonic.
663 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
665 ;; Mapping of abs neg operators
666 (define_code_iterator absneg [abs neg])
668 ;; Base name for x87 insn mnemonic.
669 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
671 ;; All single word integer modes.
672 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
674 ;; Single word integer modes without QImode.
675 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
677 ;; Instruction suffix for integer modes.
678 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
680 ;; Register class for integer modes.
681 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
683 ;; Immediate operand constraint for integer modes.
684 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
686 ;; General operand predicate for integer modes.
687 (define_mode_attr general_operand
688         [(QI "general_operand")
689          (HI "general_operand")
690          (SI "general_operand")
691          (DI "x86_64_general_operand")])
693 ;; SSE and x87 SFmode and DFmode floating point modes
694 (define_mode_iterator MODEF [SF DF])
696 ;; All x87 floating point modes
697 (define_mode_iterator X87MODEF [SF DF XF])
699 ;; All integer modes handled by x87 fisttp operator.
700 (define_mode_iterator X87MODEI [HI SI DI])
702 ;; All integer modes handled by integer x87 operators.
703 (define_mode_iterator X87MODEI12 [HI SI])
705 ;; All integer modes handled by SSE cvtts?2si* operators.
706 (define_mode_iterator SSEMODEI24 [SI DI])
708 ;; SSE asm suffix for floating point modes
709 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
711 ;; SSE vector mode corresponding to a scalar mode
712 (define_mode_attr ssevecmode
713   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
715 ;; Instruction suffix for REX 64bit operators.
716 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
718 ;; This mode iterator allows :P to be used for patterns that operate on
719 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
720 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
723 ;; Scheduling descriptions
725 (include "pentium.md")
726 (include "ppro.md")
727 (include "k6.md")
728 (include "athlon.md")
729 (include "geode.md")
732 ;; Operand and operator predicates and constraints
734 (include "predicates.md")
735 (include "constraints.md")
738 ;; Compare instructions.
740 ;; All compare insns have expanders that save the operands away without
741 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
742 ;; after the cmp) will actually emit the cmpM.
744 (define_expand "cmpti"
745   [(set (reg:CC FLAGS_REG)
746         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
747                     (match_operand:TI 1 "x86_64_general_operand" "")))]
748   "TARGET_64BIT"
750   if (MEM_P (operands[0]) && MEM_P (operands[1]))
751     operands[0] = force_reg (TImode, operands[0]);
752   ix86_compare_op0 = operands[0];
753   ix86_compare_op1 = operands[1];
754   DONE;
757 (define_expand "cmpdi"
758   [(set (reg:CC FLAGS_REG)
759         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
760                     (match_operand:DI 1 "x86_64_general_operand" "")))]
761   ""
763   if (MEM_P (operands[0]) && MEM_P (operands[1]))
764     operands[0] = force_reg (DImode, operands[0]);
765   ix86_compare_op0 = operands[0];
766   ix86_compare_op1 = operands[1];
767   DONE;
770 (define_expand "cmpsi"
771   [(set (reg:CC FLAGS_REG)
772         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
773                     (match_operand:SI 1 "general_operand" "")))]
774   ""
776   if (MEM_P (operands[0]) && MEM_P (operands[1]))
777     operands[0] = force_reg (SImode, operands[0]);
778   ix86_compare_op0 = operands[0];
779   ix86_compare_op1 = operands[1];
780   DONE;
783 (define_expand "cmphi"
784   [(set (reg:CC FLAGS_REG)
785         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
786                     (match_operand:HI 1 "general_operand" "")))]
787   ""
789   if (MEM_P (operands[0]) && MEM_P (operands[1]))
790     operands[0] = force_reg (HImode, operands[0]);
791   ix86_compare_op0 = operands[0];
792   ix86_compare_op1 = operands[1];
793   DONE;
796 (define_expand "cmpqi"
797   [(set (reg:CC FLAGS_REG)
798         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
799                     (match_operand:QI 1 "general_operand" "")))]
800   "TARGET_QIMODE_MATH"
802   if (MEM_P (operands[0]) && MEM_P (operands[1]))
803     operands[0] = force_reg (QImode, operands[0]);
804   ix86_compare_op0 = operands[0];
805   ix86_compare_op1 = operands[1];
806   DONE;
809 (define_insn "cmpdi_ccno_1_rex64"
810   [(set (reg FLAGS_REG)
811         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
812                  (match_operand:DI 1 "const0_operand" "")))]
813   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
814   "@
815    test{q}\t%0, %0
816    cmp{q}\t{%1, %0|%0, %1}"
817   [(set_attr "type" "test,icmp")
818    (set_attr "length_immediate" "0,1")
819    (set_attr "mode" "DI")])
821 (define_insn "*cmpdi_minus_1_rex64"
822   [(set (reg FLAGS_REG)
823         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
824                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
825                  (const_int 0)))]
826   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
827   "cmp{q}\t{%1, %0|%0, %1}"
828   [(set_attr "type" "icmp")
829    (set_attr "mode" "DI")])
831 (define_expand "cmpdi_1_rex64"
832   [(set (reg:CC FLAGS_REG)
833         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
834                     (match_operand:DI 1 "general_operand" "")))]
835   "TARGET_64BIT"
836   "")
838 (define_insn "cmpdi_1_insn_rex64"
839   [(set (reg FLAGS_REG)
840         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
841                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
842   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
843   "cmp{q}\t{%1, %0|%0, %1}"
844   [(set_attr "type" "icmp")
845    (set_attr "mode" "DI")])
848 (define_insn "*cmpsi_ccno_1"
849   [(set (reg FLAGS_REG)
850         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
851                  (match_operand:SI 1 "const0_operand" "")))]
852   "ix86_match_ccmode (insn, CCNOmode)"
853   "@
854    test{l}\t%0, %0
855    cmp{l}\t{%1, %0|%0, %1}"
856   [(set_attr "type" "test,icmp")
857    (set_attr "length_immediate" "0,1")
858    (set_attr "mode" "SI")])
860 (define_insn "*cmpsi_minus_1"
861   [(set (reg FLAGS_REG)
862         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
863                            (match_operand:SI 1 "general_operand" "ri,mr"))
864                  (const_int 0)))]
865   "ix86_match_ccmode (insn, CCGOCmode)"
866   "cmp{l}\t{%1, %0|%0, %1}"
867   [(set_attr "type" "icmp")
868    (set_attr "mode" "SI")])
870 (define_expand "cmpsi_1"
871   [(set (reg:CC FLAGS_REG)
872         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
873                     (match_operand:SI 1 "general_operand" "")))]
874   ""
875   "")
877 (define_insn "*cmpsi_1_insn"
878   [(set (reg FLAGS_REG)
879         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
880                  (match_operand:SI 1 "general_operand" "ri,mr")))]
881   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
882     && ix86_match_ccmode (insn, CCmode)"
883   "cmp{l}\t{%1, %0|%0, %1}"
884   [(set_attr "type" "icmp")
885    (set_attr "mode" "SI")])
887 (define_insn "*cmphi_ccno_1"
888   [(set (reg FLAGS_REG)
889         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
890                  (match_operand:HI 1 "const0_operand" "")))]
891   "ix86_match_ccmode (insn, CCNOmode)"
892   "@
893    test{w}\t%0, %0
894    cmp{w}\t{%1, %0|%0, %1}"
895   [(set_attr "type" "test,icmp")
896    (set_attr "length_immediate" "0,1")
897    (set_attr "mode" "HI")])
899 (define_insn "*cmphi_minus_1"
900   [(set (reg FLAGS_REG)
901         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
902                            (match_operand:HI 1 "general_operand" "rn,mr"))
903                  (const_int 0)))]
904   "ix86_match_ccmode (insn, CCGOCmode)"
905   "cmp{w}\t{%1, %0|%0, %1}"
906   [(set_attr "type" "icmp")
907    (set_attr "mode" "HI")])
909 (define_insn "*cmphi_1"
910   [(set (reg FLAGS_REG)
911         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
912                  (match_operand:HI 1 "general_operand" "rn,mr")))]
913   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
914    && ix86_match_ccmode (insn, CCmode)"
915   "cmp{w}\t{%1, %0|%0, %1}"
916   [(set_attr "type" "icmp")
917    (set_attr "mode" "HI")])
919 (define_insn "*cmpqi_ccno_1"
920   [(set (reg FLAGS_REG)
921         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
922                  (match_operand:QI 1 "const0_operand" "")))]
923   "ix86_match_ccmode (insn, CCNOmode)"
924   "@
925    test{b}\t%0, %0
926    cmp{b}\t{$0, %0|%0, 0}"
927   [(set_attr "type" "test,icmp")
928    (set_attr "length_immediate" "0,1")
929    (set_attr "mode" "QI")])
931 (define_insn "*cmpqi_1"
932   [(set (reg FLAGS_REG)
933         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
934                  (match_operand:QI 1 "general_operand" "qn,mq")))]
935   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
936     && ix86_match_ccmode (insn, CCmode)"
937   "cmp{b}\t{%1, %0|%0, %1}"
938   [(set_attr "type" "icmp")
939    (set_attr "mode" "QI")])
941 (define_insn "*cmpqi_minus_1"
942   [(set (reg FLAGS_REG)
943         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
944                            (match_operand:QI 1 "general_operand" "qn,mq"))
945                  (const_int 0)))]
946   "ix86_match_ccmode (insn, CCGOCmode)"
947   "cmp{b}\t{%1, %0|%0, %1}"
948   [(set_attr "type" "icmp")
949    (set_attr "mode" "QI")])
951 (define_insn "*cmpqi_ext_1"
952   [(set (reg FLAGS_REG)
953         (compare
954           (match_operand:QI 0 "general_operand" "Qm")
955           (subreg:QI
956             (zero_extract:SI
957               (match_operand 1 "ext_register_operand" "Q")
958               (const_int 8)
959               (const_int 8)) 0)))]
960   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
961   "cmp{b}\t{%h1, %0|%0, %h1}"
962   [(set_attr "type" "icmp")
963    (set_attr "mode" "QI")])
965 (define_insn "*cmpqi_ext_1_rex64"
966   [(set (reg FLAGS_REG)
967         (compare
968           (match_operand:QI 0 "register_operand" "Q")
969           (subreg:QI
970             (zero_extract:SI
971               (match_operand 1 "ext_register_operand" "Q")
972               (const_int 8)
973               (const_int 8)) 0)))]
974   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
975   "cmp{b}\t{%h1, %0|%0, %h1}"
976   [(set_attr "type" "icmp")
977    (set_attr "mode" "QI")])
979 (define_insn "*cmpqi_ext_2"
980   [(set (reg FLAGS_REG)
981         (compare
982           (subreg:QI
983             (zero_extract:SI
984               (match_operand 0 "ext_register_operand" "Q")
985               (const_int 8)
986               (const_int 8)) 0)
987           (match_operand:QI 1 "const0_operand" "")))]
988   "ix86_match_ccmode (insn, CCNOmode)"
989   "test{b}\t%h0, %h0"
990   [(set_attr "type" "test")
991    (set_attr "length_immediate" "0")
992    (set_attr "mode" "QI")])
994 (define_expand "cmpqi_ext_3"
995   [(set (reg:CC FLAGS_REG)
996         (compare:CC
997           (subreg:QI
998             (zero_extract:SI
999               (match_operand 0 "ext_register_operand" "")
1000               (const_int 8)
1001               (const_int 8)) 0)
1002           (match_operand:QI 1 "general_operand" "")))]
1003   ""
1004   "")
1006 (define_insn "cmpqi_ext_3_insn"
1007   [(set (reg FLAGS_REG)
1008         (compare
1009           (subreg:QI
1010             (zero_extract:SI
1011               (match_operand 0 "ext_register_operand" "Q")
1012               (const_int 8)
1013               (const_int 8)) 0)
1014           (match_operand:QI 1 "general_operand" "Qmn")))]
1015   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1016   "cmp{b}\t{%1, %h0|%h0, %1}"
1017   [(set_attr "type" "icmp")
1018    (set_attr "mode" "QI")])
1020 (define_insn "cmpqi_ext_3_insn_rex64"
1021   [(set (reg FLAGS_REG)
1022         (compare
1023           (subreg:QI
1024             (zero_extract:SI
1025               (match_operand 0 "ext_register_operand" "Q")
1026               (const_int 8)
1027               (const_int 8)) 0)
1028           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1029   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1030   "cmp{b}\t{%1, %h0|%h0, %1}"
1031   [(set_attr "type" "icmp")
1032    (set_attr "mode" "QI")])
1034 (define_insn "*cmpqi_ext_4"
1035   [(set (reg FLAGS_REG)
1036         (compare
1037           (subreg:QI
1038             (zero_extract:SI
1039               (match_operand 0 "ext_register_operand" "Q")
1040               (const_int 8)
1041               (const_int 8)) 0)
1042           (subreg:QI
1043             (zero_extract:SI
1044               (match_operand 1 "ext_register_operand" "Q")
1045               (const_int 8)
1046               (const_int 8)) 0)))]
1047   "ix86_match_ccmode (insn, CCmode)"
1048   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1049   [(set_attr "type" "icmp")
1050    (set_attr "mode" "QI")])
1052 ;; These implement float point compares.
1053 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1054 ;; which would allow mix and match FP modes on the compares.  Which is what
1055 ;; the old patterns did, but with many more of them.
1057 (define_expand "cmpxf"
1058   [(set (reg:CC FLAGS_REG)
1059         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
1060                     (match_operand:XF 1 "nonmemory_operand" "")))]
1061   "TARGET_80387"
1063   ix86_compare_op0 = operands[0];
1064   ix86_compare_op1 = operands[1];
1065   DONE;
1068 (define_expand "cmp<mode>"
1069   [(set (reg:CC FLAGS_REG)
1070         (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
1071                     (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
1072   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1074   ix86_compare_op0 = operands[0];
1075   ix86_compare_op1 = operands[1];
1076   DONE;
1079 ;; FP compares, step 1:
1080 ;; Set the FP condition codes.
1082 ;; CCFPmode     compare with exceptions
1083 ;; CCFPUmode    compare with no exceptions
1085 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1086 ;; used to manage the reg stack popping would not be preserved.
1088 (define_insn "*cmpfp_0"
1089   [(set (match_operand:HI 0 "register_operand" "=a")
1090         (unspec:HI
1091           [(compare:CCFP
1092              (match_operand 1 "register_operand" "f")
1093              (match_operand 2 "const0_operand" ""))]
1094         UNSPEC_FNSTSW))]
1095   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1096    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1097   "* return output_fp_compare (insn, operands, 0, 0);"
1098   [(set_attr "type" "multi")
1099    (set_attr "unit" "i387")
1100    (set (attr "mode")
1101      (cond [(match_operand:SF 1 "" "")
1102               (const_string "SF")
1103             (match_operand:DF 1 "" "")
1104               (const_string "DF")
1105            ]
1106            (const_string "XF")))])
1108 (define_insn_and_split "*cmpfp_0_cc"
1109   [(set (reg:CCFP FLAGS_REG)
1110         (compare:CCFP
1111           (match_operand 1 "register_operand" "f")
1112           (match_operand 2 "const0_operand" "")))
1113    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1114   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1115    && TARGET_SAHF && !TARGET_CMOVE
1116    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1117   "#"
1118   "&& reload_completed"
1119   [(set (match_dup 0)
1120         (unspec:HI
1121           [(compare:CCFP (match_dup 1)(match_dup 2))]
1122         UNSPEC_FNSTSW))
1123    (set (reg:CC FLAGS_REG)
1124         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1125   ""
1126   [(set_attr "type" "multi")
1127    (set_attr "unit" "i387")
1128    (set (attr "mode")
1129      (cond [(match_operand:SF 1 "" "")
1130               (const_string "SF")
1131             (match_operand:DF 1 "" "")
1132               (const_string "DF")
1133            ]
1134            (const_string "XF")))])
1136 (define_insn "*cmpfp_xf"
1137   [(set (match_operand:HI 0 "register_operand" "=a")
1138         (unspec:HI
1139           [(compare:CCFP
1140              (match_operand:XF 1 "register_operand" "f")
1141              (match_operand:XF 2 "register_operand" "f"))]
1142           UNSPEC_FNSTSW))]
1143   "TARGET_80387"
1144   "* return output_fp_compare (insn, operands, 0, 0);"
1145   [(set_attr "type" "multi")
1146    (set_attr "unit" "i387")
1147    (set_attr "mode" "XF")])
1149 (define_insn_and_split "*cmpfp_xf_cc"
1150   [(set (reg:CCFP FLAGS_REG)
1151         (compare:CCFP
1152           (match_operand:XF 1 "register_operand" "f")
1153           (match_operand:XF 2 "register_operand" "f")))
1154    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1155   "TARGET_80387
1156    && TARGET_SAHF && !TARGET_CMOVE"
1157   "#"
1158   "&& reload_completed"
1159   [(set (match_dup 0)
1160         (unspec:HI
1161           [(compare:CCFP (match_dup 1)(match_dup 2))]
1162         UNSPEC_FNSTSW))
1163    (set (reg:CC FLAGS_REG)
1164         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1165   ""
1166   [(set_attr "type" "multi")
1167    (set_attr "unit" "i387")
1168    (set_attr "mode" "XF")])
1170 (define_insn "*cmpfp_<mode>"
1171   [(set (match_operand:HI 0 "register_operand" "=a")
1172         (unspec:HI
1173           [(compare:CCFP
1174              (match_operand:MODEF 1 "register_operand" "f")
1175              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1176           UNSPEC_FNSTSW))]
1177   "TARGET_80387"
1178   "* return output_fp_compare (insn, operands, 0, 0);"
1179   [(set_attr "type" "multi")
1180    (set_attr "unit" "i387")
1181    (set_attr "mode" "<MODE>")])
1183 (define_insn_and_split "*cmpfp_<mode>_cc"
1184   [(set (reg:CCFP FLAGS_REG)
1185         (compare:CCFP
1186           (match_operand:MODEF 1 "register_operand" "f")
1187           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1188    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1189   "TARGET_80387
1190    && TARGET_SAHF && !TARGET_CMOVE"
1191   "#"
1192   "&& reload_completed"
1193   [(set (match_dup 0)
1194         (unspec:HI
1195           [(compare:CCFP (match_dup 1)(match_dup 2))]
1196         UNSPEC_FNSTSW))
1197    (set (reg:CC FLAGS_REG)
1198         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1199   ""
1200   [(set_attr "type" "multi")
1201    (set_attr "unit" "i387")
1202    (set_attr "mode" "<MODE>")])
1204 (define_insn "*cmpfp_u"
1205   [(set (match_operand:HI 0 "register_operand" "=a")
1206         (unspec:HI
1207           [(compare:CCFPU
1208              (match_operand 1 "register_operand" "f")
1209              (match_operand 2 "register_operand" "f"))]
1210           UNSPEC_FNSTSW))]
1211   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1212    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1213   "* return output_fp_compare (insn, operands, 0, 1);"
1214   [(set_attr "type" "multi")
1215    (set_attr "unit" "i387")
1216    (set (attr "mode")
1217      (cond [(match_operand:SF 1 "" "")
1218               (const_string "SF")
1219             (match_operand:DF 1 "" "")
1220               (const_string "DF")
1221            ]
1222            (const_string "XF")))])
1224 (define_insn_and_split "*cmpfp_u_cc"
1225   [(set (reg:CCFPU FLAGS_REG)
1226         (compare:CCFPU
1227           (match_operand 1 "register_operand" "f")
1228           (match_operand 2 "register_operand" "f")))
1229    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1230   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1231    && TARGET_SAHF && !TARGET_CMOVE
1232    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1233   "#"
1234   "&& reload_completed"
1235   [(set (match_dup 0)
1236         (unspec:HI
1237           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1238         UNSPEC_FNSTSW))
1239    (set (reg:CC FLAGS_REG)
1240         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1241   ""
1242   [(set_attr "type" "multi")
1243    (set_attr "unit" "i387")
1244    (set (attr "mode")
1245      (cond [(match_operand:SF 1 "" "")
1246               (const_string "SF")
1247             (match_operand:DF 1 "" "")
1248               (const_string "DF")
1249            ]
1250            (const_string "XF")))])
1252 (define_insn "*cmpfp_<mode>"
1253   [(set (match_operand:HI 0 "register_operand" "=a")
1254         (unspec:HI
1255           [(compare:CCFP
1256              (match_operand 1 "register_operand" "f")
1257              (match_operator 3 "float_operator"
1258                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1259           UNSPEC_FNSTSW))]
1260   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1261    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1262    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1263   "* return output_fp_compare (insn, operands, 0, 0);"
1264   [(set_attr "type" "multi")
1265    (set_attr "unit" "i387")
1266    (set_attr "fp_int_src" "true")
1267    (set_attr "mode" "<MODE>")])
1269 (define_insn_and_split "*cmpfp_<mode>_cc"
1270   [(set (reg:CCFP FLAGS_REG)
1271         (compare:CCFP
1272           (match_operand 1 "register_operand" "f")
1273           (match_operator 3 "float_operator"
1274             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1275    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1276   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1277    && TARGET_SAHF && !TARGET_CMOVE
1278    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1279    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1280   "#"
1281   "&& reload_completed"
1282   [(set (match_dup 0)
1283         (unspec:HI
1284           [(compare:CCFP
1285              (match_dup 1)
1286              (match_op_dup 3 [(match_dup 2)]))]
1287         UNSPEC_FNSTSW))
1288    (set (reg:CC FLAGS_REG)
1289         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1290   ""
1291   [(set_attr "type" "multi")
1292    (set_attr "unit" "i387")
1293    (set_attr "fp_int_src" "true")
1294    (set_attr "mode" "<MODE>")])
1296 ;; FP compares, step 2
1297 ;; Move the fpsw to ax.
1299 (define_insn "x86_fnstsw_1"
1300   [(set (match_operand:HI 0 "register_operand" "=a")
1301         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1302   "TARGET_80387"
1303   "fnstsw\t%0"
1304   [(set_attr "length" "2")
1305    (set_attr "mode" "SI")
1306    (set_attr "unit" "i387")])
1308 ;; FP compares, step 3
1309 ;; Get ax into flags, general case.
1311 (define_insn "x86_sahf_1"
1312   [(set (reg:CC FLAGS_REG)
1313         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1314                    UNSPEC_SAHF))]
1315   "TARGET_SAHF"
1317 #ifdef HAVE_AS_IX86_SAHF
1318   return "sahf";
1319 #else
1320   return ".byte\t0x9e";
1321 #endif
1323   [(set_attr "length" "1")
1324    (set_attr "athlon_decode" "vector")
1325    (set_attr "amdfam10_decode" "direct")
1326    (set_attr "mode" "SI")])
1328 ;; Pentium Pro can do steps 1 through 3 in one go.
1329 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1330 (define_insn "*cmpfp_i_mixed"
1331   [(set (reg:CCFP FLAGS_REG)
1332         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1333                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1334   "TARGET_MIX_SSE_I387
1335    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1336    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1337   "* return output_fp_compare (insn, operands, 1, 0);"
1338   [(set_attr "type" "fcmp,ssecomi")
1339    (set_attr "prefix" "orig,maybe_vex")
1340    (set (attr "mode")
1341      (if_then_else (match_operand:SF 1 "" "")
1342         (const_string "SF")
1343         (const_string "DF")))
1344    (set_attr "athlon_decode" "vector")
1345    (set_attr "amdfam10_decode" "direct")])
1347 (define_insn "*cmpfp_i_sse"
1348   [(set (reg:CCFP FLAGS_REG)
1349         (compare:CCFP (match_operand 0 "register_operand" "x")
1350                       (match_operand 1 "nonimmediate_operand" "xm")))]
1351   "TARGET_SSE_MATH
1352    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1353    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1354   "* return output_fp_compare (insn, operands, 1, 0);"
1355   [(set_attr "type" "ssecomi")
1356    (set_attr "prefix" "maybe_vex")
1357    (set (attr "mode")
1358      (if_then_else (match_operand:SF 1 "" "")
1359         (const_string "SF")
1360         (const_string "DF")))
1361    (set_attr "athlon_decode" "vector")
1362    (set_attr "amdfam10_decode" "direct")])
1364 (define_insn "*cmpfp_i_i387"
1365   [(set (reg:CCFP FLAGS_REG)
1366         (compare:CCFP (match_operand 0 "register_operand" "f")
1367                       (match_operand 1 "register_operand" "f")))]
1368   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1369    && TARGET_CMOVE
1370    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1371    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1372   "* return output_fp_compare (insn, operands, 1, 0);"
1373   [(set_attr "type" "fcmp")
1374    (set (attr "mode")
1375      (cond [(match_operand:SF 1 "" "")
1376               (const_string "SF")
1377             (match_operand:DF 1 "" "")
1378               (const_string "DF")
1379            ]
1380            (const_string "XF")))
1381    (set_attr "athlon_decode" "vector")
1382    (set_attr "amdfam10_decode" "direct")])
1384 (define_insn "*cmpfp_iu_mixed"
1385   [(set (reg:CCFPU FLAGS_REG)
1386         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1387                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1388   "TARGET_MIX_SSE_I387
1389    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1390    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1391   "* return output_fp_compare (insn, operands, 1, 1);"
1392   [(set_attr "type" "fcmp,ssecomi")
1393    (set_attr "prefix" "orig,maybe_vex")
1394    (set (attr "mode")
1395      (if_then_else (match_operand:SF 1 "" "")
1396         (const_string "SF")
1397         (const_string "DF")))
1398    (set_attr "athlon_decode" "vector")
1399    (set_attr "amdfam10_decode" "direct")])
1401 (define_insn "*cmpfp_iu_sse"
1402   [(set (reg:CCFPU FLAGS_REG)
1403         (compare:CCFPU (match_operand 0 "register_operand" "x")
1404                        (match_operand 1 "nonimmediate_operand" "xm")))]
1405   "TARGET_SSE_MATH
1406    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1407    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1408   "* return output_fp_compare (insn, operands, 1, 1);"
1409   [(set_attr "type" "ssecomi")
1410    (set_attr "prefix" "maybe_vex")
1411    (set (attr "mode")
1412      (if_then_else (match_operand:SF 1 "" "")
1413         (const_string "SF")
1414         (const_string "DF")))
1415    (set_attr "athlon_decode" "vector")
1416    (set_attr "amdfam10_decode" "direct")])
1418 (define_insn "*cmpfp_iu_387"
1419   [(set (reg:CCFPU FLAGS_REG)
1420         (compare:CCFPU (match_operand 0 "register_operand" "f")
1421                        (match_operand 1 "register_operand" "f")))]
1422   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1423    && TARGET_CMOVE
1424    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1425    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1426   "* return output_fp_compare (insn, operands, 1, 1);"
1427   [(set_attr "type" "fcmp")
1428    (set (attr "mode")
1429      (cond [(match_operand:SF 1 "" "")
1430               (const_string "SF")
1431             (match_operand:DF 1 "" "")
1432               (const_string "DF")
1433            ]
1434            (const_string "XF")))
1435    (set_attr "athlon_decode" "vector")
1436    (set_attr "amdfam10_decode" "direct")])
1438 ;; Move instructions.
1440 ;; General case of fullword move.
1442 (define_expand "movsi"
1443   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1444         (match_operand:SI 1 "general_operand" ""))]
1445   ""
1446   "ix86_expand_move (SImode, operands); DONE;")
1448 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1449 ;; general_operand.
1451 ;; %%% We don't use a post-inc memory reference because x86 is not a
1452 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1453 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1454 ;; targets without our curiosities, and it is just as easy to represent
1455 ;; this differently.
1457 (define_insn "*pushsi2"
1458   [(set (match_operand:SI 0 "push_operand" "=<")
1459         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1460   "!TARGET_64BIT"
1461   "push{l}\t%1"
1462   [(set_attr "type" "push")
1463    (set_attr "mode" "SI")])
1465 ;; For 64BIT abi we always round up to 8 bytes.
1466 (define_insn "*pushsi2_rex64"
1467   [(set (match_operand:SI 0 "push_operand" "=X")
1468         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1469   "TARGET_64BIT"
1470   "push{q}\t%q1"
1471   [(set_attr "type" "push")
1472    (set_attr "mode" "SI")])
1474 (define_insn "*pushsi2_prologue"
1475   [(set (match_operand:SI 0 "push_operand" "=<")
1476         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1477    (clobber (mem:BLK (scratch)))]
1478   "!TARGET_64BIT"
1479   "push{l}\t%1"
1480   [(set_attr "type" "push")
1481    (set_attr "mode" "SI")])
1483 (define_insn "*popsi1_epilogue"
1484   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1485         (mem:SI (reg:SI SP_REG)))
1486    (set (reg:SI SP_REG)
1487         (plus:SI (reg:SI SP_REG) (const_int 4)))
1488    (clobber (mem:BLK (scratch)))]
1489   "!TARGET_64BIT"
1490   "pop{l}\t%0"
1491   [(set_attr "type" "pop")
1492    (set_attr "mode" "SI")])
1494 (define_insn "popsi1"
1495   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1496         (mem:SI (reg:SI SP_REG)))
1497    (set (reg:SI SP_REG)
1498         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1499   "!TARGET_64BIT"
1500   "pop{l}\t%0"
1501   [(set_attr "type" "pop")
1502    (set_attr "mode" "SI")])
1504 (define_insn "*movsi_xor"
1505   [(set (match_operand:SI 0 "register_operand" "=r")
1506         (match_operand:SI 1 "const0_operand" ""))
1507    (clobber (reg:CC FLAGS_REG))]
1508   "reload_completed"
1509   "xor{l}\t%0, %0"
1510   [(set_attr "type" "alu1")
1511    (set_attr "mode" "SI")
1512    (set_attr "length_immediate" "0")])
1514 (define_insn "*movsi_or"
1515   [(set (match_operand:SI 0 "register_operand" "=r")
1516         (match_operand:SI 1 "immediate_operand" "i"))
1517    (clobber (reg:CC FLAGS_REG))]
1518   "reload_completed
1519    && operands[1] == constm1_rtx"
1521   operands[1] = constm1_rtx;
1522   return "or{l}\t{%1, %0|%0, %1}";
1524   [(set_attr "type" "alu1")
1525    (set_attr "mode" "SI")
1526    (set_attr "length_immediate" "1")])
1528 (define_insn "*movsi_1"
1529   [(set (match_operand:SI 0 "nonimmediate_operand"
1530                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1531         (match_operand:SI 1 "general_operand"
1532                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1533   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1535   switch (get_attr_type (insn))
1536     {
1537     case TYPE_SSELOG1:
1538       if (get_attr_mode (insn) == MODE_TI)
1539         return "%vpxor\t%0, %d0";
1540       return "%vxorps\t%0, %d0";
1542     case TYPE_SSEMOV:
1543       switch (get_attr_mode (insn))
1544         {
1545         case MODE_TI:
1546           return "%vmovdqa\t{%1, %0|%0, %1}";
1547         case MODE_V4SF:
1548           return "%vmovaps\t{%1, %0|%0, %1}";
1549         case MODE_SI:
1550           return "%vmovd\t{%1, %0|%0, %1}";
1551         case MODE_SF:
1552           return "%vmovss\t{%1, %0|%0, %1}";
1553         default:
1554           gcc_unreachable ();
1555         }
1557     case TYPE_MMX:
1558       return "pxor\t%0, %0";
1560     case TYPE_MMXMOV:
1561       if (get_attr_mode (insn) == MODE_DI)
1562         return "movq\t{%1, %0|%0, %1}";
1563       return "movd\t{%1, %0|%0, %1}";
1565     case TYPE_LEA:
1566       return "lea{l}\t{%1, %0|%0, %1}";
1568     default:
1569       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1570       return "mov{l}\t{%1, %0|%0, %1}";
1571     }
1573   [(set (attr "type")
1574      (cond [(eq_attr "alternative" "2")
1575               (const_string "mmx")
1576             (eq_attr "alternative" "3,4,5")
1577               (const_string "mmxmov")
1578             (eq_attr "alternative" "6")
1579               (const_string "sselog1")
1580             (eq_attr "alternative" "7,8,9,10,11")
1581               (const_string "ssemov")
1582             (match_operand:DI 1 "pic_32bit_operand" "")
1583               (const_string "lea")
1584            ]
1585            (const_string "imov")))
1586    (set (attr "prefix")
1587      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1588        (const_string "orig")
1589        (const_string "maybe_vex")))
1590    (set (attr "mode")
1591      (cond [(eq_attr "alternative" "2,3")
1592               (const_string "DI")
1593             (eq_attr "alternative" "6,7")
1594               (if_then_else
1595                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1596                 (const_string "V4SF")
1597                 (const_string "TI"))
1598             (and (eq_attr "alternative" "8,9,10,11")
1599                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1600               (const_string "SF")
1601            ]
1602            (const_string "SI")))])
1604 ;; Stores and loads of ax to arbitrary constant address.
1605 ;; We fake an second form of instruction to force reload to load address
1606 ;; into register when rax is not available
1607 (define_insn "*movabssi_1_rex64"
1608   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1609         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1610   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1611   "@
1612    movabs{l}\t{%1, %P0|%P0, %1}
1613    mov{l}\t{%1, %a0|%a0, %1}"
1614   [(set_attr "type" "imov")
1615    (set_attr "modrm" "0,*")
1616    (set_attr "length_address" "8,0")
1617    (set_attr "length_immediate" "0,*")
1618    (set_attr "memory" "store")
1619    (set_attr "mode" "SI")])
1621 (define_insn "*movabssi_2_rex64"
1622   [(set (match_operand:SI 0 "register_operand" "=a,r")
1623         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1624   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1625   "@
1626    movabs{l}\t{%P1, %0|%0, %P1}
1627    mov{l}\t{%a1, %0|%0, %a1}"
1628   [(set_attr "type" "imov")
1629    (set_attr "modrm" "0,*")
1630    (set_attr "length_address" "8,0")
1631    (set_attr "length_immediate" "0")
1632    (set_attr "memory" "load")
1633    (set_attr "mode" "SI")])
1635 (define_insn "*swapsi"
1636   [(set (match_operand:SI 0 "register_operand" "+r")
1637         (match_operand:SI 1 "register_operand" "+r"))
1638    (set (match_dup 1)
1639         (match_dup 0))]
1640   ""
1641   "xchg{l}\t%1, %0"
1642   [(set_attr "type" "imov")
1643    (set_attr "mode" "SI")
1644    (set_attr "pent_pair" "np")
1645    (set_attr "athlon_decode" "vector")
1646    (set_attr "amdfam10_decode" "double")])
1648 (define_expand "movhi"
1649   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1650         (match_operand:HI 1 "general_operand" ""))]
1651   ""
1652   "ix86_expand_move (HImode, operands); DONE;")
1654 (define_insn "*pushhi2"
1655   [(set (match_operand:HI 0 "push_operand" "=X")
1656         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1657   "!TARGET_64BIT"
1658   "push{l}\t%k1"
1659   [(set_attr "type" "push")
1660    (set_attr "mode" "SI")])
1662 ;; For 64BIT abi we always round up to 8 bytes.
1663 (define_insn "*pushhi2_rex64"
1664   [(set (match_operand:HI 0 "push_operand" "=X")
1665         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1666   "TARGET_64BIT"
1667   "push{q}\t%q1"
1668   [(set_attr "type" "push")
1669    (set_attr "mode" "DI")])
1671 (define_insn "*movhi_1"
1672   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1673         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1674   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1676   switch (get_attr_type (insn))
1677     {
1678     case TYPE_IMOVX:
1679       /* movzwl is faster than movw on p2 due to partial word stalls,
1680          though not as fast as an aligned movl.  */
1681       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1682     default:
1683       if (get_attr_mode (insn) == MODE_SI)
1684         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1685       else
1686         return "mov{w}\t{%1, %0|%0, %1}";
1687     }
1689   [(set (attr "type")
1690      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1691               (const_string "imov")
1692             (and (eq_attr "alternative" "0")
1693                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1694                           (const_int 0))
1695                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1696                           (const_int 0))))
1697               (const_string "imov")
1698             (and (eq_attr "alternative" "1,2")
1699                  (match_operand:HI 1 "aligned_operand" ""))
1700               (const_string "imov")
1701             (and (ne (symbol_ref "TARGET_MOVX")
1702                      (const_int 0))
1703                  (eq_attr "alternative" "0,2"))
1704               (const_string "imovx")
1705            ]
1706            (const_string "imov")))
1707     (set (attr "mode")
1708       (cond [(eq_attr "type" "imovx")
1709                (const_string "SI")
1710              (and (eq_attr "alternative" "1,2")
1711                   (match_operand:HI 1 "aligned_operand" ""))
1712                (const_string "SI")
1713              (and (eq_attr "alternative" "0")
1714                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1715                            (const_int 0))
1716                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1717                            (const_int 0))))
1718                (const_string "SI")
1719             ]
1720             (const_string "HI")))])
1722 ;; Stores and loads of ax to arbitrary constant address.
1723 ;; We fake an second form of instruction to force reload to load address
1724 ;; into register when rax is not available
1725 (define_insn "*movabshi_1_rex64"
1726   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1727         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1728   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1729   "@
1730    movabs{w}\t{%1, %P0|%P0, %1}
1731    mov{w}\t{%1, %a0|%a0, %1}"
1732   [(set_attr "type" "imov")
1733    (set_attr "modrm" "0,*")
1734    (set_attr "length_address" "8,0")
1735    (set_attr "length_immediate" "0,*")
1736    (set_attr "memory" "store")
1737    (set_attr "mode" "HI")])
1739 (define_insn "*movabshi_2_rex64"
1740   [(set (match_operand:HI 0 "register_operand" "=a,r")
1741         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1742   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1743   "@
1744    movabs{w}\t{%P1, %0|%0, %P1}
1745    mov{w}\t{%a1, %0|%0, %a1}"
1746   [(set_attr "type" "imov")
1747    (set_attr "modrm" "0,*")
1748    (set_attr "length_address" "8,0")
1749    (set_attr "length_immediate" "0")
1750    (set_attr "memory" "load")
1751    (set_attr "mode" "HI")])
1753 (define_insn "*swaphi_1"
1754   [(set (match_operand:HI 0 "register_operand" "+r")
1755         (match_operand:HI 1 "register_operand" "+r"))
1756    (set (match_dup 1)
1757         (match_dup 0))]
1758   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1759   "xchg{l}\t%k1, %k0"
1760   [(set_attr "type" "imov")
1761    (set_attr "mode" "SI")
1762    (set_attr "pent_pair" "np")
1763    (set_attr "athlon_decode" "vector")
1764    (set_attr "amdfam10_decode" "double")])
1766 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1767 (define_insn "*swaphi_2"
1768   [(set (match_operand:HI 0 "register_operand" "+r")
1769         (match_operand:HI 1 "register_operand" "+r"))
1770    (set (match_dup 1)
1771         (match_dup 0))]
1772   "TARGET_PARTIAL_REG_STALL"
1773   "xchg{w}\t%1, %0"
1774   [(set_attr "type" "imov")
1775    (set_attr "mode" "HI")
1776    (set_attr "pent_pair" "np")
1777    (set_attr "athlon_decode" "vector")])
1779 (define_expand "movstricthi"
1780   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1781         (match_operand:HI 1 "general_operand" ""))]
1782   ""
1784   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1785     FAIL;
1786   /* Don't generate memory->memory moves, go through a register */
1787   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1788     operands[1] = force_reg (HImode, operands[1]);
1791 (define_insn "*movstricthi_1"
1792   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1793         (match_operand:HI 1 "general_operand" "rn,m"))]
1794   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1795    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1796   "mov{w}\t{%1, %0|%0, %1}"
1797   [(set_attr "type" "imov")
1798    (set_attr "mode" "HI")])
1800 (define_insn "*movstricthi_xor"
1801   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1802         (match_operand:HI 1 "const0_operand" ""))
1803    (clobber (reg:CC FLAGS_REG))]
1804   "reload_completed"
1805   "xor{w}\t%0, %0"
1806   [(set_attr "type" "alu1")
1807    (set_attr "mode" "HI")
1808    (set_attr "length_immediate" "0")])
1810 (define_expand "movqi"
1811   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1812         (match_operand:QI 1 "general_operand" ""))]
1813   ""
1814   "ix86_expand_move (QImode, operands); DONE;")
1816 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1817 ;; "push a byte".  But actually we use pushl, which has the effect
1818 ;; of rounding the amount pushed up to a word.
1820 (define_insn "*pushqi2"
1821   [(set (match_operand:QI 0 "push_operand" "=X")
1822         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1823   "!TARGET_64BIT"
1824   "push{l}\t%k1"
1825   [(set_attr "type" "push")
1826    (set_attr "mode" "SI")])
1828 ;; For 64BIT abi we always round up to 8 bytes.
1829 (define_insn "*pushqi2_rex64"
1830   [(set (match_operand:QI 0 "push_operand" "=X")
1831         (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1832   "TARGET_64BIT"
1833   "push{q}\t%q1"
1834   [(set_attr "type" "push")
1835    (set_attr "mode" "DI")])
1837 ;; Situation is quite tricky about when to choose full sized (SImode) move
1838 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1839 ;; partial register dependency machines (such as AMD Athlon), where QImode
1840 ;; moves issue extra dependency and for partial register stalls machines
1841 ;; that don't use QImode patterns (and QImode move cause stall on the next
1842 ;; instruction).
1844 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1845 ;; register stall machines with, where we use QImode instructions, since
1846 ;; partial register stall can be caused there.  Then we use movzx.
1847 (define_insn "*movqi_1"
1848   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1849         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1850   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1852   switch (get_attr_type (insn))
1853     {
1854     case TYPE_IMOVX:
1855       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1856       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1857     default:
1858       if (get_attr_mode (insn) == MODE_SI)
1859         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1860       else
1861         return "mov{b}\t{%1, %0|%0, %1}";
1862     }
1864   [(set (attr "type")
1865      (cond [(and (eq_attr "alternative" "5")
1866                  (not (match_operand:QI 1 "aligned_operand" "")))
1867               (const_string "imovx")
1868             (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1869               (const_string "imov")
1870             (and (eq_attr "alternative" "3")
1871                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1872                           (const_int 0))
1873                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1874                           (const_int 0))))
1875               (const_string "imov")
1876             (eq_attr "alternative" "3,5")
1877               (const_string "imovx")
1878             (and (ne (symbol_ref "TARGET_MOVX")
1879                      (const_int 0))
1880                  (eq_attr "alternative" "2"))
1881               (const_string "imovx")
1882            ]
1883            (const_string "imov")))
1884    (set (attr "mode")
1885       (cond [(eq_attr "alternative" "3,4,5")
1886                (const_string "SI")
1887              (eq_attr "alternative" "6")
1888                (const_string "QI")
1889              (eq_attr "type" "imovx")
1890                (const_string "SI")
1891              (and (eq_attr "type" "imov")
1892                   (and (eq_attr "alternative" "0,1")
1893                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1894                                 (const_int 0))
1895                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1896                                      (const_int 0))
1897                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1898                                      (const_int 0))))))
1899                (const_string "SI")
1900              ;; Avoid partial register stalls when not using QImode arithmetic
1901              (and (eq_attr "type" "imov")
1902                   (and (eq_attr "alternative" "0,1")
1903                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1904                                 (const_int 0))
1905                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1906                                 (const_int 0)))))
1907                (const_string "SI")
1908            ]
1909            (const_string "QI")))])
1911 (define_insn "*swapqi_1"
1912   [(set (match_operand:QI 0 "register_operand" "+r")
1913         (match_operand:QI 1 "register_operand" "+r"))
1914    (set (match_dup 1)
1915         (match_dup 0))]
1916   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1917   "xchg{l}\t%k1, %k0"
1918   [(set_attr "type" "imov")
1919    (set_attr "mode" "SI")
1920    (set_attr "pent_pair" "np")
1921    (set_attr "athlon_decode" "vector")
1922    (set_attr "amdfam10_decode" "vector")])
1924 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1925 (define_insn "*swapqi_2"
1926   [(set (match_operand:QI 0 "register_operand" "+q")
1927         (match_operand:QI 1 "register_operand" "+q"))
1928    (set (match_dup 1)
1929         (match_dup 0))]
1930   "TARGET_PARTIAL_REG_STALL"
1931   "xchg{b}\t%1, %0"
1932   [(set_attr "type" "imov")
1933    (set_attr "mode" "QI")
1934    (set_attr "pent_pair" "np")
1935    (set_attr "athlon_decode" "vector")])
1937 (define_expand "movstrictqi"
1938   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1939         (match_operand:QI 1 "general_operand" ""))]
1940   ""
1942   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1943     FAIL;
1944   /* Don't generate memory->memory moves, go through a register.  */
1945   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1946     operands[1] = force_reg (QImode, operands[1]);
1949 (define_insn "*movstrictqi_1"
1950   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1951         (match_operand:QI 1 "general_operand" "*qn,m"))]
1952   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1953    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1954   "mov{b}\t{%1, %0|%0, %1}"
1955   [(set_attr "type" "imov")
1956    (set_attr "mode" "QI")])
1958 (define_insn "*movstrictqi_xor"
1959   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1960         (match_operand:QI 1 "const0_operand" ""))
1961    (clobber (reg:CC FLAGS_REG))]
1962   "reload_completed"
1963   "xor{b}\t%0, %0"
1964   [(set_attr "type" "alu1")
1965    (set_attr "mode" "QI")
1966    (set_attr "length_immediate" "0")])
1968 (define_insn "*movsi_extv_1"
1969   [(set (match_operand:SI 0 "register_operand" "=R")
1970         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1971                          (const_int 8)
1972                          (const_int 8)))]
1973   ""
1974   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1975   [(set_attr "type" "imovx")
1976    (set_attr "mode" "SI")])
1978 (define_insn "*movhi_extv_1"
1979   [(set (match_operand:HI 0 "register_operand" "=R")
1980         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1981                          (const_int 8)
1982                          (const_int 8)))]
1983   ""
1984   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1985   [(set_attr "type" "imovx")
1986    (set_attr "mode" "SI")])
1988 (define_insn "*movqi_extv_1"
1989   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1990         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1991                          (const_int 8)
1992                          (const_int 8)))]
1993   "!TARGET_64BIT"
1995   switch (get_attr_type (insn))
1996     {
1997     case TYPE_IMOVX:
1998       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1999     default:
2000       return "mov{b}\t{%h1, %0|%0, %h1}";
2001     }
2003   [(set (attr "type")
2004      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2005                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2006                              (ne (symbol_ref "TARGET_MOVX")
2007                                  (const_int 0))))
2008         (const_string "imovx")
2009         (const_string "imov")))
2010    (set (attr "mode")
2011      (if_then_else (eq_attr "type" "imovx")
2012         (const_string "SI")
2013         (const_string "QI")))])
2015 (define_insn "*movqi_extv_1_rex64"
2016   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2017         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2018                          (const_int 8)
2019                          (const_int 8)))]
2020   "TARGET_64BIT"
2022   switch (get_attr_type (insn))
2023     {
2024     case TYPE_IMOVX:
2025       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2026     default:
2027       return "mov{b}\t{%h1, %0|%0, %h1}";
2028     }
2030   [(set (attr "type")
2031      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2032                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2033                              (ne (symbol_ref "TARGET_MOVX")
2034                                  (const_int 0))))
2035         (const_string "imovx")
2036         (const_string "imov")))
2037    (set (attr "mode")
2038      (if_then_else (eq_attr "type" "imovx")
2039         (const_string "SI")
2040         (const_string "QI")))])
2042 ;; Stores and loads of ax to arbitrary constant address.
2043 ;; We fake an second form of instruction to force reload to load address
2044 ;; into register when rax is not available
2045 (define_insn "*movabsqi_1_rex64"
2046   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2047         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2048   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2049   "@
2050    movabs{b}\t{%1, %P0|%P0, %1}
2051    mov{b}\t{%1, %a0|%a0, %1}"
2052   [(set_attr "type" "imov")
2053    (set_attr "modrm" "0,*")
2054    (set_attr "length_address" "8,0")
2055    (set_attr "length_immediate" "0,*")
2056    (set_attr "memory" "store")
2057    (set_attr "mode" "QI")])
2059 (define_insn "*movabsqi_2_rex64"
2060   [(set (match_operand:QI 0 "register_operand" "=a,r")
2061         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2062   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2063   "@
2064    movabs{b}\t{%P1, %0|%0, %P1}
2065    mov{b}\t{%a1, %0|%0, %a1}"
2066   [(set_attr "type" "imov")
2067    (set_attr "modrm" "0,*")
2068    (set_attr "length_address" "8,0")
2069    (set_attr "length_immediate" "0")
2070    (set_attr "memory" "load")
2071    (set_attr "mode" "QI")])
2073 (define_insn "*movdi_extzv_1"
2074   [(set (match_operand:DI 0 "register_operand" "=R")
2075         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2076                          (const_int 8)
2077                          (const_int 8)))]
2078   "TARGET_64BIT"
2079   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2080   [(set_attr "type" "imovx")
2081    (set_attr "mode" "DI")])
2083 (define_insn "*movsi_extzv_1"
2084   [(set (match_operand:SI 0 "register_operand" "=R")
2085         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2086                          (const_int 8)
2087                          (const_int 8)))]
2088   ""
2089   "movz{bl|x}\t{%h1, %0|%0, %h1}"
2090   [(set_attr "type" "imovx")
2091    (set_attr "mode" "SI")])
2093 (define_insn "*movqi_extzv_2"
2094   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2095         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2096                                     (const_int 8)
2097                                     (const_int 8)) 0))]
2098   "!TARGET_64BIT"
2100   switch (get_attr_type (insn))
2101     {
2102     case TYPE_IMOVX:
2103       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2104     default:
2105       return "mov{b}\t{%h1, %0|%0, %h1}";
2106     }
2108   [(set (attr "type")
2109      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2110                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2111                              (ne (symbol_ref "TARGET_MOVX")
2112                                  (const_int 0))))
2113         (const_string "imovx")
2114         (const_string "imov")))
2115    (set (attr "mode")
2116      (if_then_else (eq_attr "type" "imovx")
2117         (const_string "SI")
2118         (const_string "QI")))])
2120 (define_insn "*movqi_extzv_2_rex64"
2121   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2122         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2123                                     (const_int 8)
2124                                     (const_int 8)) 0))]
2125   "TARGET_64BIT"
2127   switch (get_attr_type (insn))
2128     {
2129     case TYPE_IMOVX:
2130       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2131     default:
2132       return "mov{b}\t{%h1, %0|%0, %h1}";
2133     }
2135   [(set (attr "type")
2136      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2137                         (ne (symbol_ref "TARGET_MOVX")
2138                             (const_int 0)))
2139         (const_string "imovx")
2140         (const_string "imov")))
2141    (set (attr "mode")
2142      (if_then_else (eq_attr "type" "imovx")
2143         (const_string "SI")
2144         (const_string "QI")))])
2146 (define_insn "movsi_insv_1"
2147   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2148                          (const_int 8)
2149                          (const_int 8))
2150         (match_operand:SI 1 "general_operand" "Qmn"))]
2151   "!TARGET_64BIT"
2152   "mov{b}\t{%b1, %h0|%h0, %b1}"
2153   [(set_attr "type" "imov")
2154    (set_attr "mode" "QI")])
2156 (define_insn "*movsi_insv_1_rex64"
2157   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2158                          (const_int 8)
2159                          (const_int 8))
2160         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2161   "TARGET_64BIT"
2162   "mov{b}\t{%b1, %h0|%h0, %b1}"
2163   [(set_attr "type" "imov")
2164    (set_attr "mode" "QI")])
2166 (define_insn "movdi_insv_1_rex64"
2167   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2168                          (const_int 8)
2169                          (const_int 8))
2170         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2171   "TARGET_64BIT"
2172   "mov{b}\t{%b1, %h0|%h0, %b1}"
2173   [(set_attr "type" "imov")
2174    (set_attr "mode" "QI")])
2176 (define_insn "*movqi_insv_2"
2177   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2178                          (const_int 8)
2179                          (const_int 8))
2180         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2181                      (const_int 8)))]
2182   ""
2183   "mov{b}\t{%h1, %h0|%h0, %h1}"
2184   [(set_attr "type" "imov")
2185    (set_attr "mode" "QI")])
2187 (define_expand "movdi"
2188   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2189         (match_operand:DI 1 "general_operand" ""))]
2190   ""
2191   "ix86_expand_move (DImode, operands); DONE;")
2193 (define_insn "*pushdi"
2194   [(set (match_operand:DI 0 "push_operand" "=<")
2195         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2196   "!TARGET_64BIT"
2197   "#")
2199 (define_insn "*pushdi2_rex64"
2200   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2201         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2202   "TARGET_64BIT"
2203   "@
2204    push{q}\t%1
2205    #"
2206   [(set_attr "type" "push,multi")
2207    (set_attr "mode" "DI")])
2209 ;; Convert impossible pushes of immediate to existing instructions.
2210 ;; First try to get scratch register and go through it.  In case this
2211 ;; fails, push sign extended lower part first and then overwrite
2212 ;; upper part by 32bit move.
2213 (define_peephole2
2214   [(match_scratch:DI 2 "r")
2215    (set (match_operand:DI 0 "push_operand" "")
2216         (match_operand:DI 1 "immediate_operand" ""))]
2217   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2218    && !x86_64_immediate_operand (operands[1], DImode)"
2219   [(set (match_dup 2) (match_dup 1))
2220    (set (match_dup 0) (match_dup 2))]
2221   "")
2223 ;; We need to define this as both peepholer and splitter for case
2224 ;; peephole2 pass is not run.
2225 ;; "&& 1" is needed to keep it from matching the previous pattern.
2226 (define_peephole2
2227   [(set (match_operand:DI 0 "push_operand" "")
2228         (match_operand:DI 1 "immediate_operand" ""))]
2229   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2230    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2231   [(set (match_dup 0) (match_dup 1))
2232    (set (match_dup 2) (match_dup 3))]
2233   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2234    operands[1] = gen_lowpart (DImode, operands[2]);
2235    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2236                                                     GEN_INT (4)));
2237   ")
2239 (define_split
2240   [(set (match_operand:DI 0 "push_operand" "")
2241         (match_operand:DI 1 "immediate_operand" ""))]
2242   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2243                     ? epilogue_completed : reload_completed)
2244    && !symbolic_operand (operands[1], DImode)
2245    && !x86_64_immediate_operand (operands[1], DImode)"
2246   [(set (match_dup 0) (match_dup 1))
2247    (set (match_dup 2) (match_dup 3))]
2248   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2249    operands[1] = gen_lowpart (DImode, operands[2]);
2250    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2251                                                     GEN_INT (4)));
2252   ")
2254 (define_insn "*pushdi2_prologue_rex64"
2255   [(set (match_operand:DI 0 "push_operand" "=<")
2256         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2257    (clobber (mem:BLK (scratch)))]
2258   "TARGET_64BIT"
2259   "push{q}\t%1"
2260   [(set_attr "type" "push")
2261    (set_attr "mode" "DI")])
2263 (define_insn "*popdi1_epilogue_rex64"
2264   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2265         (mem:DI (reg:DI SP_REG)))
2266    (set (reg:DI SP_REG)
2267         (plus:DI (reg:DI SP_REG) (const_int 8)))
2268    (clobber (mem:BLK (scratch)))]
2269   "TARGET_64BIT"
2270   "pop{q}\t%0"
2271   [(set_attr "type" "pop")
2272    (set_attr "mode" "DI")])
2274 (define_insn "popdi1"
2275   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2276         (mem:DI (reg:DI SP_REG)))
2277    (set (reg:DI SP_REG)
2278         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2279   "TARGET_64BIT"
2280   "pop{q}\t%0"
2281   [(set_attr "type" "pop")
2282    (set_attr "mode" "DI")])
2284 (define_insn "*movdi_xor_rex64"
2285   [(set (match_operand:DI 0 "register_operand" "=r")
2286         (match_operand:DI 1 "const0_operand" ""))
2287    (clobber (reg:CC FLAGS_REG))]
2288   "TARGET_64BIT
2289    && reload_completed"
2290   "xor{l}\t%k0, %k0";
2291   [(set_attr "type" "alu1")
2292    (set_attr "mode" "SI")
2293    (set_attr "length_immediate" "0")])
2295 (define_insn "*movdi_or_rex64"
2296   [(set (match_operand:DI 0 "register_operand" "=r")
2297         (match_operand:DI 1 "const_int_operand" "i"))
2298    (clobber (reg:CC FLAGS_REG))]
2299   "TARGET_64BIT
2300    && reload_completed
2301    && operands[1] == constm1_rtx"
2303   operands[1] = constm1_rtx;
2304   return "or{q}\t{%1, %0|%0, %1}";
2306   [(set_attr "type" "alu1")
2307    (set_attr "mode" "DI")
2308    (set_attr "length_immediate" "1")])
2310 (define_insn "*movdi_2"
2311   [(set (match_operand:DI 0 "nonimmediate_operand"
2312                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2313         (match_operand:DI 1 "general_operand"
2314                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2315   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2316   "@
2317    #
2318    #
2319    pxor\t%0, %0
2320    movq\t{%1, %0|%0, %1}
2321    movq\t{%1, %0|%0, %1}
2322    %vpxor\t%0, %d0
2323    %vmovq\t{%1, %0|%0, %1}
2324    %vmovdqa\t{%1, %0|%0, %1}
2325    %vmovq\t{%1, %0|%0, %1}
2326    xorps\t%0, %0
2327    movlps\t{%1, %0|%0, %1}
2328    movaps\t{%1, %0|%0, %1}
2329    movlps\t{%1, %0|%0, %1}"
2330   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2331    (set (attr "prefix")
2332      (if_then_else (eq_attr "alternative" "5,6,7,8")
2333        (const_string "vex")
2334        (const_string "orig")))
2335    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2337 (define_split
2338   [(set (match_operand:DI 0 "push_operand" "")
2339         (match_operand:DI 1 "general_operand" ""))]
2340   "!TARGET_64BIT && reload_completed
2341    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2342   [(const_int 0)]
2343   "ix86_split_long_move (operands); DONE;")
2345 ;; %%% This multiword shite has got to go.
2346 (define_split
2347   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2348         (match_operand:DI 1 "general_operand" ""))]
2349   "!TARGET_64BIT && reload_completed
2350    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2351    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2352   [(const_int 0)]
2353   "ix86_split_long_move (operands); DONE;")
2355 (define_insn "*movdi_1_rex64"
2356   [(set (match_operand:DI 0 "nonimmediate_operand"
2357           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2358         (match_operand:DI 1 "general_operand"
2359           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2360   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2362   switch (get_attr_type (insn))
2363     {
2364     case TYPE_SSECVT:
2365       if (SSE_REG_P (operands[0]))
2366         return "movq2dq\t{%1, %0|%0, %1}";
2367       else
2368         return "movdq2q\t{%1, %0|%0, %1}";
2370     case TYPE_SSEMOV:
2371       if (TARGET_AVX)
2372         {
2373           if (get_attr_mode (insn) == MODE_TI)
2374             return "vmovdqa\t{%1, %0|%0, %1}";
2375           else
2376             return "vmovq\t{%1, %0|%0, %1}";
2377         }
2379       if (get_attr_mode (insn) == MODE_TI)
2380         return "movdqa\t{%1, %0|%0, %1}";
2381       /* FALLTHRU */
2383     case TYPE_MMXMOV:
2384       /* Moves from and into integer register is done using movd
2385          opcode with REX prefix.  */
2386       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2387         return "movd\t{%1, %0|%0, %1}";
2388       return "movq\t{%1, %0|%0, %1}";
2390     case TYPE_SSELOG1:
2391       return "%vpxor\t%0, %d0";
2393     case TYPE_MMX:
2394       return "pxor\t%0, %0";
2396     case TYPE_MULTI:
2397       return "#";
2399     case TYPE_LEA:
2400       return "lea{q}\t{%a1, %0|%0, %a1}";
2402     default:
2403       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2404       if (get_attr_mode (insn) == MODE_SI)
2405         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2406       else if (which_alternative == 2)
2407         return "movabs{q}\t{%1, %0|%0, %1}";
2408       else
2409         return "mov{q}\t{%1, %0|%0, %1}";
2410     }
2412   [(set (attr "type")
2413      (cond [(eq_attr "alternative" "5")
2414               (const_string "mmx")
2415             (eq_attr "alternative" "6,7,8,9,10")
2416               (const_string "mmxmov")
2417             (eq_attr "alternative" "11")
2418               (const_string "sselog1")
2419             (eq_attr "alternative" "12,13,14,15,16")
2420               (const_string "ssemov")
2421             (eq_attr "alternative" "17,18")
2422               (const_string "ssecvt")
2423             (eq_attr "alternative" "4")
2424               (const_string "multi")
2425             (match_operand:DI 1 "pic_32bit_operand" "")
2426               (const_string "lea")
2427            ]
2428            (const_string "imov")))
2429    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2430    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2431    (set (attr "prefix")
2432      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2433        (const_string "maybe_vex")
2434        (const_string "orig")))
2435    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2437 ;; Stores and loads of ax to arbitrary constant address.
2438 ;; We fake an second form of instruction to force reload to load address
2439 ;; into register when rax is not available
2440 (define_insn "*movabsdi_1_rex64"
2441   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2442         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2443   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2444   "@
2445    movabs{q}\t{%1, %P0|%P0, %1}
2446    mov{q}\t{%1, %a0|%a0, %1}"
2447   [(set_attr "type" "imov")
2448    (set_attr "modrm" "0,*")
2449    (set_attr "length_address" "8,0")
2450    (set_attr "length_immediate" "0,*")
2451    (set_attr "memory" "store")
2452    (set_attr "mode" "DI")])
2454 (define_insn "*movabsdi_2_rex64"
2455   [(set (match_operand:DI 0 "register_operand" "=a,r")
2456         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2457   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2458   "@
2459    movabs{q}\t{%P1, %0|%0, %P1}
2460    mov{q}\t{%a1, %0|%0, %a1}"
2461   [(set_attr "type" "imov")
2462    (set_attr "modrm" "0,*")
2463    (set_attr "length_address" "8,0")
2464    (set_attr "length_immediate" "0")
2465    (set_attr "memory" "load")
2466    (set_attr "mode" "DI")])
2468 ;; Convert impossible stores of immediate to existing instructions.
2469 ;; First try to get scratch register and go through it.  In case this
2470 ;; fails, move by 32bit parts.
2471 (define_peephole2
2472   [(match_scratch:DI 2 "r")
2473    (set (match_operand:DI 0 "memory_operand" "")
2474         (match_operand:DI 1 "immediate_operand" ""))]
2475   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2476    && !x86_64_immediate_operand (operands[1], DImode)"
2477   [(set (match_dup 2) (match_dup 1))
2478    (set (match_dup 0) (match_dup 2))]
2479   "")
2481 ;; We need to define this as both peepholer and splitter for case
2482 ;; peephole2 pass is not run.
2483 ;; "&& 1" is needed to keep it from matching the previous pattern.
2484 (define_peephole2
2485   [(set (match_operand:DI 0 "memory_operand" "")
2486         (match_operand:DI 1 "immediate_operand" ""))]
2487   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2488    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2489   [(set (match_dup 2) (match_dup 3))
2490    (set (match_dup 4) (match_dup 5))]
2491   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2493 (define_split
2494   [(set (match_operand:DI 0 "memory_operand" "")
2495         (match_operand:DI 1 "immediate_operand" ""))]
2496   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2497                     ? epilogue_completed : reload_completed)
2498    && !symbolic_operand (operands[1], DImode)
2499    && !x86_64_immediate_operand (operands[1], DImode)"
2500   [(set (match_dup 2) (match_dup 3))
2501    (set (match_dup 4) (match_dup 5))]
2502   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2504 (define_insn "*swapdi_rex64"
2505   [(set (match_operand:DI 0 "register_operand" "+r")
2506         (match_operand:DI 1 "register_operand" "+r"))
2507    (set (match_dup 1)
2508         (match_dup 0))]
2509   "TARGET_64BIT"
2510   "xchg{q}\t%1, %0"
2511   [(set_attr "type" "imov")
2512    (set_attr "mode" "DI")
2513    (set_attr "pent_pair" "np")
2514    (set_attr "athlon_decode" "vector")
2515    (set_attr "amdfam10_decode" "double")])
2517 (define_expand "movoi"
2518   [(set (match_operand:OI 0 "nonimmediate_operand" "")
2519         (match_operand:OI 1 "general_operand" ""))]
2520   "TARGET_AVX"
2521   "ix86_expand_move (OImode, operands); DONE;")
2523 (define_insn "*movoi_internal"
2524   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2525         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2526   "TARGET_AVX
2527    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2529   switch (which_alternative)
2530     {
2531     case 0:
2532       return "vxorps\t%0, %0, %0";
2533     case 1:
2534     case 2:
2535       if (misaligned_operand (operands[0], OImode)
2536           || misaligned_operand (operands[1], OImode))
2537         return "vmovdqu\t{%1, %0|%0, %1}";
2538       else
2539         return "vmovdqa\t{%1, %0|%0, %1}";
2540     default:
2541       gcc_unreachable ();
2542     }
2544   [(set_attr "type" "sselog1,ssemov,ssemov")
2545    (set_attr "prefix" "vex")
2546    (set_attr "mode" "OI")])
2548 (define_expand "movti"
2549   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2550         (match_operand:TI 1 "nonimmediate_operand" ""))]
2551   "TARGET_SSE || TARGET_64BIT"
2553   if (TARGET_64BIT)
2554     ix86_expand_move (TImode, operands);
2555   else if (push_operand (operands[0], TImode))
2556     ix86_expand_push (TImode, operands[1]);
2557   else
2558     ix86_expand_vector_move (TImode, operands);
2559   DONE;
2562 (define_insn "*movti_internal"
2563   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2564         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2565   "TARGET_SSE && !TARGET_64BIT
2566    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2568   switch (which_alternative)
2569     {
2570     case 0:
2571       if (get_attr_mode (insn) == MODE_V4SF)
2572         return "%vxorps\t%0, %d0";
2573       else
2574         return "%vpxor\t%0, %d0";
2575     case 1:
2576     case 2:
2577       /* TDmode values are passed as TImode on the stack.  Moving them
2578          to stack may result in unaligned memory access.  */
2579       if (misaligned_operand (operands[0], TImode)
2580           || misaligned_operand (operands[1], TImode))
2581         {
2582           if (get_attr_mode (insn) == MODE_V4SF)
2583             return "%vmovups\t{%1, %0|%0, %1}";
2584          else
2585            return "%vmovdqu\t{%1, %0|%0, %1}";
2586         }
2587       else
2588         {
2589           if (get_attr_mode (insn) == MODE_V4SF)
2590             return "%vmovaps\t{%1, %0|%0, %1}";
2591          else
2592            return "%vmovdqa\t{%1, %0|%0, %1}";
2593         }
2594     default:
2595       gcc_unreachable ();
2596     }
2598   [(set_attr "type" "sselog1,ssemov,ssemov")
2599    (set_attr "prefix" "maybe_vex")
2600    (set (attr "mode")
2601         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2602                     (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2603                  (const_string "V4SF")
2604                (and (eq_attr "alternative" "2")
2605                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2606                         (const_int 0)))
2607                  (const_string "V4SF")]
2608               (const_string "TI")))])
2610 (define_insn "*movti_rex64"
2611   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2612         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2613   "TARGET_64BIT
2614    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2616   switch (which_alternative)
2617     {
2618     case 0:
2619     case 1:
2620       return "#";
2621     case 2:
2622       if (get_attr_mode (insn) == MODE_V4SF)
2623         return "%vxorps\t%0, %d0";
2624       else
2625         return "%vpxor\t%0, %d0";
2626     case 3:
2627     case 4:
2628       /* TDmode values are passed as TImode on the stack.  Moving them
2629          to stack may result in unaligned memory access.  */
2630       if (misaligned_operand (operands[0], TImode)
2631           || misaligned_operand (operands[1], TImode))
2632         {
2633           if (get_attr_mode (insn) == MODE_V4SF)
2634             return "%vmovups\t{%1, %0|%0, %1}";
2635          else
2636            return "%vmovdqu\t{%1, %0|%0, %1}";
2637         }
2638       else
2639         {
2640           if (get_attr_mode (insn) == MODE_V4SF)
2641             return "%vmovaps\t{%1, %0|%0, %1}";
2642          else
2643            return "%vmovdqa\t{%1, %0|%0, %1}";
2644         }
2645     default:
2646       gcc_unreachable ();
2647     }
2649   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2650    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2651    (set (attr "mode")
2652         (cond [(eq_attr "alternative" "2,3")
2653                  (if_then_else
2654                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2655                        (const_int 0))
2656                    (const_string "V4SF")
2657                    (const_string "TI"))
2658                (eq_attr "alternative" "4")
2659                  (if_then_else
2660                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2661                             (const_int 0))
2662                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2663                             (const_int 0)))
2664                    (const_string "V4SF")
2665                    (const_string "TI"))]
2666                (const_string "DI")))])
2668 (define_split
2669   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2670         (match_operand:TI 1 "general_operand" ""))]
2671   "reload_completed && !SSE_REG_P (operands[0])
2672    && !SSE_REG_P (operands[1])"
2673   [(const_int 0)]
2674   "ix86_split_long_move (operands); DONE;")
2676 ;; This expands to what emit_move_complex would generate if we didn't
2677 ;; have a movti pattern.  Having this avoids problems with reload on
2678 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2679 ;; to have around all the time.
2680 (define_expand "movcdi"
2681   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2682         (match_operand:CDI 1 "general_operand" ""))]
2683   ""
2685   if (push_operand (operands[0], CDImode))
2686     emit_move_complex_push (CDImode, operands[0], operands[1]);
2687   else
2688     emit_move_complex_parts (operands[0], operands[1]);
2689   DONE;
2692 (define_expand "movsf"
2693   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2694         (match_operand:SF 1 "general_operand" ""))]
2695   ""
2696   "ix86_expand_move (SFmode, operands); DONE;")
2698 (define_insn "*pushsf"
2699   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2700         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2701   "!TARGET_64BIT"
2703   /* Anything else should be already split before reg-stack.  */
2704   gcc_assert (which_alternative == 1);
2705   return "push{l}\t%1";
2707   [(set_attr "type" "multi,push,multi")
2708    (set_attr "unit" "i387,*,*")
2709    (set_attr "mode" "SF,SI,SF")])
2711 (define_insn "*pushsf_rex64"
2712   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2713         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2714   "TARGET_64BIT"
2716   /* Anything else should be already split before reg-stack.  */
2717   gcc_assert (which_alternative == 1);
2718   return "push{q}\t%q1";
2720   [(set_attr "type" "multi,push,multi")
2721    (set_attr "unit" "i387,*,*")
2722    (set_attr "mode" "SF,DI,SF")])
2724 (define_split
2725   [(set (match_operand:SF 0 "push_operand" "")
2726         (match_operand:SF 1 "memory_operand" ""))]
2727   "reload_completed
2728    && MEM_P (operands[1])
2729    && (operands[2] = find_constant_src (insn))"
2730   [(set (match_dup 0)
2731         (match_dup 2))])
2734 ;; %%% Kill this when call knows how to work this out.
2735 (define_split
2736   [(set (match_operand:SF 0 "push_operand" "")
2737         (match_operand:SF 1 "any_fp_register_operand" ""))]
2738   "!TARGET_64BIT"
2739   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2740    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2742 (define_split
2743   [(set (match_operand:SF 0 "push_operand" "")
2744         (match_operand:SF 1 "any_fp_register_operand" ""))]
2745   "TARGET_64BIT"
2746   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2747    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2749 (define_insn "*movsf_1"
2750   [(set (match_operand:SF 0 "nonimmediate_operand"
2751           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2752         (match_operand:SF 1 "general_operand"
2753           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2754   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2755    && (reload_in_progress || reload_completed
2756        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2757        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2758            && standard_80387_constant_p (operands[1]))
2759        || GET_CODE (operands[1]) != CONST_DOUBLE
2760        || memory_operand (operands[0], SFmode))"
2762   switch (which_alternative)
2763     {
2764     case 0:
2765     case 1:
2766       return output_387_reg_move (insn, operands);
2768     case 2:
2769       return standard_80387_constant_opcode (operands[1]);
2771     case 3:
2772     case 4:
2773       return "mov{l}\t{%1, %0|%0, %1}";
2774     case 5:
2775       if (get_attr_mode (insn) == MODE_TI)
2776         return "%vpxor\t%0, %d0";
2777       else
2778         return "%vxorps\t%0, %d0";
2779     case 6:
2780       if (get_attr_mode (insn) == MODE_V4SF)
2781         return "%vmovaps\t{%1, %0|%0, %1}";
2782       else
2783         return "%vmovss\t{%1, %d0|%d0, %1}";
2784     case 7:
2785       if (TARGET_AVX)
2786         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2787                                    : "vmovss\t{%1, %0|%0, %1}";
2788       else
2789         return "movss\t{%1, %0|%0, %1}";
2790     case 8:
2791       return "%vmovss\t{%1, %0|%0, %1}";
2793     case 9: case 10: case 14: case 15:
2794       return "movd\t{%1, %0|%0, %1}";
2795     case 12: case 13:
2796       return "%vmovd\t{%1, %0|%0, %1}";
2798     case 11:
2799       return "movq\t{%1, %0|%0, %1}";
2801     default:
2802       gcc_unreachable ();
2803     }
2805   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2806    (set (attr "prefix")
2807      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2808        (const_string "maybe_vex")
2809        (const_string "orig")))
2810    (set (attr "mode")
2811         (cond [(eq_attr "alternative" "3,4,9,10")
2812                  (const_string "SI")
2813                (eq_attr "alternative" "5")
2814                  (if_then_else
2815                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2816                                  (const_int 0))
2817                              (ne (symbol_ref "TARGET_SSE2")
2818                                  (const_int 0)))
2819                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2820                             (const_int 0)))
2821                    (const_string "TI")
2822                    (const_string "V4SF"))
2823                /* For architectures resolving dependencies on
2824                   whole SSE registers use APS move to break dependency
2825                   chains, otherwise use short move to avoid extra work.
2827                   Do the same for architectures resolving dependencies on
2828                   the parts.  While in DF mode it is better to always handle
2829                   just register parts, the SF mode is different due to lack
2830                   of instructions to load just part of the register.  It is
2831                   better to maintain the whole registers in single format
2832                   to avoid problems on using packed logical operations.  */
2833                (eq_attr "alternative" "6")
2834                  (if_then_else
2835                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2836                             (const_int 0))
2837                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2838                             (const_int 0)))
2839                    (const_string "V4SF")
2840                    (const_string "SF"))
2841                (eq_attr "alternative" "11")
2842                  (const_string "DI")]
2843                (const_string "SF")))])
2845 (define_insn "*swapsf"
2846   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2847         (match_operand:SF 1 "fp_register_operand" "+f"))
2848    (set (match_dup 1)
2849         (match_dup 0))]
2850   "reload_completed || TARGET_80387"
2852   if (STACK_TOP_P (operands[0]))
2853     return "fxch\t%1";
2854   else
2855     return "fxch\t%0";
2857   [(set_attr "type" "fxch")
2858    (set_attr "mode" "SF")])
2860 (define_expand "movdf"
2861   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2862         (match_operand:DF 1 "general_operand" ""))]
2863   ""
2864   "ix86_expand_move (DFmode, operands); DONE;")
2866 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2867 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2868 ;; On the average, pushdf using integers can be still shorter.  Allow this
2869 ;; pattern for optimize_size too.
2871 (define_insn "*pushdf_nointeger"
2872   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2873         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2874   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2876   /* This insn should be already split before reg-stack.  */
2877   gcc_unreachable ();
2879   [(set_attr "type" "multi")
2880    (set_attr "unit" "i387,*,*,*")
2881    (set_attr "mode" "DF,SI,SI,DF")])
2883 (define_insn "*pushdf_integer"
2884   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2885         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2886   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2888   /* This insn should be already split before reg-stack.  */
2889   gcc_unreachable ();
2891   [(set_attr "type" "multi")
2892    (set_attr "unit" "i387,*,*")
2893    (set_attr "mode" "DF,SI,DF")])
2895 ;; %%% Kill this when call knows how to work this out.
2896 (define_split
2897   [(set (match_operand:DF 0 "push_operand" "")
2898         (match_operand:DF 1 "any_fp_register_operand" ""))]
2899   "reload_completed"
2900   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2901    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2902   "")
2904 (define_split
2905   [(set (match_operand:DF 0 "push_operand" "")
2906         (match_operand:DF 1 "general_operand" ""))]
2907   "reload_completed"
2908   [(const_int 0)]
2909   "ix86_split_long_move (operands); DONE;")
2911 ;; Moving is usually shorter when only FP registers are used. This separate
2912 ;; movdf pattern avoids the use of integer registers for FP operations
2913 ;; when optimizing for size.
2915 (define_insn "*movdf_nointeger"
2916   [(set (match_operand:DF 0 "nonimmediate_operand"
2917                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2918         (match_operand:DF 1 "general_operand"
2919                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
2920   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2921    && ((optimize_function_for_size_p (cfun)
2922        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2923    && (reload_in_progress || reload_completed
2924        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2925        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2926            && optimize_function_for_size_p (cfun)
2927            && !memory_operand (operands[0], DFmode)
2928            && standard_80387_constant_p (operands[1]))
2929        || GET_CODE (operands[1]) != CONST_DOUBLE
2930        || ((optimize_function_for_size_p (cfun)
2931             || !TARGET_MEMORY_MISMATCH_STALL
2932             || reload_in_progress || reload_completed)
2933            && memory_operand (operands[0], DFmode)))"
2935   switch (which_alternative)
2936     {
2937     case 0:
2938     case 1:
2939       return output_387_reg_move (insn, operands);
2941     case 2:
2942       return standard_80387_constant_opcode (operands[1]);
2944     case 3:
2945     case 4:
2946       return "#";
2947     case 5:
2948       switch (get_attr_mode (insn))
2949         {
2950         case MODE_V4SF:
2951           return "%vxorps\t%0, %d0";
2952         case MODE_V2DF:
2953           return "%vxorpd\t%0, %d0";
2954         case MODE_TI:
2955           return "%vpxor\t%0, %d0";
2956         default:
2957           gcc_unreachable ();
2958         }
2959     case 6:
2960     case 7:
2961     case 8:
2962       switch (get_attr_mode (insn))
2963         {
2964         case MODE_V4SF:
2965           return "%vmovaps\t{%1, %0|%0, %1}";
2966         case MODE_V2DF:
2967           return "%vmovapd\t{%1, %0|%0, %1}";
2968         case MODE_TI:
2969           return "%vmovdqa\t{%1, %0|%0, %1}";
2970         case MODE_DI:
2971           return "%vmovq\t{%1, %0|%0, %1}";
2972         case MODE_DF:
2973           if (TARGET_AVX)
2974             {
2975               if (REG_P (operands[0]) && REG_P (operands[1]))
2976                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2977               else
2978                 return "vmovsd\t{%1, %0|%0, %1}";
2979             }
2980           else
2981             return "movsd\t{%1, %0|%0, %1}";
2982         case MODE_V1DF:
2983           if (TARGET_AVX)
2984             {
2985               if (REG_P (operands[0]))
2986                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
2987               else
2988                 return "vmovlpd\t{%1, %0|%0, %1}";
2989             }
2990           else
2991             return "movlpd\t{%1, %0|%0, %1}";
2992         case MODE_V2SF:
2993           if (TARGET_AVX)
2994             {
2995               if (REG_P (operands[0]))
2996                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
2997               else
2998                 return "vmovlps\t{%1, %0|%0, %1}";
2999             }
3000           else
3001             return "movlps\t{%1, %0|%0, %1}";
3002         default:
3003           gcc_unreachable ();
3004         }
3006     default:
3007       gcc_unreachable ();
3008     }
3010   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3011    (set (attr "prefix")
3012      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3013        (const_string "orig")
3014        (const_string "maybe_vex")))
3015    (set (attr "mode")
3016         (cond [(eq_attr "alternative" "0,1,2")
3017                  (const_string "DF")
3018                (eq_attr "alternative" "3,4")
3019                  (const_string "SI")
3021                /* For SSE1, we have many fewer alternatives.  */
3022                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3023                  (cond [(eq_attr "alternative" "5,6")
3024                           (const_string "V4SF")
3025                        ]
3026                    (const_string "V2SF"))
3028                /* xorps is one byte shorter.  */
3029                (eq_attr "alternative" "5")
3030                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3031                             (const_int 0))
3032                           (const_string "V4SF")
3033                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3034                             (const_int 0))
3035                           (const_string "TI")
3036                        ]
3037                        (const_string "V2DF"))
3039                /* For architectures resolving dependencies on
3040                   whole SSE registers use APD move to break dependency
3041                   chains, otherwise use short move to avoid extra work.
3043                   movaps encodes one byte shorter.  */
3044                (eq_attr "alternative" "6")
3045                  (cond
3046                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3047                         (const_int 0))
3048                       (const_string "V4SF")
3049                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3050                         (const_int 0))
3051                       (const_string "V2DF")
3052                    ]
3053                    (const_string "DF"))
3054                /* For architectures resolving dependencies on register
3055                   parts we may avoid extra work to zero out upper part
3056                   of register.  */
3057                (eq_attr "alternative" "7")
3058                  (if_then_else
3059                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3060                        (const_int 0))
3061                    (const_string "V1DF")
3062                    (const_string "DF"))
3063               ]
3064               (const_string "DF")))])
3066 (define_insn "*movdf_integer_rex64"
3067   [(set (match_operand:DF 0 "nonimmediate_operand"
3068                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
3069         (match_operand:DF 1 "general_operand"
3070                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
3071   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3072    && (reload_in_progress || reload_completed
3073        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3074        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3075            && optimize_function_for_size_p (cfun)
3076            && standard_80387_constant_p (operands[1]))
3077        || GET_CODE (operands[1]) != CONST_DOUBLE
3078        || memory_operand (operands[0], DFmode))"
3080   switch (which_alternative)
3081     {
3082     case 0:
3083     case 1:
3084       return output_387_reg_move (insn, operands);
3086     case 2:
3087       return standard_80387_constant_opcode (operands[1]);
3089     case 3:
3090     case 4:
3091       return "#";
3093     case 5:
3094       switch (get_attr_mode (insn))
3095         {
3096         case MODE_V4SF:
3097           return "%vxorps\t%0, %d0";
3098         case MODE_V2DF:
3099           return "%vxorpd\t%0, %d0";
3100         case MODE_TI:
3101           return "%vpxor\t%0, %d0";
3102         default:
3103           gcc_unreachable ();
3104         }
3105     case 6:
3106     case 7:
3107     case 8:
3108       switch (get_attr_mode (insn))
3109         {
3110         case MODE_V4SF:
3111           return "%vmovaps\t{%1, %0|%0, %1}";
3112         case MODE_V2DF:
3113           return "%vmovapd\t{%1, %0|%0, %1}";
3114         case MODE_TI:
3115           return "%vmovdqa\t{%1, %0|%0, %1}";
3116         case MODE_DI:
3117           return "%vmovq\t{%1, %0|%0, %1}";
3118         case MODE_DF:
3119           if (TARGET_AVX)
3120             {
3121               if (REG_P (operands[0]) && REG_P (operands[1]))
3122                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3123               else
3124                 return "vmovsd\t{%1, %0|%0, %1}";
3125             }
3126           else
3127             return "movsd\t{%1, %0|%0, %1}";
3128         case MODE_V1DF:
3129           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3130         case MODE_V2SF:
3131           return "%vmovlps\t{%1, %d0|%d0, %1}";
3132         default:
3133           gcc_unreachable ();
3134         }
3136     case 9:
3137     case 10:
3138     return "%vmovd\t{%1, %0|%0, %1}";
3140     default:
3141       gcc_unreachable();
3142     }
3144   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3145    (set (attr "prefix")
3146      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3147        (const_string "orig")
3148        (const_string "maybe_vex")))
3149    (set (attr "mode")
3150         (cond [(eq_attr "alternative" "0,1,2")
3151                  (const_string "DF")
3152                (eq_attr "alternative" "3,4,9,10")
3153                  (const_string "DI")
3155                /* For SSE1, we have many fewer alternatives.  */
3156                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3157                  (cond [(eq_attr "alternative" "5,6")
3158                           (const_string "V4SF")
3159                        ]
3160                    (const_string "V2SF"))
3162                /* xorps is one byte shorter.  */
3163                (eq_attr "alternative" "5")
3164                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3165                             (const_int 0))
3166                           (const_string "V4SF")
3167                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3168                             (const_int 0))
3169                           (const_string "TI")
3170                        ]
3171                        (const_string "V2DF"))
3173                /* For architectures resolving dependencies on
3174                   whole SSE registers use APD move to break dependency
3175                   chains, otherwise use short move to avoid extra work.
3177                   movaps encodes one byte shorter.  */
3178                (eq_attr "alternative" "6")
3179                  (cond
3180                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3181                         (const_int 0))
3182                       (const_string "V4SF")
3183                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3184                         (const_int 0))
3185                       (const_string "V2DF")
3186                    ]
3187                    (const_string "DF"))
3188                /* For architectures resolving dependencies on register
3189                   parts we may avoid extra work to zero out upper part
3190                   of register.  */
3191                (eq_attr "alternative" "7")
3192                  (if_then_else
3193                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3194                        (const_int 0))
3195                    (const_string "V1DF")
3196                    (const_string "DF"))
3197               ]
3198               (const_string "DF")))])
3200 (define_insn "*movdf_integer"
3201   [(set (match_operand:DF 0 "nonimmediate_operand"
3202                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3203         (match_operand:DF 1 "general_operand"
3204                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3205   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3206    && optimize_function_for_speed_p (cfun)
3207    && TARGET_INTEGER_DFMODE_MOVES
3208    && (reload_in_progress || reload_completed
3209        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3210        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3211            && optimize_function_for_size_p (cfun)
3212            && standard_80387_constant_p (operands[1]))
3213        || GET_CODE (operands[1]) != CONST_DOUBLE
3214        || memory_operand (operands[0], DFmode))"
3216   switch (which_alternative)
3217     {
3218     case 0:
3219     case 1:
3220       return output_387_reg_move (insn, operands);
3222     case 2:
3223       return standard_80387_constant_opcode (operands[1]);
3225     case 3:
3226     case 4:
3227       return "#";
3229     case 5:
3230       switch (get_attr_mode (insn))
3231         {
3232         case MODE_V4SF:
3233           return "xorps\t%0, %0";
3234         case MODE_V2DF:
3235           return "xorpd\t%0, %0";
3236         case MODE_TI:
3237           return "pxor\t%0, %0";
3238         default:
3239           gcc_unreachable ();
3240         }
3241     case 6:
3242     case 7:
3243     case 8:
3244       switch (get_attr_mode (insn))
3245         {
3246         case MODE_V4SF:
3247           return "movaps\t{%1, %0|%0, %1}";
3248         case MODE_V2DF:
3249           return "movapd\t{%1, %0|%0, %1}";
3250         case MODE_TI:
3251           return "movdqa\t{%1, %0|%0, %1}";
3252         case MODE_DI:
3253           return "movq\t{%1, %0|%0, %1}";
3254         case MODE_DF:
3255           return "movsd\t{%1, %0|%0, %1}";
3256         case MODE_V1DF:
3257           return "movlpd\t{%1, %0|%0, %1}";
3258         case MODE_V2SF:
3259           return "movlps\t{%1, %0|%0, %1}";
3260         default:
3261           gcc_unreachable ();
3262         }
3264     default:
3265       gcc_unreachable();
3266     }
3268   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3269    (set (attr "mode")
3270         (cond [(eq_attr "alternative" "0,1,2")
3271                  (const_string "DF")
3272                (eq_attr "alternative" "3,4")
3273                  (const_string "SI")
3275                /* For SSE1, we have many fewer alternatives.  */
3276                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3277                  (cond [(eq_attr "alternative" "5,6")
3278                           (const_string "V4SF")
3279                        ]
3280                    (const_string "V2SF"))
3282                /* xorps is one byte shorter.  */
3283                (eq_attr "alternative" "5")
3284                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3285                             (const_int 0))
3286                           (const_string "V4SF")
3287                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3288                             (const_int 0))
3289                           (const_string "TI")
3290                        ]
3291                        (const_string "V2DF"))
3293                /* For architectures resolving dependencies on
3294                   whole SSE registers use APD move to break dependency
3295                   chains, otherwise use short move to avoid extra work.
3297                   movaps encodes one byte shorter.  */
3298                (eq_attr "alternative" "6")
3299                  (cond
3300                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3301                         (const_int 0))
3302                       (const_string "V4SF")
3303                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3304                         (const_int 0))
3305                       (const_string "V2DF")
3306                    ]
3307                    (const_string "DF"))
3308                /* For architectures resolving dependencies on register
3309                   parts we may avoid extra work to zero out upper part
3310                   of register.  */
3311                (eq_attr "alternative" "7")
3312                  (if_then_else
3313                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3314                        (const_int 0))
3315                    (const_string "V1DF")
3316                    (const_string "DF"))
3317               ]
3318               (const_string "DF")))])
3320 (define_split
3321   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3322         (match_operand:DF 1 "general_operand" ""))]
3323   "reload_completed
3324    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3325    && ! (ANY_FP_REG_P (operands[0]) ||
3326          (GET_CODE (operands[0]) == SUBREG
3327           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3328    && ! (ANY_FP_REG_P (operands[1]) ||
3329          (GET_CODE (operands[1]) == SUBREG
3330           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3331   [(const_int 0)]
3332   "ix86_split_long_move (operands); DONE;")
3334 (define_insn "*swapdf"
3335   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3336         (match_operand:DF 1 "fp_register_operand" "+f"))
3337    (set (match_dup 1)
3338         (match_dup 0))]
3339   "reload_completed || TARGET_80387"
3341   if (STACK_TOP_P (operands[0]))
3342     return "fxch\t%1";
3343   else
3344     return "fxch\t%0";
3346   [(set_attr "type" "fxch")
3347    (set_attr "mode" "DF")])
3349 (define_expand "movxf"
3350   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3351         (match_operand:XF 1 "general_operand" ""))]
3352   ""
3353   "ix86_expand_move (XFmode, operands); DONE;")
3355 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3356 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3357 ;; Pushing using integer instructions is longer except for constants
3358 ;; and direct memory references.
3359 ;; (assuming that any given constant is pushed only once, but this ought to be
3360 ;;  handled elsewhere).
3362 (define_insn "*pushxf_nointeger"
3363   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3364         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3365   "optimize_function_for_size_p (cfun)"
3367   /* This insn should be already split before reg-stack.  */
3368   gcc_unreachable ();
3370   [(set_attr "type" "multi")
3371    (set_attr "unit" "i387,*,*")
3372    (set_attr "mode" "XF,SI,SI")])
3374 (define_insn "*pushxf_integer"
3375   [(set (match_operand:XF 0 "push_operand" "=<,<")
3376         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3377   "optimize_function_for_speed_p (cfun)"
3379   /* This insn should be already split before reg-stack.  */
3380   gcc_unreachable ();
3382   [(set_attr "type" "multi")
3383    (set_attr "unit" "i387,*")
3384    (set_attr "mode" "XF,SI")])
3386 (define_split
3387   [(set (match_operand 0 "push_operand" "")
3388         (match_operand 1 "general_operand" ""))]
3389   "reload_completed
3390    && (GET_MODE (operands[0]) == XFmode
3391        || GET_MODE (operands[0]) == DFmode)
3392    && !ANY_FP_REG_P (operands[1])"
3393   [(const_int 0)]
3394   "ix86_split_long_move (operands); DONE;")
3396 (define_split
3397   [(set (match_operand:XF 0 "push_operand" "")
3398         (match_operand:XF 1 "any_fp_register_operand" ""))]
3399   ""
3400   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3401    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3402   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3404 ;; Do not use integer registers when optimizing for size
3405 (define_insn "*movxf_nointeger"
3406   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3407         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3408   "optimize_function_for_size_p (cfun)
3409    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3410    && (reload_in_progress || reload_completed
3411        || standard_80387_constant_p (operands[1])
3412        || GET_CODE (operands[1]) != CONST_DOUBLE
3413        || memory_operand (operands[0], XFmode))"
3415   switch (which_alternative)
3416     {
3417     case 0:
3418     case 1:
3419       return output_387_reg_move (insn, operands);
3421     case 2:
3422       return standard_80387_constant_opcode (operands[1]);
3424     case 3: case 4:
3425       return "#";
3426     default:
3427       gcc_unreachable ();
3428     }
3430   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3431    (set_attr "mode" "XF,XF,XF,SI,SI")])
3433 (define_insn "*movxf_integer"
3434   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3435         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3436   "optimize_function_for_speed_p (cfun)
3437    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3438    && (reload_in_progress || reload_completed
3439        || GET_CODE (operands[1]) != CONST_DOUBLE
3440        || memory_operand (operands[0], XFmode))"
3442   switch (which_alternative)
3443     {
3444     case 0:
3445     case 1:
3446       return output_387_reg_move (insn, operands);
3448     case 2:
3449       return standard_80387_constant_opcode (operands[1]);
3451     case 3: case 4:
3452       return "#";
3454     default:
3455       gcc_unreachable ();
3456     }
3458   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3459    (set_attr "mode" "XF,XF,XF,SI,SI")])
3461 (define_expand "movtf"
3462   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3463         (match_operand:TF 1 "nonimmediate_operand" ""))]
3464   "TARGET_SSE2"
3466   ix86_expand_move (TFmode, operands);
3467   DONE;
3470 (define_insn "*movtf_internal"
3471   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3472         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3473   "TARGET_SSE2
3474    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3476   switch (which_alternative)
3477     {
3478     case 0:
3479     case 1:
3480       if (get_attr_mode (insn) == MODE_V4SF)
3481         return "%vmovaps\t{%1, %0|%0, %1}";
3482       else
3483         return "%vmovdqa\t{%1, %0|%0, %1}";
3484     case 2:
3485       if (get_attr_mode (insn) == MODE_V4SF)
3486         return "%vxorps\t%0, %d0";
3487       else
3488         return "%vpxor\t%0, %d0";
3489     case 3:
3490     case 4:
3491         return "#";
3492     default:
3493       gcc_unreachable ();
3494     }
3496   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3497    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3498    (set (attr "mode")
3499         (cond [(eq_attr "alternative" "0,2")
3500                  (if_then_else
3501                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3502                        (const_int 0))
3503                    (const_string "V4SF")
3504                    (const_string "TI"))
3505                (eq_attr "alternative" "1")
3506                  (if_then_else
3507                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3508                             (const_int 0))
3509                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3510                             (const_int 0)))
3511                    (const_string "V4SF")
3512                    (const_string "TI"))]
3513                (const_string "DI")))])
3515 (define_insn "*pushtf_sse"
3516   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3517         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3518   "TARGET_SSE2"
3520   /* This insn should be already split before reg-stack.  */
3521   gcc_unreachable ();
3523   [(set_attr "type" "multi")
3524    (set_attr "unit" "sse,*,*")
3525    (set_attr "mode" "TF,SI,SI")])
3527 (define_split
3528   [(set (match_operand:TF 0 "push_operand" "")
3529         (match_operand:TF 1 "general_operand" ""))]
3530   "TARGET_SSE2 && reload_completed
3531    && !SSE_REG_P (operands[1])"
3532   [(const_int 0)]
3533   "ix86_split_long_move (operands); DONE;")
3535 (define_split
3536   [(set (match_operand:TF 0 "push_operand" "")
3537         (match_operand:TF 1 "any_fp_register_operand" ""))]
3538   "TARGET_SSE2"
3539   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3540    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3541   "")
3543 (define_split
3544   [(set (match_operand 0 "nonimmediate_operand" "")
3545         (match_operand 1 "general_operand" ""))]
3546   "reload_completed
3547    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3548    && GET_MODE (operands[0]) == XFmode
3549    && ! (ANY_FP_REG_P (operands[0]) ||
3550          (GET_CODE (operands[0]) == SUBREG
3551           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3552    && ! (ANY_FP_REG_P (operands[1]) ||
3553          (GET_CODE (operands[1]) == SUBREG
3554           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3555   [(const_int 0)]
3556   "ix86_split_long_move (operands); DONE;")
3558 (define_split
3559   [(set (match_operand 0 "register_operand" "")
3560         (match_operand 1 "memory_operand" ""))]
3561   "reload_completed
3562    && MEM_P (operands[1])
3563    && (GET_MODE (operands[0]) == TFmode
3564        || GET_MODE (operands[0]) == XFmode
3565        || GET_MODE (operands[0]) == SFmode
3566        || GET_MODE (operands[0]) == DFmode)
3567    && (operands[2] = find_constant_src (insn))"
3568   [(set (match_dup 0) (match_dup 2))]
3570   rtx c = operands[2];
3571   rtx r = operands[0];
3573   if (GET_CODE (r) == SUBREG)
3574     r = SUBREG_REG (r);
3576   if (SSE_REG_P (r))
3577     {
3578       if (!standard_sse_constant_p (c))
3579         FAIL;
3580     }
3581   else if (FP_REG_P (r))
3582     {
3583       if (!standard_80387_constant_p (c))
3584         FAIL;
3585     }
3586   else if (MMX_REG_P (r))
3587     FAIL;
3590 (define_split
3591   [(set (match_operand 0 "register_operand" "")
3592         (float_extend (match_operand 1 "memory_operand" "")))]
3593   "reload_completed
3594    && MEM_P (operands[1])
3595    && (GET_MODE (operands[0]) == TFmode
3596        || GET_MODE (operands[0]) == XFmode
3597        || GET_MODE (operands[0]) == SFmode
3598        || GET_MODE (operands[0]) == DFmode)
3599    && (operands[2] = find_constant_src (insn))"
3600   [(set (match_dup 0) (match_dup 2))]
3602   rtx c = operands[2];
3603   rtx r = operands[0];
3605   if (GET_CODE (r) == SUBREG)
3606     r = SUBREG_REG (r);
3608   if (SSE_REG_P (r))
3609     {
3610       if (!standard_sse_constant_p (c))
3611         FAIL;
3612     }
3613   else if (FP_REG_P (r))
3614     {
3615       if (!standard_80387_constant_p (c))
3616         FAIL;
3617     }
3618   else if (MMX_REG_P (r))
3619     FAIL;
3622 (define_insn "swapxf"
3623   [(set (match_operand:XF 0 "register_operand" "+f")
3624         (match_operand:XF 1 "register_operand" "+f"))
3625    (set (match_dup 1)
3626         (match_dup 0))]
3627   "TARGET_80387"
3629   if (STACK_TOP_P (operands[0]))
3630     return "fxch\t%1";
3631   else
3632     return "fxch\t%0";
3634   [(set_attr "type" "fxch")
3635    (set_attr "mode" "XF")])
3637 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3638 (define_split
3639   [(set (match_operand:X87MODEF 0 "register_operand" "")
3640         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3641   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3642    && (standard_80387_constant_p (operands[1]) == 8
3643        || standard_80387_constant_p (operands[1]) == 9)"
3644   [(set (match_dup 0)(match_dup 1))
3645    (set (match_dup 0)
3646         (neg:X87MODEF (match_dup 0)))]
3648   REAL_VALUE_TYPE r;
3650   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3651   if (real_isnegzero (&r))
3652     operands[1] = CONST0_RTX (<MODE>mode);
3653   else
3654     operands[1] = CONST1_RTX (<MODE>mode);
3657 (define_split
3658   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3659         (match_operand:TF 1 "general_operand" ""))]
3660   "reload_completed
3661    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3662   [(const_int 0)]
3663   "ix86_split_long_move (operands); DONE;")
3665 ;; Zero extension instructions
3667 (define_expand "zero_extendhisi2"
3668   [(set (match_operand:SI 0 "register_operand" "")
3669      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3670   ""
3672   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3673     {
3674       operands[1] = force_reg (HImode, operands[1]);
3675       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3676       DONE;
3677     }
3680 (define_insn "zero_extendhisi2_and"
3681   [(set (match_operand:SI 0 "register_operand" "=r")
3682      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3683    (clobber (reg:CC FLAGS_REG))]
3684   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3685   "#"
3686   [(set_attr "type" "alu1")
3687    (set_attr "mode" "SI")])
3689 (define_split
3690   [(set (match_operand:SI 0 "register_operand" "")
3691         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3692    (clobber (reg:CC FLAGS_REG))]
3693   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3694    && optimize_function_for_speed_p (cfun)"
3695   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3696               (clobber (reg:CC FLAGS_REG))])]
3697   "")
3699 (define_insn "*zero_extendhisi2_movzwl"
3700   [(set (match_operand:SI 0 "register_operand" "=r")
3701      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3702   "!TARGET_ZERO_EXTEND_WITH_AND
3703    || optimize_function_for_size_p (cfun)"
3704   "movz{wl|x}\t{%1, %0|%0, %1}"
3705   [(set_attr "type" "imovx")
3706    (set_attr "mode" "SI")])
3708 (define_expand "zero_extendqihi2"
3709   [(parallel
3710     [(set (match_operand:HI 0 "register_operand" "")
3711        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3712      (clobber (reg:CC FLAGS_REG))])]
3713   ""
3714   "")
3716 (define_insn "*zero_extendqihi2_and"
3717   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3718      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3719    (clobber (reg:CC FLAGS_REG))]
3720   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3721   "#"
3722   [(set_attr "type" "alu1")
3723    (set_attr "mode" "HI")])
3725 (define_insn "*zero_extendqihi2_movzbw_and"
3726   [(set (match_operand:HI 0 "register_operand" "=r,r")
3727      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3728    (clobber (reg:CC FLAGS_REG))]
3729   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3730   "#"
3731   [(set_attr "type" "imovx,alu1")
3732    (set_attr "mode" "HI")])
3734 ; zero extend to SImode here to avoid partial register stalls
3735 (define_insn "*zero_extendqihi2_movzbl"
3736   [(set (match_operand:HI 0 "register_operand" "=r")
3737      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3738   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3739    && reload_completed"
3740   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3741   [(set_attr "type" "imovx")
3742    (set_attr "mode" "SI")])
3744 ;; For the movzbw case strip only the clobber
3745 (define_split
3746   [(set (match_operand:HI 0 "register_operand" "")
3747         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3748    (clobber (reg:CC FLAGS_REG))]
3749   "reload_completed
3750    && (!TARGET_ZERO_EXTEND_WITH_AND
3751        || optimize_function_for_size_p (cfun))
3752    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3753   [(set (match_operand:HI 0 "register_operand" "")
3754         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3756 ;; When source and destination does not overlap, clear destination
3757 ;; first and then do the movb
3758 (define_split
3759   [(set (match_operand:HI 0 "register_operand" "")
3760         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3761    (clobber (reg:CC FLAGS_REG))]
3762   "reload_completed
3763    && ANY_QI_REG_P (operands[0])
3764    && (TARGET_ZERO_EXTEND_WITH_AND
3765        && optimize_function_for_speed_p (cfun))
3766    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3767   [(set (match_dup 0) (const_int 0))
3768    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3769   "operands[2] = gen_lowpart (QImode, operands[0]);")
3771 ;; Rest is handled by single and.
3772 (define_split
3773   [(set (match_operand:HI 0 "register_operand" "")
3774         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3775    (clobber (reg:CC FLAGS_REG))]
3776   "reload_completed
3777    && true_regnum (operands[0]) == true_regnum (operands[1])"
3778   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3779               (clobber (reg:CC FLAGS_REG))])]
3780   "")
3782 (define_expand "zero_extendqisi2"
3783   [(parallel
3784     [(set (match_operand:SI 0 "register_operand" "")
3785        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3786      (clobber (reg:CC FLAGS_REG))])]
3787   ""
3788   "")
3790 (define_insn "*zero_extendqisi2_and"
3791   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3792      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3793    (clobber (reg:CC FLAGS_REG))]
3794   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3795   "#"
3796   [(set_attr "type" "alu1")
3797    (set_attr "mode" "SI")])
3799 (define_insn "*zero_extendqisi2_movzbw_and"
3800   [(set (match_operand:SI 0 "register_operand" "=r,r")
3801      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3802    (clobber (reg:CC FLAGS_REG))]
3803   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3804   "#"
3805   [(set_attr "type" "imovx,alu1")
3806    (set_attr "mode" "SI")])
3808 (define_insn "*zero_extendqisi2_movzbw"
3809   [(set (match_operand:SI 0 "register_operand" "=r")
3810      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3811   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3812    && reload_completed"
3813   "movz{bl|x}\t{%1, %0|%0, %1}"
3814   [(set_attr "type" "imovx")
3815    (set_attr "mode" "SI")])
3817 ;; For the movzbl case strip only the clobber
3818 (define_split
3819   [(set (match_operand:SI 0 "register_operand" "")
3820         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3821    (clobber (reg:CC FLAGS_REG))]
3822   "reload_completed
3823    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3824    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3825   [(set (match_dup 0)
3826         (zero_extend:SI (match_dup 1)))])
3828 ;; When source and destination does not overlap, clear destination
3829 ;; first and then do the movb
3830 (define_split
3831   [(set (match_operand:SI 0 "register_operand" "")
3832         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3833    (clobber (reg:CC FLAGS_REG))]
3834   "reload_completed
3835    && ANY_QI_REG_P (operands[0])
3836    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3837    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3838    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3839   [(set (match_dup 0) (const_int 0))
3840    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3841   "operands[2] = gen_lowpart (QImode, operands[0]);")
3843 ;; Rest is handled by single and.
3844 (define_split
3845   [(set (match_operand:SI 0 "register_operand" "")
3846         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3847    (clobber (reg:CC FLAGS_REG))]
3848   "reload_completed
3849    && true_regnum (operands[0]) == true_regnum (operands[1])"
3850   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3851               (clobber (reg:CC FLAGS_REG))])]
3852   "")
3854 ;; %%% Kill me once multi-word ops are sane.
3855 (define_expand "zero_extendsidi2"
3856   [(set (match_operand:DI 0 "register_operand" "")
3857      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3858   ""
3860   if (!TARGET_64BIT)
3861     {
3862       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3863       DONE;
3864     }
3867 (define_insn "zero_extendsidi2_32"
3868   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3869         (zero_extend:DI
3870          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3871    (clobber (reg:CC FLAGS_REG))]
3872   "!TARGET_64BIT"
3873   "@
3874    #
3875    #
3876    #
3877    movd\t{%1, %0|%0, %1}
3878    movd\t{%1, %0|%0, %1}
3879    %vmovd\t{%1, %0|%0, %1}
3880    %vmovd\t{%1, %0|%0, %1}"
3881   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3882    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3883    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3885 (define_insn "zero_extendsidi2_rex64"
3886   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3887      (zero_extend:DI
3888        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3889   "TARGET_64BIT"
3890   "@
3891    mov\t{%k1, %k0|%k0, %k1}
3892    #
3893    movd\t{%1, %0|%0, %1}
3894    movd\t{%1, %0|%0, %1}
3895    %vmovd\t{%1, %0|%0, %1}
3896    %vmovd\t{%1, %0|%0, %1}"
3897   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3898    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3899    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3901 (define_split
3902   [(set (match_operand:DI 0 "memory_operand" "")
3903      (zero_extend:DI (match_dup 0)))]
3904   "TARGET_64BIT"
3905   [(set (match_dup 4) (const_int 0))]
3906   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3908 (define_split
3909   [(set (match_operand:DI 0 "register_operand" "")
3910         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3911    (clobber (reg:CC FLAGS_REG))]
3912   "!TARGET_64BIT && reload_completed
3913    && true_regnum (operands[0]) == true_regnum (operands[1])"
3914   [(set (match_dup 4) (const_int 0))]
3915   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3917 (define_split
3918   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3919         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3920    (clobber (reg:CC FLAGS_REG))]
3921   "!TARGET_64BIT && reload_completed
3922    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3923   [(set (match_dup 3) (match_dup 1))
3924    (set (match_dup 4) (const_int 0))]
3925   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3927 (define_insn "zero_extendhidi2"
3928   [(set (match_operand:DI 0 "register_operand" "=r")
3929      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3930   "TARGET_64BIT"
3931   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3932   [(set_attr "type" "imovx")
3933    (set_attr "mode" "DI")])
3935 (define_insn "zero_extendqidi2"
3936   [(set (match_operand:DI 0 "register_operand" "=r")
3937      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3938   "TARGET_64BIT"
3939   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3940   [(set_attr "type" "imovx")
3941    (set_attr "mode" "DI")])
3943 ;; Sign extension instructions
3945 (define_expand "extendsidi2"
3946   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3947                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3948               (clobber (reg:CC FLAGS_REG))
3949               (clobber (match_scratch:SI 2 ""))])]
3950   ""
3952   if (TARGET_64BIT)
3953     {
3954       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3955       DONE;
3956     }
3959 (define_insn "*extendsidi2_1"
3960   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3961         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3962    (clobber (reg:CC FLAGS_REG))
3963    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3964   "!TARGET_64BIT"
3965   "#")
3967 (define_insn "extendsidi2_rex64"
3968   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3969         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3970   "TARGET_64BIT"
3971   "@
3972    {cltq|cdqe}
3973    movs{lq|x}\t{%1,%0|%0, %1}"
3974   [(set_attr "type" "imovx")
3975    (set_attr "mode" "DI")
3976    (set_attr "prefix_0f" "0")
3977    (set_attr "modrm" "0,1")])
3979 (define_insn "extendhidi2"
3980   [(set (match_operand:DI 0 "register_operand" "=r")
3981         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3982   "TARGET_64BIT"
3983   "movs{wq|x}\t{%1,%0|%0, %1}"
3984   [(set_attr "type" "imovx")
3985    (set_attr "mode" "DI")])
3987 (define_insn "extendqidi2"
3988   [(set (match_operand:DI 0 "register_operand" "=r")
3989         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3990   "TARGET_64BIT"
3991   "movs{bq|x}\t{%1,%0|%0, %1}"
3992    [(set_attr "type" "imovx")
3993     (set_attr "mode" "DI")])
3995 ;; Extend to memory case when source register does die.
3996 (define_split
3997   [(set (match_operand:DI 0 "memory_operand" "")
3998         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3999    (clobber (reg:CC FLAGS_REG))
4000    (clobber (match_operand:SI 2 "register_operand" ""))]
4001   "(reload_completed
4002     && dead_or_set_p (insn, operands[1])
4003     && !reg_mentioned_p (operands[1], operands[0]))"
4004   [(set (match_dup 3) (match_dup 1))
4005    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4006               (clobber (reg:CC FLAGS_REG))])
4007    (set (match_dup 4) (match_dup 1))]
4008   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4010 ;; Extend to memory case when source register does not die.
4011 (define_split
4012   [(set (match_operand:DI 0 "memory_operand" "")
4013         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4014    (clobber (reg:CC FLAGS_REG))
4015    (clobber (match_operand:SI 2 "register_operand" ""))]
4016   "reload_completed"
4017   [(const_int 0)]
4019   split_di (&operands[0], 1, &operands[3], &operands[4]);
4021   emit_move_insn (operands[3], operands[1]);
4023   /* Generate a cltd if possible and doing so it profitable.  */
4024   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4025       && true_regnum (operands[1]) == AX_REG
4026       && true_regnum (operands[2]) == DX_REG)
4027     {
4028       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4029     }
4030   else
4031     {
4032       emit_move_insn (operands[2], operands[1]);
4033       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4034     }
4035   emit_move_insn (operands[4], operands[2]);
4036   DONE;
4039 ;; Extend to register case.  Optimize case where source and destination
4040 ;; registers match and cases where we can use cltd.
4041 (define_split
4042   [(set (match_operand:DI 0 "register_operand" "")
4043         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4044    (clobber (reg:CC FLAGS_REG))
4045    (clobber (match_scratch:SI 2 ""))]
4046   "reload_completed"
4047   [(const_int 0)]
4049   split_di (&operands[0], 1, &operands[3], &operands[4]);
4051   if (true_regnum (operands[3]) != true_regnum (operands[1]))
4052     emit_move_insn (operands[3], operands[1]);
4054   /* Generate a cltd if possible and doing so it profitable.  */
4055   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4056       && true_regnum (operands[3]) == AX_REG)
4057     {
4058       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4059       DONE;
4060     }
4062   if (true_regnum (operands[4]) != true_regnum (operands[1]))
4063     emit_move_insn (operands[4], operands[1]);
4065   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4066   DONE;
4069 (define_insn "extendhisi2"
4070   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4071         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4072   ""
4074   switch (get_attr_prefix_0f (insn))
4075     {
4076     case 0:
4077       return "{cwtl|cwde}";
4078     default:
4079       return "movs{wl|x}\t{%1,%0|%0, %1}";
4080     }
4082   [(set_attr "type" "imovx")
4083    (set_attr "mode" "SI")
4084    (set (attr "prefix_0f")
4085      ;; movsx is short decodable while cwtl is vector decoded.
4086      (if_then_else (and (eq_attr "cpu" "!k6")
4087                         (eq_attr "alternative" "0"))
4088         (const_string "0")
4089         (const_string "1")))
4090    (set (attr "modrm")
4091      (if_then_else (eq_attr "prefix_0f" "0")
4092         (const_string "0")
4093         (const_string "1")))])
4095 (define_insn "*extendhisi2_zext"
4096   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4097         (zero_extend:DI
4098           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4099   "TARGET_64BIT"
4101   switch (get_attr_prefix_0f (insn))
4102     {
4103     case 0:
4104       return "{cwtl|cwde}";
4105     default:
4106       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
4107     }
4109   [(set_attr "type" "imovx")
4110    (set_attr "mode" "SI")
4111    (set (attr "prefix_0f")
4112      ;; movsx is short decodable while cwtl is vector decoded.
4113      (if_then_else (and (eq_attr "cpu" "!k6")
4114                         (eq_attr "alternative" "0"))
4115         (const_string "0")
4116         (const_string "1")))
4117    (set (attr "modrm")
4118      (if_then_else (eq_attr "prefix_0f" "0")
4119         (const_string "0")
4120         (const_string "1")))])
4122 (define_insn "extendqihi2"
4123   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4124         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4125   ""
4127   switch (get_attr_prefix_0f (insn))
4128     {
4129     case 0:
4130       return "{cbtw|cbw}";
4131     default:
4132       return "movs{bw|x}\t{%1,%0|%0, %1}";
4133     }
4135   [(set_attr "type" "imovx")
4136    (set_attr "mode" "HI")
4137    (set (attr "prefix_0f")
4138      ;; movsx is short decodable while cwtl is vector decoded.
4139      (if_then_else (and (eq_attr "cpu" "!k6")
4140                         (eq_attr "alternative" "0"))
4141         (const_string "0")
4142         (const_string "1")))
4143    (set (attr "modrm")
4144      (if_then_else (eq_attr "prefix_0f" "0")
4145         (const_string "0")
4146         (const_string "1")))])
4148 (define_insn "extendqisi2"
4149   [(set (match_operand:SI 0 "register_operand" "=r")
4150         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4151   ""
4152   "movs{bl|x}\t{%1,%0|%0, %1}"
4153    [(set_attr "type" "imovx")
4154     (set_attr "mode" "SI")])
4156 (define_insn "*extendqisi2_zext"
4157   [(set (match_operand:DI 0 "register_operand" "=r")
4158         (zero_extend:DI
4159           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4160   "TARGET_64BIT"
4161   "movs{bl|x}\t{%1,%k0|%k0, %1}"
4162    [(set_attr "type" "imovx")
4163     (set_attr "mode" "SI")])
4165 ;; Conversions between float and double.
4167 ;; These are all no-ops in the model used for the 80387.  So just
4168 ;; emit moves.
4170 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4171 (define_insn "*dummy_extendsfdf2"
4172   [(set (match_operand:DF 0 "push_operand" "=<")
4173         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4174   "0"
4175   "#")
4177 (define_split
4178   [(set (match_operand:DF 0 "push_operand" "")
4179         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4180   ""
4181   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4182    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4184 (define_insn "*dummy_extendsfxf2"
4185   [(set (match_operand:XF 0 "push_operand" "=<")
4186         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4187   "0"
4188   "#")
4190 (define_split
4191   [(set (match_operand:XF 0 "push_operand" "")
4192         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4193   ""
4194   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4195    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4196   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4198 (define_split
4199   [(set (match_operand:XF 0 "push_operand" "")
4200         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4201   ""
4202   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4203    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4204   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4206 (define_expand "extendsfdf2"
4207   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4208         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4209   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4211   /* ??? Needed for compress_float_constant since all fp constants
4212      are LEGITIMATE_CONSTANT_P.  */
4213   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4214     {
4215       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4216           && standard_80387_constant_p (operands[1]) > 0)
4217         {
4218           operands[1] = simplify_const_unary_operation
4219             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4220           emit_move_insn_1 (operands[0], operands[1]);
4221           DONE;
4222         }
4223       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4224     }
4227 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4228    cvtss2sd:
4229       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4230       cvtps2pd xmm2,xmm1
4231    We do the conversion post reload to avoid producing of 128bit spills
4232    that might lead to ICE on 32bit target.  The sequence unlikely combine
4233    anyway.  */
4234 (define_split
4235   [(set (match_operand:DF 0 "register_operand" "")
4236         (float_extend:DF
4237           (match_operand:SF 1 "nonimmediate_operand" "")))]
4238   "TARGET_USE_VECTOR_FP_CONVERTS
4239    && optimize_insn_for_speed_p ()
4240    && reload_completed && SSE_REG_P (operands[0])"
4241    [(set (match_dup 2)
4242          (float_extend:V2DF
4243            (vec_select:V2SF
4244              (match_dup 3)
4245              (parallel [(const_int 0) (const_int 1)]))))]
4247   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4248   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4249   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4250      Try to avoid move when unpacking can be done in source.  */
4251   if (REG_P (operands[1]))
4252     {
4253       /* If it is unsafe to overwrite upper half of source, we need
4254          to move to destination and unpack there.  */
4255       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4256            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4257           && true_regnum (operands[0]) != true_regnum (operands[1]))
4258         {
4259           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4260           emit_move_insn (tmp, operands[1]);
4261         }
4262       else
4263         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4264       emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4265     }
4266   else
4267     emit_insn (gen_vec_setv4sf_0 (operands[3],
4268                                   CONST0_RTX (V4SFmode), operands[1]));
4271 (define_insn "*extendsfdf2_mixed"
4272   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4273         (float_extend:DF
4274           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4275   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4277   switch (which_alternative)
4278     {
4279     case 0:
4280     case 1:
4281       return output_387_reg_move (insn, operands);
4283     case 2:
4284       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4286     default:
4287       gcc_unreachable ();
4288     }
4290   [(set_attr "type" "fmov,fmov,ssecvt")
4291    (set_attr "prefix" "orig,orig,maybe_vex")
4292    (set_attr "mode" "SF,XF,DF")])
4294 (define_insn "*extendsfdf2_sse"
4295   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4296         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4297   "TARGET_SSE2 && TARGET_SSE_MATH"
4298   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4299   [(set_attr "type" "ssecvt")
4300    (set_attr "prefix" "maybe_vex")
4301    (set_attr "mode" "DF")])
4303 (define_insn "*extendsfdf2_i387"
4304   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4305         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4306   "TARGET_80387"
4307   "* return output_387_reg_move (insn, operands);"
4308   [(set_attr "type" "fmov")
4309    (set_attr "mode" "SF,XF")])
4311 (define_expand "extend<mode>xf2"
4312   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4313         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4314   "TARGET_80387"
4316   /* ??? Needed for compress_float_constant since all fp constants
4317      are LEGITIMATE_CONSTANT_P.  */
4318   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4319     {
4320       if (standard_80387_constant_p (operands[1]) > 0)
4321         {
4322           operands[1] = simplify_const_unary_operation
4323             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4324           emit_move_insn_1 (operands[0], operands[1]);
4325           DONE;
4326         }
4327       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4328     }
4331 (define_insn "*extend<mode>xf2_i387"
4332   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4333         (float_extend:XF
4334           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4335   "TARGET_80387"
4336   "* return output_387_reg_move (insn, operands);"
4337   [(set_attr "type" "fmov")
4338    (set_attr "mode" "<MODE>,XF")])
4340 ;; %%% This seems bad bad news.
4341 ;; This cannot output into an f-reg because there is no way to be sure
4342 ;; of truncating in that case.  Otherwise this is just like a simple move
4343 ;; insn.  So we pretend we can output to a reg in order to get better
4344 ;; register preferencing, but we really use a stack slot.
4346 ;; Conversion from DFmode to SFmode.
4348 (define_expand "truncdfsf2"
4349   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4350         (float_truncate:SF
4351           (match_operand:DF 1 "nonimmediate_operand" "")))]
4352   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4354   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4355     ;
4356   else if (flag_unsafe_math_optimizations)
4357     ;
4358   else
4359     {
4360       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4361       rtx temp = assign_386_stack_local (SFmode, slot);
4362       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4363       DONE;
4364     }
4367 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4368    cvtsd2ss:
4369       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4370       cvtpd2ps xmm2,xmm1
4371    We do the conversion post reload to avoid producing of 128bit spills
4372    that might lead to ICE on 32bit target.  The sequence unlikely combine
4373    anyway.  */
4374 (define_split
4375   [(set (match_operand:SF 0 "register_operand" "")
4376         (float_truncate:SF
4377           (match_operand:DF 1 "nonimmediate_operand" "")))]
4378   "TARGET_USE_VECTOR_FP_CONVERTS
4379    && optimize_insn_for_speed_p ()
4380    && reload_completed && SSE_REG_P (operands[0])"
4381    [(set (match_dup 2)
4382          (vec_concat:V4SF
4383            (float_truncate:V2SF
4384              (match_dup 4))
4385            (match_dup 3)))]
4387   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4388   operands[3] = CONST0_RTX (V2SFmode);
4389   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4390   /* Use movsd for loading from memory, unpcklpd for registers.
4391      Try to avoid move when unpacking can be done in source, or SSE3
4392      movddup is available.  */
4393   if (REG_P (operands[1]))
4394     {
4395       if (!TARGET_SSE3
4396           && true_regnum (operands[0]) != true_regnum (operands[1])
4397           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4398               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4399         {
4400           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4401           emit_move_insn (tmp, operands[1]);
4402           operands[1] = tmp;
4403         }
4404       else if (!TARGET_SSE3)
4405         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4406       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4407     }
4408   else
4409     emit_insn (gen_sse2_loadlpd (operands[4],
4410                                  CONST0_RTX (V2DFmode), operands[1]));
4413 (define_expand "truncdfsf2_with_temp"
4414   [(parallel [(set (match_operand:SF 0 "" "")
4415                    (float_truncate:SF (match_operand:DF 1 "" "")))
4416               (clobber (match_operand:SF 2 "" ""))])]
4417   "")
4419 (define_insn "*truncdfsf_fast_mixed"
4420   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4421         (float_truncate:SF
4422           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4423   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4425   switch (which_alternative)
4426     {
4427     case 0:
4428       return output_387_reg_move (insn, operands);
4429     case 1:
4430       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4431     default:
4432       gcc_unreachable ();
4433     }
4435   [(set_attr "type" "fmov,ssecvt")
4436    (set_attr "prefix" "orig,maybe_vex")
4437    (set_attr "mode" "SF")])
4439 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4440 ;; because nothing we do here is unsafe.
4441 (define_insn "*truncdfsf_fast_sse"
4442   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4443         (float_truncate:SF
4444           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4445   "TARGET_SSE2 && TARGET_SSE_MATH"
4446   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4447   [(set_attr "type" "ssecvt")
4448    (set_attr "prefix" "maybe_vex")
4449    (set_attr "mode" "SF")])
4451 (define_insn "*truncdfsf_fast_i387"
4452   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4453         (float_truncate:SF
4454           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4455   "TARGET_80387 && flag_unsafe_math_optimizations"
4456   "* return output_387_reg_move (insn, operands);"
4457   [(set_attr "type" "fmov")
4458    (set_attr "mode" "SF")])
4460 (define_insn "*truncdfsf_mixed"
4461   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4462         (float_truncate:SF
4463           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4464    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4465   "TARGET_MIX_SSE_I387"
4467   switch (which_alternative)
4468     {
4469     case 0:
4470       return output_387_reg_move (insn, operands);
4471     case 1:
4472       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4474     default:
4475       return "#";
4476     }
4478   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4479    (set_attr "unit" "*,*,i387,i387,i387")
4480    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4481    (set_attr "mode" "SF")])
4483 (define_insn "*truncdfsf_i387"
4484   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4485         (float_truncate:SF
4486           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4487    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4488   "TARGET_80387"
4490   switch (which_alternative)
4491     {
4492     case 0:
4493       return output_387_reg_move (insn, operands);
4495     default:
4496       return "#";
4497     }
4499   [(set_attr "type" "fmov,multi,multi,multi")
4500    (set_attr "unit" "*,i387,i387,i387")
4501    (set_attr "mode" "SF")])
4503 (define_insn "*truncdfsf2_i387_1"
4504   [(set (match_operand:SF 0 "memory_operand" "=m")
4505         (float_truncate:SF
4506           (match_operand:DF 1 "register_operand" "f")))]
4507   "TARGET_80387
4508    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4509    && !TARGET_MIX_SSE_I387"
4510   "* return output_387_reg_move (insn, operands);"
4511   [(set_attr "type" "fmov")
4512    (set_attr "mode" "SF")])
4514 (define_split
4515   [(set (match_operand:SF 0 "register_operand" "")
4516         (float_truncate:SF
4517          (match_operand:DF 1 "fp_register_operand" "")))
4518    (clobber (match_operand 2 "" ""))]
4519   "reload_completed"
4520   [(set (match_dup 2) (match_dup 1))
4521    (set (match_dup 0) (match_dup 2))]
4523   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4526 ;; Conversion from XFmode to {SF,DF}mode
4528 (define_expand "truncxf<mode>2"
4529   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4530                    (float_truncate:MODEF
4531                      (match_operand:XF 1 "register_operand" "")))
4532               (clobber (match_dup 2))])]
4533   "TARGET_80387"
4535   if (flag_unsafe_math_optimizations)
4536     {
4537       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4538       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4539       if (reg != operands[0])
4540         emit_move_insn (operands[0], reg);
4541       DONE;
4542     }
4543   else
4544     {
4545       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4546       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4547     }
4550 (define_insn "*truncxfsf2_mixed"
4551   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4552         (float_truncate:SF
4553           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4554    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4555   "TARGET_80387"
4557   gcc_assert (!which_alternative);
4558   return output_387_reg_move (insn, operands);
4560   [(set_attr "type" "fmov,multi,multi,multi")
4561    (set_attr "unit" "*,i387,i387,i387")
4562    (set_attr "mode" "SF")])
4564 (define_insn "*truncxfdf2_mixed"
4565   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4566         (float_truncate:DF
4567           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4568    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4569   "TARGET_80387"
4571   gcc_assert (!which_alternative);
4572   return output_387_reg_move (insn, operands);
4574   [(set_attr "type" "fmov,multi,multi,multi")
4575    (set_attr "unit" "*,i387,i387,i387")
4576    (set_attr "mode" "DF")])
4578 (define_insn "truncxf<mode>2_i387_noop"
4579   [(set (match_operand:MODEF 0 "register_operand" "=f")
4580         (float_truncate:MODEF
4581           (match_operand:XF 1 "register_operand" "f")))]
4582   "TARGET_80387 && flag_unsafe_math_optimizations"
4583   "* return output_387_reg_move (insn, operands);"
4584   [(set_attr "type" "fmov")
4585    (set_attr "mode" "<MODE>")])
4587 (define_insn "*truncxf<mode>2_i387"
4588   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4589         (float_truncate:MODEF
4590           (match_operand:XF 1 "register_operand" "f")))]
4591   "TARGET_80387"
4592   "* return output_387_reg_move (insn, operands);"
4593   [(set_attr "type" "fmov")
4594    (set_attr "mode" "<MODE>")])
4596 (define_split
4597   [(set (match_operand:MODEF 0 "register_operand" "")
4598         (float_truncate:MODEF
4599           (match_operand:XF 1 "register_operand" "")))
4600    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4601   "TARGET_80387 && reload_completed"
4602   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4603    (set (match_dup 0) (match_dup 2))]
4604   "")
4606 (define_split
4607   [(set (match_operand:MODEF 0 "memory_operand" "")
4608         (float_truncate:MODEF
4609           (match_operand:XF 1 "register_operand" "")))
4610    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4611   "TARGET_80387"
4612   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4613   "")
4615 ;; Signed conversion to DImode.
4617 (define_expand "fix_truncxfdi2"
4618   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4619                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4620               (clobber (reg:CC FLAGS_REG))])]
4621   "TARGET_80387"
4623   if (TARGET_FISTTP)
4624    {
4625      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4626      DONE;
4627    }
4630 (define_expand "fix_trunc<mode>di2"
4631   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4632                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4633               (clobber (reg:CC FLAGS_REG))])]
4634   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4636   if (TARGET_FISTTP
4637       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4638    {
4639      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4640      DONE;
4641    }
4642   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4643    {
4644      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4645      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4646      if (out != operands[0])
4647         emit_move_insn (operands[0], out);
4648      DONE;
4649    }
4652 ;; Signed conversion to SImode.
4654 (define_expand "fix_truncxfsi2"
4655   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4656                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4657               (clobber (reg:CC FLAGS_REG))])]
4658   "TARGET_80387"
4660   if (TARGET_FISTTP)
4661    {
4662      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4663      DONE;
4664    }
4667 (define_expand "fix_trunc<mode>si2"
4668   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4669                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4670               (clobber (reg:CC FLAGS_REG))])]
4671   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4673   if (TARGET_FISTTP
4674       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4675    {
4676      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4677      DONE;
4678    }
4679   if (SSE_FLOAT_MODE_P (<MODE>mode))
4680    {
4681      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4682      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4683      if (out != operands[0])
4684         emit_move_insn (operands[0], out);
4685      DONE;
4686    }
4689 ;; Signed conversion to HImode.
4691 (define_expand "fix_trunc<mode>hi2"
4692   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4693                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4694               (clobber (reg:CC FLAGS_REG))])]
4695   "TARGET_80387
4696    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4698   if (TARGET_FISTTP)
4699    {
4700      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4701      DONE;
4702    }
4705 ;; Unsigned conversion to SImode.
4707 (define_expand "fixuns_trunc<mode>si2"
4708   [(parallel
4709     [(set (match_operand:SI 0 "register_operand" "")
4710           (unsigned_fix:SI
4711             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4712      (use (match_dup 2))
4713      (clobber (match_scratch:<ssevecmode> 3 ""))
4714      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4715   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4717   enum machine_mode mode = <MODE>mode;
4718   enum machine_mode vecmode = <ssevecmode>mode;
4719   REAL_VALUE_TYPE TWO31r;
4720   rtx two31;
4722   if (optimize_insn_for_size_p ())
4723     FAIL;
4725   real_ldexp (&TWO31r, &dconst1, 31);
4726   two31 = const_double_from_real_value (TWO31r, mode);
4727   two31 = ix86_build_const_vector (mode, true, two31);
4728   operands[2] = force_reg (vecmode, two31);
4731 (define_insn_and_split "*fixuns_trunc<mode>_1"
4732   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4733         (unsigned_fix:SI
4734           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4735    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4736    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4737    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4738   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4739    && optimize_function_for_speed_p (cfun)"
4740   "#"
4741   "&& reload_completed"
4742   [(const_int 0)]
4744   ix86_split_convert_uns_si_sse (operands);
4745   DONE;
4748 ;; Unsigned conversion to HImode.
4749 ;; Without these patterns, we'll try the unsigned SI conversion which
4750 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4752 (define_expand "fixuns_trunc<mode>hi2"
4753   [(set (match_dup 2)
4754         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4755    (set (match_operand:HI 0 "nonimmediate_operand" "")
4756         (subreg:HI (match_dup 2) 0))]
4757   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4758   "operands[2] = gen_reg_rtx (SImode);")
4760 ;; When SSE is available, it is always faster to use it!
4761 (define_insn "fix_trunc<mode>di_sse"
4762   [(set (match_operand:DI 0 "register_operand" "=r,r")
4763         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4764   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4765    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4766   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4767   [(set_attr "type" "sseicvt")
4768    (set_attr "prefix" "maybe_vex")
4769    (set_attr "mode" "<MODE>")
4770    (set_attr "athlon_decode" "double,vector")
4771    (set_attr "amdfam10_decode" "double,double")])
4773 (define_insn "fix_trunc<mode>si_sse"
4774   [(set (match_operand:SI 0 "register_operand" "=r,r")
4775         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4776   "SSE_FLOAT_MODE_P (<MODE>mode)
4777    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4778   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4779   [(set_attr "type" "sseicvt")
4780    (set_attr "prefix" "maybe_vex")
4781    (set_attr "mode" "<MODE>")
4782    (set_attr "athlon_decode" "double,vector")
4783    (set_attr "amdfam10_decode" "double,double")])
4785 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4786 (define_peephole2
4787   [(set (match_operand:MODEF 0 "register_operand" "")
4788         (match_operand:MODEF 1 "memory_operand" ""))
4789    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4790         (fix:SSEMODEI24 (match_dup 0)))]
4791   "TARGET_SHORTEN_X87_SSE
4792    && peep2_reg_dead_p (2, operands[0])"
4793   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4794   "")
4796 ;; Avoid vector decoded forms of the instruction.
4797 (define_peephole2
4798   [(match_scratch:DF 2 "Y2")
4799    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4800         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4801   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4802   [(set (match_dup 2) (match_dup 1))
4803    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4804   "")
4806 (define_peephole2
4807   [(match_scratch:SF 2 "x")
4808    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4809         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4810   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4811   [(set (match_dup 2) (match_dup 1))
4812    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4813   "")
4815 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4816   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4817         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4818   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4819    && TARGET_FISTTP
4820    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4821          && (TARGET_64BIT || <MODE>mode != DImode))
4822         && TARGET_SSE_MATH)
4823    && !(reload_completed || reload_in_progress)"
4824   "#"
4825   "&& 1"
4826   [(const_int 0)]
4828   if (memory_operand (operands[0], VOIDmode))
4829     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4830   else
4831     {
4832       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4833       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4834                                                             operands[1],
4835                                                             operands[2]));
4836     }
4837   DONE;
4839   [(set_attr "type" "fisttp")
4840    (set_attr "mode" "<MODE>")])
4842 (define_insn "fix_trunc<mode>_i387_fisttp"
4843   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4844         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4845    (clobber (match_scratch:XF 2 "=&1f"))]
4846   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4847    && TARGET_FISTTP
4848    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4849          && (TARGET_64BIT || <MODE>mode != DImode))
4850         && TARGET_SSE_MATH)"
4851   "* return output_fix_trunc (insn, operands, 1);"
4852   [(set_attr "type" "fisttp")
4853    (set_attr "mode" "<MODE>")])
4855 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4856   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4857         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4858    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4859    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4860   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4861    && TARGET_FISTTP
4862    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4863         && (TARGET_64BIT || <MODE>mode != DImode))
4864         && TARGET_SSE_MATH)"
4865   "#"
4866   [(set_attr "type" "fisttp")
4867    (set_attr "mode" "<MODE>")])
4869 (define_split
4870   [(set (match_operand:X87MODEI 0 "register_operand" "")
4871         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4872    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4873    (clobber (match_scratch 3 ""))]
4874   "reload_completed"
4875   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4876               (clobber (match_dup 3))])
4877    (set (match_dup 0) (match_dup 2))]
4878   "")
4880 (define_split
4881   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4882         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4883    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4884    (clobber (match_scratch 3 ""))]
4885   "reload_completed"
4886   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4887               (clobber (match_dup 3))])]
4888   "")
4890 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4891 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4892 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4893 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4894 ;; function in i386.c.
4895 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4896   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4897         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4898    (clobber (reg:CC FLAGS_REG))]
4899   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4900    && !TARGET_FISTTP
4901    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4902          && (TARGET_64BIT || <MODE>mode != DImode))
4903    && !(reload_completed || reload_in_progress)"
4904   "#"
4905   "&& 1"
4906   [(const_int 0)]
4908   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4910   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4911   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4912   if (memory_operand (operands[0], VOIDmode))
4913     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4914                                          operands[2], operands[3]));
4915   else
4916     {
4917       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4918       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4919                                                      operands[2], operands[3],
4920                                                      operands[4]));
4921     }
4922   DONE;
4924   [(set_attr "type" "fistp")
4925    (set_attr "i387_cw" "trunc")
4926    (set_attr "mode" "<MODE>")])
4928 (define_insn "fix_truncdi_i387"
4929   [(set (match_operand:DI 0 "memory_operand" "=m")
4930         (fix:DI (match_operand 1 "register_operand" "f")))
4931    (use (match_operand:HI 2 "memory_operand" "m"))
4932    (use (match_operand:HI 3 "memory_operand" "m"))
4933    (clobber (match_scratch:XF 4 "=&1f"))]
4934   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4935    && !TARGET_FISTTP
4936    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4937   "* return output_fix_trunc (insn, operands, 0);"
4938   [(set_attr "type" "fistp")
4939    (set_attr "i387_cw" "trunc")
4940    (set_attr "mode" "DI")])
4942 (define_insn "fix_truncdi_i387_with_temp"
4943   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4944         (fix:DI (match_operand 1 "register_operand" "f,f")))
4945    (use (match_operand:HI 2 "memory_operand" "m,m"))
4946    (use (match_operand:HI 3 "memory_operand" "m,m"))
4947    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4948    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4949   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4950    && !TARGET_FISTTP
4951    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4952   "#"
4953   [(set_attr "type" "fistp")
4954    (set_attr "i387_cw" "trunc")
4955    (set_attr "mode" "DI")])
4957 (define_split
4958   [(set (match_operand:DI 0 "register_operand" "")
4959         (fix:DI (match_operand 1 "register_operand" "")))
4960    (use (match_operand:HI 2 "memory_operand" ""))
4961    (use (match_operand:HI 3 "memory_operand" ""))
4962    (clobber (match_operand:DI 4 "memory_operand" ""))
4963    (clobber (match_scratch 5 ""))]
4964   "reload_completed"
4965   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4966               (use (match_dup 2))
4967               (use (match_dup 3))
4968               (clobber (match_dup 5))])
4969    (set (match_dup 0) (match_dup 4))]
4970   "")
4972 (define_split
4973   [(set (match_operand:DI 0 "memory_operand" "")
4974         (fix:DI (match_operand 1 "register_operand" "")))
4975    (use (match_operand:HI 2 "memory_operand" ""))
4976    (use (match_operand:HI 3 "memory_operand" ""))
4977    (clobber (match_operand:DI 4 "memory_operand" ""))
4978    (clobber (match_scratch 5 ""))]
4979   "reload_completed"
4980   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4981               (use (match_dup 2))
4982               (use (match_dup 3))
4983               (clobber (match_dup 5))])]
4984   "")
4986 (define_insn "fix_trunc<mode>_i387"
4987   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4988         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4989    (use (match_operand:HI 2 "memory_operand" "m"))
4990    (use (match_operand:HI 3 "memory_operand" "m"))]
4991   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4992    && !TARGET_FISTTP
4993    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4994   "* return output_fix_trunc (insn, operands, 0);"
4995   [(set_attr "type" "fistp")
4996    (set_attr "i387_cw" "trunc")
4997    (set_attr "mode" "<MODE>")])
4999 (define_insn "fix_trunc<mode>_i387_with_temp"
5000   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5001         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5002    (use (match_operand:HI 2 "memory_operand" "m,m"))
5003    (use (match_operand:HI 3 "memory_operand" "m,m"))
5004    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5005   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5006    && !TARGET_FISTTP
5007    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5008   "#"
5009   [(set_attr "type" "fistp")
5010    (set_attr "i387_cw" "trunc")
5011    (set_attr "mode" "<MODE>")])
5013 (define_split
5014   [(set (match_operand:X87MODEI12 0 "register_operand" "")
5015         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5016    (use (match_operand:HI 2 "memory_operand" ""))
5017    (use (match_operand:HI 3 "memory_operand" ""))
5018    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5019   "reload_completed"
5020   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5021               (use (match_dup 2))
5022               (use (match_dup 3))])
5023    (set (match_dup 0) (match_dup 4))]
5024   "")
5026 (define_split
5027   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5028         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5029    (use (match_operand:HI 2 "memory_operand" ""))
5030    (use (match_operand:HI 3 "memory_operand" ""))
5031    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5032   "reload_completed"
5033   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5034               (use (match_dup 2))
5035               (use (match_dup 3))])]
5036   "")
5038 (define_insn "x86_fnstcw_1"
5039   [(set (match_operand:HI 0 "memory_operand" "=m")
5040         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5041   "TARGET_80387"
5042   "fnstcw\t%0"
5043   [(set_attr "length" "2")
5044    (set_attr "mode" "HI")
5045    (set_attr "unit" "i387")])
5047 (define_insn "x86_fldcw_1"
5048   [(set (reg:HI FPCR_REG)
5049         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5050   "TARGET_80387"
5051   "fldcw\t%0"
5052   [(set_attr "length" "2")
5053    (set_attr "mode" "HI")
5054    (set_attr "unit" "i387")
5055    (set_attr "athlon_decode" "vector")
5056    (set_attr "amdfam10_decode" "vector")])
5058 ;; Conversion between fixed point and floating point.
5060 ;; Even though we only accept memory inputs, the backend _really_
5061 ;; wants to be able to do this between registers.
5063 (define_expand "floathi<mode>2"
5064   [(set (match_operand:X87MODEF 0 "register_operand" "")
5065         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5066   "TARGET_80387
5067    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5068        || TARGET_MIX_SSE_I387)"
5069   "")
5071 ;; Pre-reload splitter to add memory clobber to the pattern.
5072 (define_insn_and_split "*floathi<mode>2_1"
5073   [(set (match_operand:X87MODEF 0 "register_operand" "")
5074         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5075   "TARGET_80387
5076    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5077        || TARGET_MIX_SSE_I387)
5078    && !(reload_completed || reload_in_progress)"
5079   "#"
5080   "&& 1"
5081   [(parallel [(set (match_dup 0)
5082               (float:X87MODEF (match_dup 1)))
5083    (clobber (match_dup 2))])]
5084   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5086 (define_insn "*floathi<mode>2_i387_with_temp"
5087   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5088         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5089   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5090   "TARGET_80387
5091    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5092        || TARGET_MIX_SSE_I387)"
5093   "#"
5094   [(set_attr "type" "fmov,multi")
5095    (set_attr "mode" "<MODE>")
5096    (set_attr "unit" "*,i387")
5097    (set_attr "fp_int_src" "true")])
5099 (define_insn "*floathi<mode>2_i387"
5100   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5101         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5102   "TARGET_80387
5103    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5104        || TARGET_MIX_SSE_I387)"
5105   "fild%z1\t%1"
5106   [(set_attr "type" "fmov")
5107    (set_attr "mode" "<MODE>")
5108    (set_attr "fp_int_src" "true")])
5110 (define_split
5111   [(set (match_operand:X87MODEF 0 "register_operand" "")
5112         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5113    (clobber (match_operand:HI 2 "memory_operand" ""))]
5114   "TARGET_80387
5115    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5116        || TARGET_MIX_SSE_I387)
5117    && reload_completed"
5118   [(set (match_dup 2) (match_dup 1))
5119    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5120   "")
5122 (define_split
5123   [(set (match_operand:X87MODEF 0 "register_operand" "")
5124         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5125    (clobber (match_operand:HI 2 "memory_operand" ""))]
5126    "TARGET_80387
5127     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5128         || TARGET_MIX_SSE_I387)
5129     && reload_completed"
5130   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5131   "")
5133 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5134   [(set (match_operand:X87MODEF 0 "register_operand" "")
5135         (float:X87MODEF
5136           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5137   "TARGET_80387
5138    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5139        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5140   "")
5142 ;; Pre-reload splitter to add memory clobber to the pattern.
5143 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5144   [(set (match_operand:X87MODEF 0 "register_operand" "")
5145         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5146   "((TARGET_80387
5147      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5148            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5149          || TARGET_MIX_SSE_I387))
5150     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5151         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5152         && ((<SSEMODEI24:MODE>mode == SImode
5153              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5154              && optimize_function_for_speed_p (cfun)
5155              && flag_trapping_math)
5156             || !(TARGET_INTER_UNIT_CONVERSIONS
5157                  || optimize_function_for_size_p (cfun)))))
5158    && !(reload_completed || reload_in_progress)"
5159   "#"
5160   "&& 1"
5161   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5162               (clobber (match_dup 2))])]
5164   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5166   /* Avoid store forwarding (partial memory) stall penalty
5167      by passing DImode value through XMM registers.  */
5168   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5169       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5170       && optimize_function_for_speed_p (cfun))
5171     {
5172       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5173                                                             operands[1],
5174                                                             operands[2]));
5175       DONE;
5176     }
5179 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5180   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5181         (float:MODEF
5182           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5183    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5184   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5185    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5186   "#"
5187   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5188    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5189    (set_attr "unit" "*,i387,*,*,*")
5190    (set_attr "athlon_decode" "*,*,double,direct,double")
5191    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5192    (set_attr "fp_int_src" "true")])
5194 (define_insn "*floatsi<mode>2_vector_mixed"
5195   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5196         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5197   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5198    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5199   "@
5200    fild%z1\t%1
5201    #"
5202   [(set_attr "type" "fmov,sseicvt")
5203    (set_attr "mode" "<MODE>,<ssevecmode>")
5204    (set_attr "unit" "i387,*")
5205    (set_attr "athlon_decode" "*,direct")
5206    (set_attr "amdfam10_decode" "*,double")
5207    (set_attr "fp_int_src" "true")])
5209 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5210   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5211         (float:MODEF
5212           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5213   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5214   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5215    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5216   "#"
5217   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5218    (set_attr "mode" "<MODEF:MODE>")
5219    (set_attr "unit" "*,i387,*,*")
5220    (set_attr "athlon_decode" "*,*,double,direct")
5221    (set_attr "amdfam10_decode" "*,*,vector,double")
5222    (set_attr "fp_int_src" "true")])
5224 (define_split
5225   [(set (match_operand:MODEF 0 "register_operand" "")
5226         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5227    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5228   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5229    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5230    && TARGET_INTER_UNIT_CONVERSIONS
5231    && reload_completed
5232    && (SSE_REG_P (operands[0])
5233        || (GET_CODE (operands[0]) == SUBREG
5234            && SSE_REG_P (operands[0])))"
5235   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5236   "")
5238 (define_split
5239   [(set (match_operand:MODEF 0 "register_operand" "")
5240         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5241    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5242   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5243    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5244    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5245    && reload_completed
5246    && (SSE_REG_P (operands[0])
5247        || (GET_CODE (operands[0]) == SUBREG
5248            && SSE_REG_P (operands[0])))"
5249   [(set (match_dup 2) (match_dup 1))
5250    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5251   "")
5253 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5254   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5255         (float:MODEF
5256           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5257   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5258    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5259    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5260   "@
5261    fild%z1\t%1
5262    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5263    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5264   [(set_attr "type" "fmov,sseicvt,sseicvt")
5265    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5266    (set_attr "mode" "<MODEF:MODE>")
5267    (set_attr "unit" "i387,*,*")
5268    (set_attr "athlon_decode" "*,double,direct")
5269    (set_attr "amdfam10_decode" "*,vector,double")
5270    (set_attr "fp_int_src" "true")])
5272 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5273   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5274         (float:MODEF
5275           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5276   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5277    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5278    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5279   "@
5280    fild%z1\t%1
5281    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5282   [(set_attr "type" "fmov,sseicvt")
5283    (set_attr "prefix" "orig,maybe_vex")
5284    (set_attr "mode" "<MODEF:MODE>")
5285    (set_attr "athlon_decode" "*,direct")
5286    (set_attr "amdfam10_decode" "*,double")
5287    (set_attr "fp_int_src" "true")])
5289 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5290   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5291         (float:MODEF
5292           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5293    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5294   "TARGET_SSE2 && TARGET_SSE_MATH
5295    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5296   "#"
5297   [(set_attr "type" "sseicvt")
5298    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5299    (set_attr "athlon_decode" "double,direct,double")
5300    (set_attr "amdfam10_decode" "vector,double,double")
5301    (set_attr "fp_int_src" "true")])
5303 (define_insn "*floatsi<mode>2_vector_sse"
5304   [(set (match_operand:MODEF 0 "register_operand" "=x")
5305         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5306   "TARGET_SSE2 && TARGET_SSE_MATH
5307    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5308   "#"
5309   [(set_attr "type" "sseicvt")
5310    (set_attr "mode" "<MODE>")
5311    (set_attr "athlon_decode" "direct")
5312    (set_attr "amdfam10_decode" "double")
5313    (set_attr "fp_int_src" "true")])
5315 (define_split
5316   [(set (match_operand:MODEF 0 "register_operand" "")
5317         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5318    (clobber (match_operand:SI 2 "memory_operand" ""))]
5319   "TARGET_SSE2 && TARGET_SSE_MATH
5320    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5321    && reload_completed
5322    && (SSE_REG_P (operands[0])
5323        || (GET_CODE (operands[0]) == SUBREG
5324            && SSE_REG_P (operands[0])))"
5325   [(const_int 0)]
5327   rtx op1 = operands[1];
5329   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5330                                      <MODE>mode, 0);
5331   if (GET_CODE (op1) == SUBREG)
5332     op1 = SUBREG_REG (op1);
5334   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5335     {
5336       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5337       emit_insn (gen_sse2_loadld (operands[4],
5338                                   CONST0_RTX (V4SImode), operands[1]));
5339     }
5340   /* We can ignore possible trapping value in the
5341      high part of SSE register for non-trapping math. */
5342   else if (SSE_REG_P (op1) && !flag_trapping_math)
5343     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5344   else
5345     {
5346       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5347       emit_move_insn (operands[2], operands[1]);
5348       emit_insn (gen_sse2_loadld (operands[4],
5349                                   CONST0_RTX (V4SImode), operands[2]));
5350     }
5351   emit_insn
5352     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5353   DONE;
5356 (define_split
5357   [(set (match_operand:MODEF 0 "register_operand" "")
5358         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5359    (clobber (match_operand:SI 2 "memory_operand" ""))]
5360   "TARGET_SSE2 && TARGET_SSE_MATH
5361    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5362    && reload_completed
5363    && (SSE_REG_P (operands[0])
5364        || (GET_CODE (operands[0]) == SUBREG
5365            && SSE_REG_P (operands[0])))"
5366   [(const_int 0)]
5368   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5369                                      <MODE>mode, 0);
5370   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5372   emit_insn (gen_sse2_loadld (operands[4],
5373                               CONST0_RTX (V4SImode), operands[1]));
5374   emit_insn
5375     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5376   DONE;
5379 (define_split
5380   [(set (match_operand:MODEF 0 "register_operand" "")
5381         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5382   "TARGET_SSE2 && TARGET_SSE_MATH
5383    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5384    && reload_completed
5385    && (SSE_REG_P (operands[0])
5386        || (GET_CODE (operands[0]) == SUBREG
5387            && SSE_REG_P (operands[0])))"
5388   [(const_int 0)]
5390   rtx op1 = operands[1];
5392   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5393                                      <MODE>mode, 0);
5394   if (GET_CODE (op1) == SUBREG)
5395     op1 = SUBREG_REG (op1);
5397   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5398     {
5399       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5400       emit_insn (gen_sse2_loadld (operands[4],
5401                                   CONST0_RTX (V4SImode), operands[1]));
5402     }
5403   /* We can ignore possible trapping value in the
5404      high part of SSE register for non-trapping math. */
5405   else if (SSE_REG_P (op1) && !flag_trapping_math)
5406     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5407   else
5408     gcc_unreachable ();
5409   emit_insn
5410     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5411   DONE;
5414 (define_split
5415   [(set (match_operand:MODEF 0 "register_operand" "")
5416         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5417   "TARGET_SSE2 && TARGET_SSE_MATH
5418    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5419    && reload_completed
5420    && (SSE_REG_P (operands[0])
5421        || (GET_CODE (operands[0]) == SUBREG
5422            && SSE_REG_P (operands[0])))"
5423   [(const_int 0)]
5425   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5426                                      <MODE>mode, 0);
5427   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5429   emit_insn (gen_sse2_loadld (operands[4],
5430                               CONST0_RTX (V4SImode), operands[1]));
5431   emit_insn
5432     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5433   DONE;
5436 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5437   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5438         (float:MODEF
5439           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5440   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5441   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5442    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5443   "#"
5444   [(set_attr "type" "sseicvt")
5445    (set_attr "mode" "<MODEF:MODE>")
5446    (set_attr "athlon_decode" "double,direct")
5447    (set_attr "amdfam10_decode" "vector,double")
5448    (set_attr "fp_int_src" "true")])
5450 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5451   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5452         (float:MODEF
5453           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5454   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5455    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5456    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5457   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5458   [(set_attr "type" "sseicvt")
5459    (set_attr "prefix" "maybe_vex")
5460    (set_attr "mode" "<MODEF:MODE>")
5461    (set_attr "athlon_decode" "double,direct")
5462    (set_attr "amdfam10_decode" "vector,double")
5463    (set_attr "fp_int_src" "true")])
5465 (define_split
5466   [(set (match_operand:MODEF 0 "register_operand" "")
5467         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5468    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5469   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5470    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5471    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5472    && reload_completed
5473    && (SSE_REG_P (operands[0])
5474        || (GET_CODE (operands[0]) == SUBREG
5475            && SSE_REG_P (operands[0])))"
5476   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5477   "")
5479 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5480   [(set (match_operand:MODEF 0 "register_operand" "=x")
5481         (float:MODEF
5482           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5483   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5484    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5485    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5486   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5487   [(set_attr "type" "sseicvt")
5488    (set_attr "prefix" "maybe_vex")
5489    (set_attr "mode" "<MODEF:MODE>")
5490    (set_attr "athlon_decode" "direct")
5491    (set_attr "amdfam10_decode" "double")
5492    (set_attr "fp_int_src" "true")])
5494 (define_split
5495   [(set (match_operand:MODEF 0 "register_operand" "")
5496         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5497    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5498   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5499    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5500    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5501    && reload_completed
5502    && (SSE_REG_P (operands[0])
5503        || (GET_CODE (operands[0]) == SUBREG
5504            && SSE_REG_P (operands[0])))"
5505   [(set (match_dup 2) (match_dup 1))
5506    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5507   "")
5509 (define_split
5510   [(set (match_operand:MODEF 0 "register_operand" "")
5511         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5512    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5513   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5514    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5515    && reload_completed
5516    && (SSE_REG_P (operands[0])
5517        || (GET_CODE (operands[0]) == SUBREG
5518            && SSE_REG_P (operands[0])))"
5519   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5520   "")
5522 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5523   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5524         (float:X87MODEF
5525           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5526   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5527   "TARGET_80387"
5528   "@
5529    fild%z1\t%1
5530    #"
5531   [(set_attr "type" "fmov,multi")
5532    (set_attr "mode" "<X87MODEF:MODE>")
5533    (set_attr "unit" "*,i387")
5534    (set_attr "fp_int_src" "true")])
5536 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5537   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5538         (float:X87MODEF
5539           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5540   "TARGET_80387"
5541   "fild%z1\t%1"
5542   [(set_attr "type" "fmov")
5543    (set_attr "mode" "<X87MODEF:MODE>")
5544    (set_attr "fp_int_src" "true")])
5546 (define_split
5547   [(set (match_operand:X87MODEF 0 "register_operand" "")
5548         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5549    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5550   "TARGET_80387
5551    && reload_completed
5552    && FP_REG_P (operands[0])"
5553   [(set (match_dup 2) (match_dup 1))
5554    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5555   "")
5557 (define_split
5558   [(set (match_operand:X87MODEF 0 "register_operand" "")
5559         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5560    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5561   "TARGET_80387
5562    && reload_completed
5563    && FP_REG_P (operands[0])"
5564   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5565   "")
5567 ;; Avoid store forwarding (partial memory) stall penalty
5568 ;; by passing DImode value through XMM registers.  */
5570 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5571   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5572         (float:X87MODEF
5573           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5574    (clobber (match_scratch:V4SI 3 "=X,x"))
5575    (clobber (match_scratch:V4SI 4 "=X,x"))
5576    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5577   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5578    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5579   "#"
5580   [(set_attr "type" "multi")
5581    (set_attr "mode" "<X87MODEF:MODE>")
5582    (set_attr "unit" "i387")
5583    (set_attr "fp_int_src" "true")])
5585 (define_split
5586   [(set (match_operand:X87MODEF 0 "register_operand" "")
5587         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5588    (clobber (match_scratch:V4SI 3 ""))
5589    (clobber (match_scratch:V4SI 4 ""))
5590    (clobber (match_operand:DI 2 "memory_operand" ""))]
5591   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5592    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5593    && reload_completed
5594    && FP_REG_P (operands[0])"
5595   [(set (match_dup 2) (match_dup 3))
5596    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5598   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5599      Assemble the 64-bit DImode value in an xmm register.  */
5600   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5601                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5602   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5603                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5604   emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5606   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5609 (define_split
5610   [(set (match_operand:X87MODEF 0 "register_operand" "")
5611         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5612    (clobber (match_scratch:V4SI 3 ""))
5613    (clobber (match_scratch:V4SI 4 ""))
5614    (clobber (match_operand:DI 2 "memory_operand" ""))]
5615   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5616    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5617    && reload_completed
5618    && FP_REG_P (operands[0])"
5619   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5620   "")
5622 ;; Avoid store forwarding (partial memory) stall penalty by extending
5623 ;; SImode value to DImode through XMM register instead of pushing two
5624 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5625 ;; targets benefit from this optimization. Also note that fild
5626 ;; loads from memory only.
5628 (define_insn "*floatunssi<mode>2_1"
5629   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5630         (unsigned_float:X87MODEF
5631           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5632    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5633    (clobber (match_scratch:SI 3 "=X,x"))]
5634   "!TARGET_64BIT
5635    && TARGET_80387 && TARGET_SSE"
5636   "#"
5637   [(set_attr "type" "multi")
5638    (set_attr "mode" "<MODE>")])
5640 (define_split
5641   [(set (match_operand:X87MODEF 0 "register_operand" "")
5642         (unsigned_float:X87MODEF
5643           (match_operand:SI 1 "register_operand" "")))
5644    (clobber (match_operand:DI 2 "memory_operand" ""))
5645    (clobber (match_scratch:SI 3 ""))]
5646   "!TARGET_64BIT
5647    && TARGET_80387 && TARGET_SSE
5648    && reload_completed"
5649   [(set (match_dup 2) (match_dup 1))
5650    (set (match_dup 0)
5651         (float:X87MODEF (match_dup 2)))]
5652   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5654 (define_split
5655   [(set (match_operand:X87MODEF 0 "register_operand" "")
5656         (unsigned_float:X87MODEF
5657           (match_operand:SI 1 "memory_operand" "")))
5658    (clobber (match_operand:DI 2 "memory_operand" ""))
5659    (clobber (match_scratch:SI 3 ""))]
5660   "!TARGET_64BIT
5661    && TARGET_80387 && TARGET_SSE
5662    && reload_completed"
5663   [(set (match_dup 2) (match_dup 3))
5664    (set (match_dup 0)
5665         (float:X87MODEF (match_dup 2)))]
5667   emit_move_insn (operands[3], operands[1]);
5668   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5671 (define_expand "floatunssi<mode>2"
5672   [(parallel
5673      [(set (match_operand:X87MODEF 0 "register_operand" "")
5674            (unsigned_float:X87MODEF
5675              (match_operand:SI 1 "nonimmediate_operand" "")))
5676       (clobber (match_dup 2))
5677       (clobber (match_scratch:SI 3 ""))])]
5678   "!TARGET_64BIT
5679    && ((TARGET_80387 && TARGET_SSE)
5680        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5682   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5683     {
5684       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5685       DONE;
5686     }
5687   else
5688     {
5689       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5690       operands[2] = assign_386_stack_local (DImode, slot);
5691     }
5694 (define_expand "floatunsdisf2"
5695   [(use (match_operand:SF 0 "register_operand" ""))
5696    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5697   "TARGET_64BIT && TARGET_SSE_MATH"
5698   "x86_emit_floatuns (operands); DONE;")
5700 (define_expand "floatunsdidf2"
5701   [(use (match_operand:DF 0 "register_operand" ""))
5702    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5703   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5704    && TARGET_SSE2 && TARGET_SSE_MATH"
5706   if (TARGET_64BIT)
5707     x86_emit_floatuns (operands);
5708   else
5709     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5710   DONE;
5713 ;; Add instructions
5715 ;; %%% splits for addditi3
5717 (define_expand "addti3"
5718   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5719         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5720                  (match_operand:TI 2 "x86_64_general_operand" "")))]
5721   "TARGET_64BIT"
5722   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5724 (define_insn "*addti3_1"
5725   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5726         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5727                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5728    (clobber (reg:CC FLAGS_REG))]
5729   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5730   "#")
5732 (define_split
5733   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5734         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5735                  (match_operand:TI 2 "x86_64_general_operand" "")))
5736    (clobber (reg:CC FLAGS_REG))]
5737   "TARGET_64BIT && reload_completed"
5738   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5739                                           UNSPEC_ADD_CARRY))
5740               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5741    (parallel [(set (match_dup 3)
5742                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5743                                      (match_dup 4))
5744                             (match_dup 5)))
5745               (clobber (reg:CC FLAGS_REG))])]
5746   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5748 ;; %%% splits for addsidi3
5749 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5750 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5751 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5753 (define_expand "adddi3"
5754   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5755         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5756                  (match_operand:DI 2 "x86_64_general_operand" "")))]
5757   ""
5758   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5760 (define_insn "*adddi3_1"
5761   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5762         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5763                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5764    (clobber (reg:CC FLAGS_REG))]
5765   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5766   "#")
5768 (define_split
5769   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5770         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5771                  (match_operand:DI 2 "general_operand" "")))
5772    (clobber (reg:CC FLAGS_REG))]
5773   "!TARGET_64BIT && reload_completed"
5774   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5775                                           UNSPEC_ADD_CARRY))
5776               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5777    (parallel [(set (match_dup 3)
5778                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5779                                      (match_dup 4))
5780                             (match_dup 5)))
5781               (clobber (reg:CC FLAGS_REG))])]
5782   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5784 (define_insn "adddi3_carry_rex64"
5785   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5786           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5787                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5788                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5789    (clobber (reg:CC FLAGS_REG))]
5790   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5791   "adc{q}\t{%2, %0|%0, %2}"
5792   [(set_attr "type" "alu")
5793    (set_attr "pent_pair" "pu")
5794    (set_attr "mode" "DI")])
5796 (define_insn "*adddi3_cc_rex64"
5797   [(set (reg:CC FLAGS_REG)
5798         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5799                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5800                    UNSPEC_ADD_CARRY))
5801    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5802         (plus:DI (match_dup 1) (match_dup 2)))]
5803   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5804   "add{q}\t{%2, %0|%0, %2}"
5805   [(set_attr "type" "alu")
5806    (set_attr "mode" "DI")])
5808 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
5809   [(set (reg:CCC FLAGS_REG)
5810         (compare:CCC
5811             (plusminus:SWI
5812                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5813                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5814             (match_dup 1)))
5815    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5816         (plusminus:SWI (match_dup 1) (match_dup 2)))]
5817   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5818   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
5819   [(set_attr "type" "alu")
5820    (set_attr "mode" "<MODE>")])
5822 (define_insn "*add<mode>3_cconly_overflow"
5823   [(set (reg:CCC FLAGS_REG)
5824         (compare:CCC
5825                 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5826                           (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5827                 (match_dup 1)))
5828    (clobber (match_scratch:SWI 0 "=<r>"))]
5829   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5830   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5831   [(set_attr "type" "alu")
5832    (set_attr "mode" "<MODE>")])
5834 (define_insn "*sub<mode>3_cconly_overflow"
5835   [(set (reg:CCC FLAGS_REG)
5836         (compare:CCC
5837              (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5838                         (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5839              (match_dup 0)))]
5840   ""
5841   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5842   [(set_attr "type" "icmp")
5843    (set_attr "mode" "<MODE>")])
5845 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
5846   [(set (reg:CCC FLAGS_REG)
5847         (compare:CCC
5848             (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5849                           (match_operand:SI 2 "general_operand" "g"))
5850             (match_dup 1)))
5851    (set (match_operand:DI 0 "register_operand" "=r")
5852         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5853   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5854   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
5855   [(set_attr "type" "alu")
5856    (set_attr "mode" "SI")])
5858 (define_insn "addqi3_carry"
5859   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5860           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5861                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5862                    (match_operand:QI 2 "general_operand" "qn,qm")))
5863    (clobber (reg:CC FLAGS_REG))]
5864   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5865   "adc{b}\t{%2, %0|%0, %2}"
5866   [(set_attr "type" "alu")
5867    (set_attr "pent_pair" "pu")
5868    (set_attr "mode" "QI")])
5870 (define_insn "addhi3_carry"
5871   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5872           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5873                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5874                    (match_operand:HI 2 "general_operand" "rn,rm")))
5875    (clobber (reg:CC FLAGS_REG))]
5876   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5877   "adc{w}\t{%2, %0|%0, %2}"
5878   [(set_attr "type" "alu")
5879    (set_attr "pent_pair" "pu")
5880    (set_attr "mode" "HI")])
5882 (define_insn "addsi3_carry"
5883   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5884           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5885                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5886                    (match_operand:SI 2 "general_operand" "ri,rm")))
5887    (clobber (reg:CC FLAGS_REG))]
5888   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5889   "adc{l}\t{%2, %0|%0, %2}"
5890   [(set_attr "type" "alu")
5891    (set_attr "pent_pair" "pu")
5892    (set_attr "mode" "SI")])
5894 (define_insn "*addsi3_carry_zext"
5895   [(set (match_operand:DI 0 "register_operand" "=r")
5896           (zero_extend:DI
5897             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5898                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5899                      (match_operand:SI 2 "general_operand" "g"))))
5900    (clobber (reg:CC FLAGS_REG))]
5901   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5902   "adc{l}\t{%2, %k0|%k0, %2}"
5903   [(set_attr "type" "alu")
5904    (set_attr "pent_pair" "pu")
5905    (set_attr "mode" "SI")])
5907 (define_insn "*addsi3_cc"
5908   [(set (reg:CC FLAGS_REG)
5909         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5910                     (match_operand:SI 2 "general_operand" "ri,rm")]
5911                    UNSPEC_ADD_CARRY))
5912    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5913         (plus:SI (match_dup 1) (match_dup 2)))]
5914   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5915   "add{l}\t{%2, %0|%0, %2}"
5916   [(set_attr "type" "alu")
5917    (set_attr "mode" "SI")])
5919 (define_insn "addqi3_cc"
5920   [(set (reg:CC FLAGS_REG)
5921         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5922                     (match_operand:QI 2 "general_operand" "qn,qm")]
5923                    UNSPEC_ADD_CARRY))
5924    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5925         (plus:QI (match_dup 1) (match_dup 2)))]
5926   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5927   "add{b}\t{%2, %0|%0, %2}"
5928   [(set_attr "type" "alu")
5929    (set_attr "mode" "QI")])
5931 (define_expand "addsi3"
5932   [(set (match_operand:SI 0 "nonimmediate_operand" "")
5933         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5934                  (match_operand:SI 2 "general_operand" "")))]
5935   ""
5936   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5938 (define_insn "*lea_1"
5939   [(set (match_operand:SI 0 "register_operand" "=r")
5940         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5941   "!TARGET_64BIT"
5942   "lea{l}\t{%a1, %0|%0, %a1}"
5943   [(set_attr "type" "lea")
5944    (set_attr "mode" "SI")])
5946 (define_insn "*lea_1_rex64"
5947   [(set (match_operand:SI 0 "register_operand" "=r")
5948         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5949   "TARGET_64BIT"
5950   "lea{l}\t{%a1, %0|%0, %a1}"
5951   [(set_attr "type" "lea")
5952    (set_attr "mode" "SI")])
5954 (define_insn "*lea_1_zext"
5955   [(set (match_operand:DI 0 "register_operand" "=r")
5956         (zero_extend:DI
5957          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5958   "TARGET_64BIT"
5959   "lea{l}\t{%a1, %k0|%k0, %a1}"
5960   [(set_attr "type" "lea")
5961    (set_attr "mode" "SI")])
5963 (define_insn "*lea_2_rex64"
5964   [(set (match_operand:DI 0 "register_operand" "=r")
5965         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5966   "TARGET_64BIT"
5967   "lea{q}\t{%a1, %0|%0, %a1}"
5968   [(set_attr "type" "lea")
5969    (set_attr "mode" "DI")])
5971 ;; The lea patterns for non-Pmodes needs to be matched by several
5972 ;; insns converted to real lea by splitters.
5974 (define_insn_and_split "*lea_general_1"
5975   [(set (match_operand 0 "register_operand" "=r")
5976         (plus (plus (match_operand 1 "index_register_operand" "l")
5977                     (match_operand 2 "register_operand" "r"))
5978               (match_operand 3 "immediate_operand" "i")))]
5979   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5980     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5981    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5982    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5983    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5984    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5985        || GET_MODE (operands[3]) == VOIDmode)"
5986   "#"
5987   "&& reload_completed"
5988   [(const_int 0)]
5990   rtx pat;
5991   operands[0] = gen_lowpart (SImode, operands[0]);
5992   operands[1] = gen_lowpart (Pmode, operands[1]);
5993   operands[2] = gen_lowpart (Pmode, operands[2]);
5994   operands[3] = gen_lowpart (Pmode, operands[3]);
5995   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5996                       operands[3]);
5997   if (Pmode != SImode)
5998     pat = gen_rtx_SUBREG (SImode, pat, 0);
5999   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6000   DONE;
6002   [(set_attr "type" "lea")
6003    (set_attr "mode" "SI")])
6005 (define_insn_and_split "*lea_general_1_zext"
6006   [(set (match_operand:DI 0 "register_operand" "=r")
6007         (zero_extend:DI
6008           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
6009                             (match_operand:SI 2 "register_operand" "r"))
6010                    (match_operand:SI 3 "immediate_operand" "i"))))]
6011   "TARGET_64BIT"
6012   "#"
6013   "&& reload_completed"
6014   [(set (match_dup 0)
6015         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6016                                                      (match_dup 2))
6017                                             (match_dup 3)) 0)))]
6019   operands[1] = gen_lowpart (Pmode, operands[1]);
6020   operands[2] = gen_lowpart (Pmode, operands[2]);
6021   operands[3] = gen_lowpart (Pmode, operands[3]);
6023   [(set_attr "type" "lea")
6024    (set_attr "mode" "SI")])
6026 (define_insn_and_split "*lea_general_2"
6027   [(set (match_operand 0 "register_operand" "=r")
6028         (plus (mult (match_operand 1 "index_register_operand" "l")
6029                     (match_operand 2 "const248_operand" "i"))
6030               (match_operand 3 "nonmemory_operand" "ri")))]
6031   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6032     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6033    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6034    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6035    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6036        || GET_MODE (operands[3]) == VOIDmode)"
6037   "#"
6038   "&& reload_completed"
6039   [(const_int 0)]
6041   rtx pat;
6042   operands[0] = gen_lowpart (SImode, operands[0]);
6043   operands[1] = gen_lowpart (Pmode, operands[1]);
6044   operands[3] = gen_lowpart (Pmode, operands[3]);
6045   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6046                       operands[3]);
6047   if (Pmode != SImode)
6048     pat = gen_rtx_SUBREG (SImode, pat, 0);
6049   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6050   DONE;
6052   [(set_attr "type" "lea")
6053    (set_attr "mode" "SI")])
6055 (define_insn_and_split "*lea_general_2_zext"
6056   [(set (match_operand:DI 0 "register_operand" "=r")
6057         (zero_extend:DI
6058           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
6059                             (match_operand:SI 2 "const248_operand" "n"))
6060                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6061   "TARGET_64BIT"
6062   "#"
6063   "&& reload_completed"
6064   [(set (match_dup 0)
6065         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6066                                                      (match_dup 2))
6067                                             (match_dup 3)) 0)))]
6069   operands[1] = gen_lowpart (Pmode, operands[1]);
6070   operands[3] = gen_lowpart (Pmode, operands[3]);
6072   [(set_attr "type" "lea")
6073    (set_attr "mode" "SI")])
6075 (define_insn_and_split "*lea_general_3"
6076   [(set (match_operand 0 "register_operand" "=r")
6077         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6078                           (match_operand 2 "const248_operand" "i"))
6079                     (match_operand 3 "register_operand" "r"))
6080               (match_operand 4 "immediate_operand" "i")))]
6081   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6082     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6083    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6084    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6085    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6086   "#"
6087   "&& reload_completed"
6088   [(const_int 0)]
6090   rtx pat;
6091   operands[0] = gen_lowpart (SImode, operands[0]);
6092   operands[1] = gen_lowpart (Pmode, operands[1]);
6093   operands[3] = gen_lowpart (Pmode, operands[3]);
6094   operands[4] = gen_lowpart (Pmode, operands[4]);
6095   pat = gen_rtx_PLUS (Pmode,
6096                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6097                                                          operands[2]),
6098                                     operands[3]),
6099                       operands[4]);
6100   if (Pmode != SImode)
6101     pat = gen_rtx_SUBREG (SImode, pat, 0);
6102   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6103   DONE;
6105   [(set_attr "type" "lea")
6106    (set_attr "mode" "SI")])
6108 (define_insn_and_split "*lea_general_3_zext"
6109   [(set (match_operand:DI 0 "register_operand" "=r")
6110         (zero_extend:DI
6111           (plus:SI (plus:SI (mult:SI
6112                               (match_operand:SI 1 "index_register_operand" "l")
6113                               (match_operand:SI 2 "const248_operand" "n"))
6114                             (match_operand:SI 3 "register_operand" "r"))
6115                    (match_operand:SI 4 "immediate_operand" "i"))))]
6116   "TARGET_64BIT"
6117   "#"
6118   "&& reload_completed"
6119   [(set (match_dup 0)
6120         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6121                                                               (match_dup 2))
6122                                                      (match_dup 3))
6123                                             (match_dup 4)) 0)))]
6125   operands[1] = gen_lowpart (Pmode, operands[1]);
6126   operands[3] = gen_lowpart (Pmode, operands[3]);
6127   operands[4] = gen_lowpart (Pmode, operands[4]);
6129   [(set_attr "type" "lea")
6130    (set_attr "mode" "SI")])
6132 (define_insn "*adddi_1_rex64"
6133   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
6134         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
6135                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
6136    (clobber (reg:CC FLAGS_REG))]
6137   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6139   switch (get_attr_type (insn))
6140     {
6141     case TYPE_LEA:
6142       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6143       return "lea{q}\t{%a2, %0|%0, %a2}";
6145     case TYPE_INCDEC:
6146       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6147       if (operands[2] == const1_rtx)
6148         return "inc{q}\t%0";
6149       else
6150         {
6151           gcc_assert (operands[2] == constm1_rtx);
6152           return "dec{q}\t%0";
6153         }
6155     default:
6156       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6158       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6159          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6160       if (CONST_INT_P (operands[2])
6161           /* Avoid overflows.  */
6162           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6163           && (INTVAL (operands[2]) == 128
6164               || (INTVAL (operands[2]) < 0
6165                   && INTVAL (operands[2]) != -128)))
6166         {
6167           operands[2] = GEN_INT (-INTVAL (operands[2]));
6168           return "sub{q}\t{%2, %0|%0, %2}";
6169         }
6170       return "add{q}\t{%2, %0|%0, %2}";
6171     }
6173   [(set (attr "type")
6174      (cond [(eq_attr "alternative" "2")
6175               (const_string "lea")
6176             ; Current assemblers are broken and do not allow @GOTOFF in
6177             ; ought but a memory context.
6178             (match_operand:DI 2 "pic_symbolic_operand" "")
6179               (const_string "lea")
6180             (match_operand:DI 2 "incdec_operand" "")
6181               (const_string "incdec")
6182            ]
6183            (const_string "alu")))
6184    (set_attr "mode" "DI")])
6186 ;; Convert lea to the lea pattern to avoid flags dependency.
6187 (define_split
6188   [(set (match_operand:DI 0 "register_operand" "")
6189         (plus:DI (match_operand:DI 1 "register_operand" "")
6190                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6191    (clobber (reg:CC FLAGS_REG))]
6192   "TARGET_64BIT && reload_completed
6193    && true_regnum (operands[0]) != true_regnum (operands[1])"
6194   [(set (match_dup 0)
6195         (plus:DI (match_dup 1)
6196                  (match_dup 2)))]
6197   "")
6199 (define_insn "*adddi_2_rex64"
6200   [(set (reg FLAGS_REG)
6201         (compare
6202           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6203                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
6204           (const_int 0)))
6205    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
6206         (plus:DI (match_dup 1) (match_dup 2)))]
6207   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6208    && ix86_binary_operator_ok (PLUS, DImode, operands)
6209    /* Current assemblers are broken and do not allow @GOTOFF in
6210       ought but a memory context.  */
6211    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6213   switch (get_attr_type (insn))
6214     {
6215     case TYPE_INCDEC:
6216       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6217       if (operands[2] == const1_rtx)
6218         return "inc{q}\t%0";
6219       else
6220         {
6221           gcc_assert (operands[2] == constm1_rtx);
6222           return "dec{q}\t%0";
6223         }
6225     default:
6226       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6227       /* ???? We ought to handle there the 32bit case too
6228          - do we need new constraint?  */
6229       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6230          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6231       if (CONST_INT_P (operands[2])
6232           /* Avoid overflows.  */
6233           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6234           && (INTVAL (operands[2]) == 128
6235               || (INTVAL (operands[2]) < 0
6236                   && INTVAL (operands[2]) != -128)))
6237         {
6238           operands[2] = GEN_INT (-INTVAL (operands[2]));
6239           return "sub{q}\t{%2, %0|%0, %2}";
6240         }
6241       return "add{q}\t{%2, %0|%0, %2}";
6242     }
6244   [(set (attr "type")
6245      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6246         (const_string "incdec")
6247         (const_string "alu")))
6248    (set_attr "mode" "DI")])
6250 (define_insn "*adddi_3_rex64"
6251   [(set (reg FLAGS_REG)
6252         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6253                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
6254    (clobber (match_scratch:DI 0 "=r"))]
6255   "TARGET_64BIT
6256    && ix86_match_ccmode (insn, CCZmode)
6257    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6258    /* Current assemblers are broken and do not allow @GOTOFF in
6259       ought but a memory context.  */
6260    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6262   switch (get_attr_type (insn))
6263     {
6264     case TYPE_INCDEC:
6265       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6266       if (operands[2] == const1_rtx)
6267         return "inc{q}\t%0";
6268       else
6269         {
6270           gcc_assert (operands[2] == constm1_rtx);
6271           return "dec{q}\t%0";
6272         }
6274     default:
6275       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6276       /* ???? We ought to handle there the 32bit case too
6277          - do we need new constraint?  */
6278       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6279          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6280       if (CONST_INT_P (operands[2])
6281           /* Avoid overflows.  */
6282           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6283           && (INTVAL (operands[2]) == 128
6284               || (INTVAL (operands[2]) < 0
6285                   && INTVAL (operands[2]) != -128)))
6286         {
6287           operands[2] = GEN_INT (-INTVAL (operands[2]));
6288           return "sub{q}\t{%2, %0|%0, %2}";
6289         }
6290       return "add{q}\t{%2, %0|%0, %2}";
6291     }
6293   [(set (attr "type")
6294      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6295         (const_string "incdec")
6296         (const_string "alu")))
6297    (set_attr "mode" "DI")])
6299 ; For comparisons against 1, -1 and 128, we may generate better code
6300 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6301 ; is matched then.  We can't accept general immediate, because for
6302 ; case of overflows,  the result is messed up.
6303 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6304 ; when negated.
6305 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6306 ; only for comparisons not depending on it.
6307 (define_insn "*adddi_4_rex64"
6308   [(set (reg FLAGS_REG)
6309         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6310                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6311    (clobber (match_scratch:DI 0 "=rm"))]
6312   "TARGET_64BIT
6313    &&  ix86_match_ccmode (insn, CCGCmode)"
6315   switch (get_attr_type (insn))
6316     {
6317     case TYPE_INCDEC:
6318       if (operands[2] == constm1_rtx)
6319         return "inc{q}\t%0";
6320       else
6321         {
6322           gcc_assert (operands[2] == const1_rtx);
6323           return "dec{q}\t%0";
6324         }
6326     default:
6327       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6328       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6329          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6330       if ((INTVAL (operands[2]) == -128
6331            || (INTVAL (operands[2]) > 0
6332                && INTVAL (operands[2]) != 128))
6333           /* Avoid overflows.  */
6334           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6335         return "sub{q}\t{%2, %0|%0, %2}";
6336       operands[2] = GEN_INT (-INTVAL (operands[2]));
6337       return "add{q}\t{%2, %0|%0, %2}";
6338     }
6340   [(set (attr "type")
6341      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6342         (const_string "incdec")
6343         (const_string "alu")))
6344    (set_attr "mode" "DI")])
6346 (define_insn "*adddi_5_rex64"
6347   [(set (reg FLAGS_REG)
6348         (compare
6349           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6350                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
6351           (const_int 0)))
6352    (clobber (match_scratch:DI 0 "=r"))]
6353   "TARGET_64BIT
6354    && ix86_match_ccmode (insn, CCGOCmode)
6355    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6356    /* Current assemblers are broken and do not allow @GOTOFF in
6357       ought but a memory context.  */
6358    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6360   switch (get_attr_type (insn))
6361     {
6362     case TYPE_INCDEC:
6363       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6364       if (operands[2] == const1_rtx)
6365         return "inc{q}\t%0";
6366       else
6367         {
6368           gcc_assert (operands[2] == constm1_rtx);
6369           return "dec{q}\t%0";
6370         }
6372     default:
6373       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6374       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6375          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6376       if (CONST_INT_P (operands[2])
6377           /* Avoid overflows.  */
6378           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6379           && (INTVAL (operands[2]) == 128
6380               || (INTVAL (operands[2]) < 0
6381                   && INTVAL (operands[2]) != -128)))
6382         {
6383           operands[2] = GEN_INT (-INTVAL (operands[2]));
6384           return "sub{q}\t{%2, %0|%0, %2}";
6385         }
6386       return "add{q}\t{%2, %0|%0, %2}";
6387     }
6389   [(set (attr "type")
6390      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6391         (const_string "incdec")
6392         (const_string "alu")))
6393    (set_attr "mode" "DI")])
6396 (define_insn "*addsi_1"
6397   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6398         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6399                  (match_operand:SI 2 "general_operand" "g,ri,li")))
6400    (clobber (reg:CC FLAGS_REG))]
6401   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6403   switch (get_attr_type (insn))
6404     {
6405     case TYPE_LEA:
6406       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6407       return "lea{l}\t{%a2, %0|%0, %a2}";
6409     case TYPE_INCDEC:
6410       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6411       if (operands[2] == const1_rtx)
6412         return "inc{l}\t%0";
6413       else
6414         {
6415           gcc_assert (operands[2] == constm1_rtx);
6416           return "dec{l}\t%0";
6417         }
6419     default:
6420       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6422       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6423          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6424       if (CONST_INT_P (operands[2])
6425           && (INTVAL (operands[2]) == 128
6426               || (INTVAL (operands[2]) < 0
6427                   && INTVAL (operands[2]) != -128)))
6428         {
6429           operands[2] = GEN_INT (-INTVAL (operands[2]));
6430           return "sub{l}\t{%2, %0|%0, %2}";
6431         }
6432       return "add{l}\t{%2, %0|%0, %2}";
6433     }
6435   [(set (attr "type")
6436      (cond [(eq_attr "alternative" "2")
6437               (const_string "lea")
6438             ; Current assemblers are broken and do not allow @GOTOFF in
6439             ; ought but a memory context.
6440             (match_operand:SI 2 "pic_symbolic_operand" "")
6441               (const_string "lea")
6442             (match_operand:SI 2 "incdec_operand" "")
6443               (const_string "incdec")
6444            ]
6445            (const_string "alu")))
6446    (set_attr "mode" "SI")])
6448 ;; Convert lea to the lea pattern to avoid flags dependency.
6449 (define_split
6450   [(set (match_operand 0 "register_operand" "")
6451         (plus (match_operand 1 "register_operand" "")
6452               (match_operand 2 "nonmemory_operand" "")))
6453    (clobber (reg:CC FLAGS_REG))]
6454   "reload_completed
6455    && true_regnum (operands[0]) != true_regnum (operands[1])"
6456   [(const_int 0)]
6458   rtx pat;
6459   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6460      may confuse gen_lowpart.  */
6461   if (GET_MODE (operands[0]) != Pmode)
6462     {
6463       operands[1] = gen_lowpart (Pmode, operands[1]);
6464       operands[2] = gen_lowpart (Pmode, operands[2]);
6465     }
6466   operands[0] = gen_lowpart (SImode, operands[0]);
6467   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6468   if (Pmode != SImode)
6469     pat = gen_rtx_SUBREG (SImode, pat, 0);
6470   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6471   DONE;
6474 ;; It may seem that nonimmediate operand is proper one for operand 1.
6475 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6476 ;; we take care in ix86_binary_operator_ok to not allow two memory
6477 ;; operands so proper swapping will be done in reload.  This allow
6478 ;; patterns constructed from addsi_1 to match.
6479 (define_insn "addsi_1_zext"
6480   [(set (match_operand:DI 0 "register_operand" "=r,r")
6481         (zero_extend:DI
6482           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6483                    (match_operand:SI 2 "general_operand" "g,li"))))
6484    (clobber (reg:CC FLAGS_REG))]
6485   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6487   switch (get_attr_type (insn))
6488     {
6489     case TYPE_LEA:
6490       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6491       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6493     case TYPE_INCDEC:
6494       if (operands[2] == const1_rtx)
6495         return "inc{l}\t%k0";
6496       else
6497         {
6498           gcc_assert (operands[2] == constm1_rtx);
6499           return "dec{l}\t%k0";
6500         }
6502     default:
6503       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6504          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6505       if (CONST_INT_P (operands[2])
6506           && (INTVAL (operands[2]) == 128
6507               || (INTVAL (operands[2]) < 0
6508                   && INTVAL (operands[2]) != -128)))
6509         {
6510           operands[2] = GEN_INT (-INTVAL (operands[2]));
6511           return "sub{l}\t{%2, %k0|%k0, %2}";
6512         }
6513       return "add{l}\t{%2, %k0|%k0, %2}";
6514     }
6516   [(set (attr "type")
6517      (cond [(eq_attr "alternative" "1")
6518               (const_string "lea")
6519             ; Current assemblers are broken and do not allow @GOTOFF in
6520             ; ought but a memory context.
6521             (match_operand:SI 2 "pic_symbolic_operand" "")
6522               (const_string "lea")
6523             (match_operand:SI 2 "incdec_operand" "")
6524               (const_string "incdec")
6525            ]
6526            (const_string "alu")))
6527    (set_attr "mode" "SI")])
6529 ;; Convert lea to the lea pattern to avoid flags dependency.
6530 (define_split
6531   [(set (match_operand:DI 0 "register_operand" "")
6532         (zero_extend:DI
6533           (plus:SI (match_operand:SI 1 "register_operand" "")
6534                    (match_operand:SI 2 "nonmemory_operand" ""))))
6535    (clobber (reg:CC FLAGS_REG))]
6536   "TARGET_64BIT && reload_completed
6537    && true_regnum (operands[0]) != true_regnum (operands[1])"
6538   [(set (match_dup 0)
6539         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6541   operands[1] = gen_lowpart (Pmode, operands[1]);
6542   operands[2] = gen_lowpart (Pmode, operands[2]);
6545 (define_insn "*addsi_2"
6546   [(set (reg FLAGS_REG)
6547         (compare
6548           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6549                    (match_operand:SI 2 "general_operand" "g,ri"))
6550           (const_int 0)))
6551    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6552         (plus:SI (match_dup 1) (match_dup 2)))]
6553   "ix86_match_ccmode (insn, CCGOCmode)
6554    && ix86_binary_operator_ok (PLUS, SImode, operands)
6555    /* Current assemblers are broken and do not allow @GOTOFF in
6556       ought but a memory context.  */
6557    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6559   switch (get_attr_type (insn))
6560     {
6561     case TYPE_INCDEC:
6562       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6563       if (operands[2] == const1_rtx)
6564         return "inc{l}\t%0";
6565       else
6566         {
6567           gcc_assert (operands[2] == constm1_rtx);
6568           return "dec{l}\t%0";
6569         }
6571     default:
6572       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6573       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6574          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6575       if (CONST_INT_P (operands[2])
6576           && (INTVAL (operands[2]) == 128
6577               || (INTVAL (operands[2]) < 0
6578                   && INTVAL (operands[2]) != -128)))
6579         {
6580           operands[2] = GEN_INT (-INTVAL (operands[2]));
6581           return "sub{l}\t{%2, %0|%0, %2}";
6582         }
6583       return "add{l}\t{%2, %0|%0, %2}";
6584     }
6586   [(set (attr "type")
6587      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6588         (const_string "incdec")
6589         (const_string "alu")))
6590    (set_attr "mode" "SI")])
6592 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6593 (define_insn "*addsi_2_zext"
6594   [(set (reg FLAGS_REG)
6595         (compare
6596           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6597                    (match_operand:SI 2 "general_operand" "g"))
6598           (const_int 0)))
6599    (set (match_operand:DI 0 "register_operand" "=r")
6600         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6601   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6602    && ix86_binary_operator_ok (PLUS, SImode, operands)
6603    /* Current assemblers are broken and do not allow @GOTOFF in
6604       ought but a memory context.  */
6605    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6607   switch (get_attr_type (insn))
6608     {
6609     case TYPE_INCDEC:
6610       if (operands[2] == const1_rtx)
6611         return "inc{l}\t%k0";
6612       else
6613         {
6614           gcc_assert (operands[2] == constm1_rtx);
6615           return "dec{l}\t%k0";
6616         }
6618     default:
6619       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6620          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6621       if (CONST_INT_P (operands[2])
6622           && (INTVAL (operands[2]) == 128
6623               || (INTVAL (operands[2]) < 0
6624                   && INTVAL (operands[2]) != -128)))
6625         {
6626           operands[2] = GEN_INT (-INTVAL (operands[2]));
6627           return "sub{l}\t{%2, %k0|%k0, %2}";
6628         }
6629       return "add{l}\t{%2, %k0|%k0, %2}";
6630     }
6632   [(set (attr "type")
6633      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6634         (const_string "incdec")
6635         (const_string "alu")))
6636    (set_attr "mode" "SI")])
6638 (define_insn "*addsi_3"
6639   [(set (reg FLAGS_REG)
6640         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6641                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6642    (clobber (match_scratch:SI 0 "=r"))]
6643   "ix86_match_ccmode (insn, CCZmode)
6644    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6645    /* Current assemblers are broken and do not allow @GOTOFF in
6646       ought but a memory context.  */
6647    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6649   switch (get_attr_type (insn))
6650     {
6651     case TYPE_INCDEC:
6652       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6653       if (operands[2] == const1_rtx)
6654         return "inc{l}\t%0";
6655       else
6656         {
6657           gcc_assert (operands[2] == constm1_rtx);
6658           return "dec{l}\t%0";
6659         }
6661     default:
6662       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6663       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6664          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6665       if (CONST_INT_P (operands[2])
6666           && (INTVAL (operands[2]) == 128
6667               || (INTVAL (operands[2]) < 0
6668                   && INTVAL (operands[2]) != -128)))
6669         {
6670           operands[2] = GEN_INT (-INTVAL (operands[2]));
6671           return "sub{l}\t{%2, %0|%0, %2}";
6672         }
6673       return "add{l}\t{%2, %0|%0, %2}";
6674     }
6676   [(set (attr "type")
6677      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6678         (const_string "incdec")
6679         (const_string "alu")))
6680    (set_attr "mode" "SI")])
6682 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6683 (define_insn "*addsi_3_zext"
6684   [(set (reg FLAGS_REG)
6685         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6686                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6687    (set (match_operand:DI 0 "register_operand" "=r")
6688         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6689   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6690    && ix86_binary_operator_ok (PLUS, SImode, operands)
6691    /* Current assemblers are broken and do not allow @GOTOFF in
6692       ought but a memory context.  */
6693    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6695   switch (get_attr_type (insn))
6696     {
6697     case TYPE_INCDEC:
6698       if (operands[2] == const1_rtx)
6699         return "inc{l}\t%k0";
6700       else
6701         {
6702           gcc_assert (operands[2] == constm1_rtx);
6703           return "dec{l}\t%k0";
6704         }
6706     default:
6707       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6708          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6709       if (CONST_INT_P (operands[2])
6710           && (INTVAL (operands[2]) == 128
6711               || (INTVAL (operands[2]) < 0
6712                   && INTVAL (operands[2]) != -128)))
6713         {
6714           operands[2] = GEN_INT (-INTVAL (operands[2]));
6715           return "sub{l}\t{%2, %k0|%k0, %2}";
6716         }
6717       return "add{l}\t{%2, %k0|%k0, %2}";
6718     }
6720   [(set (attr "type")
6721      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6722         (const_string "incdec")
6723         (const_string "alu")))
6724    (set_attr "mode" "SI")])
6726 ; For comparisons against 1, -1 and 128, we may generate better code
6727 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6728 ; is matched then.  We can't accept general immediate, because for
6729 ; case of overflows,  the result is messed up.
6730 ; This pattern also don't hold of 0x80000000, since the value overflows
6731 ; when negated.
6732 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6733 ; only for comparisons not depending on it.
6734 (define_insn "*addsi_4"
6735   [(set (reg FLAGS_REG)
6736         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6737                  (match_operand:SI 2 "const_int_operand" "n")))
6738    (clobber (match_scratch:SI 0 "=rm"))]
6739   "ix86_match_ccmode (insn, CCGCmode)
6740    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6742   switch (get_attr_type (insn))
6743     {
6744     case TYPE_INCDEC:
6745       if (operands[2] == constm1_rtx)
6746         return "inc{l}\t%0";
6747       else
6748         {
6749           gcc_assert (operands[2] == const1_rtx);
6750           return "dec{l}\t%0";
6751         }
6753     default:
6754       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6755       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6756          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6757       if ((INTVAL (operands[2]) == -128
6758            || (INTVAL (operands[2]) > 0
6759                && INTVAL (operands[2]) != 128)))
6760         return "sub{l}\t{%2, %0|%0, %2}";
6761       operands[2] = GEN_INT (-INTVAL (operands[2]));
6762       return "add{l}\t{%2, %0|%0, %2}";
6763     }
6765   [(set (attr "type")
6766      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6767         (const_string "incdec")
6768         (const_string "alu")))
6769    (set_attr "mode" "SI")])
6771 (define_insn "*addsi_5"
6772   [(set (reg FLAGS_REG)
6773         (compare
6774           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6775                    (match_operand:SI 2 "general_operand" "g"))
6776           (const_int 0)))
6777    (clobber (match_scratch:SI 0 "=r"))]
6778   "ix86_match_ccmode (insn, CCGOCmode)
6779    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6780    /* Current assemblers are broken and do not allow @GOTOFF in
6781       ought but a memory context.  */
6782    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6784   switch (get_attr_type (insn))
6785     {
6786     case TYPE_INCDEC:
6787       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6788       if (operands[2] == const1_rtx)
6789         return "inc{l}\t%0";
6790       else
6791         {
6792           gcc_assert (operands[2] == constm1_rtx);
6793           return "dec{l}\t%0";
6794         }
6796     default:
6797       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6798       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6799          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6800       if (CONST_INT_P (operands[2])
6801           && (INTVAL (operands[2]) == 128
6802               || (INTVAL (operands[2]) < 0
6803                   && INTVAL (operands[2]) != -128)))
6804         {
6805           operands[2] = GEN_INT (-INTVAL (operands[2]));
6806           return "sub{l}\t{%2, %0|%0, %2}";
6807         }
6808       return "add{l}\t{%2, %0|%0, %2}";
6809     }
6811   [(set (attr "type")
6812      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6813         (const_string "incdec")
6814         (const_string "alu")))
6815    (set_attr "mode" "SI")])
6817 (define_expand "addhi3"
6818   [(set (match_operand:HI 0 "nonimmediate_operand" "")
6819         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6820                  (match_operand:HI 2 "general_operand" "")))]
6821   "TARGET_HIMODE_MATH"
6822   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6824 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6825 ;; type optimizations enabled by define-splits.  This is not important
6826 ;; for PII, and in fact harmful because of partial register stalls.
6828 (define_insn "*addhi_1_lea"
6829   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6830         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6831                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6832    (clobber (reg:CC FLAGS_REG))]
6833   "!TARGET_PARTIAL_REG_STALL
6834    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6836   switch (get_attr_type (insn))
6837     {
6838     case TYPE_LEA:
6839       return "#";
6840     case TYPE_INCDEC:
6841       if (operands[2] == const1_rtx)
6842         return "inc{w}\t%0";
6843       else
6844         {
6845           gcc_assert (operands[2] == constm1_rtx);
6846           return "dec{w}\t%0";
6847         }
6849     default:
6850       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6851          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6852       if (CONST_INT_P (operands[2])
6853           && (INTVAL (operands[2]) == 128
6854               || (INTVAL (operands[2]) < 0
6855                   && INTVAL (operands[2]) != -128)))
6856         {
6857           operands[2] = GEN_INT (-INTVAL (operands[2]));
6858           return "sub{w}\t{%2, %0|%0, %2}";
6859         }
6860       return "add{w}\t{%2, %0|%0, %2}";
6861     }
6863   [(set (attr "type")
6864      (if_then_else (eq_attr "alternative" "2")
6865         (const_string "lea")
6866         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6867            (const_string "incdec")
6868            (const_string "alu"))))
6869    (set_attr "mode" "HI,HI,SI")])
6871 (define_insn "*addhi_1"
6872   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6873         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6874                  (match_operand:HI 2 "general_operand" "rn,rm")))
6875    (clobber (reg:CC FLAGS_REG))]
6876   "TARGET_PARTIAL_REG_STALL
6877    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6879   switch (get_attr_type (insn))
6880     {
6881     case TYPE_INCDEC:
6882       if (operands[2] == const1_rtx)
6883         return "inc{w}\t%0";
6884       else
6885         {
6886           gcc_assert (operands[2] == constm1_rtx);
6887           return "dec{w}\t%0";
6888         }
6890     default:
6891       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6892          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6893       if (CONST_INT_P (operands[2])
6894           && (INTVAL (operands[2]) == 128
6895               || (INTVAL (operands[2]) < 0
6896                   && INTVAL (operands[2]) != -128)))
6897         {
6898           operands[2] = GEN_INT (-INTVAL (operands[2]));
6899           return "sub{w}\t{%2, %0|%0, %2}";
6900         }
6901       return "add{w}\t{%2, %0|%0, %2}";
6902     }
6904   [(set (attr "type")
6905      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6906         (const_string "incdec")
6907         (const_string "alu")))
6908    (set_attr "mode" "HI")])
6910 (define_insn "*addhi_2"
6911   [(set (reg FLAGS_REG)
6912         (compare
6913           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6914                    (match_operand:HI 2 "general_operand" "rmn,rn"))
6915           (const_int 0)))
6916    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6917         (plus:HI (match_dup 1) (match_dup 2)))]
6918   "ix86_match_ccmode (insn, CCGOCmode)
6919    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6921   switch (get_attr_type (insn))
6922     {
6923     case TYPE_INCDEC:
6924       if (operands[2] == const1_rtx)
6925         return "inc{w}\t%0";
6926       else
6927         {
6928           gcc_assert (operands[2] == constm1_rtx);
6929           return "dec{w}\t%0";
6930         }
6932     default:
6933       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6934          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6935       if (CONST_INT_P (operands[2])
6936           && (INTVAL (operands[2]) == 128
6937               || (INTVAL (operands[2]) < 0
6938                   && INTVAL (operands[2]) != -128)))
6939         {
6940           operands[2] = GEN_INT (-INTVAL (operands[2]));
6941           return "sub{w}\t{%2, %0|%0, %2}";
6942         }
6943       return "add{w}\t{%2, %0|%0, %2}";
6944     }
6946   [(set (attr "type")
6947      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6948         (const_string "incdec")
6949         (const_string "alu")))
6950    (set_attr "mode" "HI")])
6952 (define_insn "*addhi_3"
6953   [(set (reg FLAGS_REG)
6954         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6955                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6956    (clobber (match_scratch:HI 0 "=r"))]
6957   "ix86_match_ccmode (insn, CCZmode)
6958    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6960   switch (get_attr_type (insn))
6961     {
6962     case TYPE_INCDEC:
6963       if (operands[2] == const1_rtx)
6964         return "inc{w}\t%0";
6965       else
6966         {
6967           gcc_assert (operands[2] == constm1_rtx);
6968           return "dec{w}\t%0";
6969         }
6971     default:
6972       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6973          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6974       if (CONST_INT_P (operands[2])
6975           && (INTVAL (operands[2]) == 128
6976               || (INTVAL (operands[2]) < 0
6977                   && INTVAL (operands[2]) != -128)))
6978         {
6979           operands[2] = GEN_INT (-INTVAL (operands[2]));
6980           return "sub{w}\t{%2, %0|%0, %2}";
6981         }
6982       return "add{w}\t{%2, %0|%0, %2}";
6983     }
6985   [(set (attr "type")
6986      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6987         (const_string "incdec")
6988         (const_string "alu")))
6989    (set_attr "mode" "HI")])
6991 ; See comments above addsi_4 for details.
6992 (define_insn "*addhi_4"
6993   [(set (reg FLAGS_REG)
6994         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6995                  (match_operand:HI 2 "const_int_operand" "n")))
6996    (clobber (match_scratch:HI 0 "=rm"))]
6997   "ix86_match_ccmode (insn, CCGCmode)
6998    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
7000   switch (get_attr_type (insn))
7001     {
7002     case TYPE_INCDEC:
7003       if (operands[2] == constm1_rtx)
7004         return "inc{w}\t%0";
7005       else
7006         {
7007           gcc_assert (operands[2] == const1_rtx);
7008           return "dec{w}\t%0";
7009         }
7011     default:
7012       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7013       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7014          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7015       if ((INTVAL (operands[2]) == -128
7016            || (INTVAL (operands[2]) > 0
7017                && INTVAL (operands[2]) != 128)))
7018         return "sub{w}\t{%2, %0|%0, %2}";
7019       operands[2] = GEN_INT (-INTVAL (operands[2]));
7020       return "add{w}\t{%2, %0|%0, %2}";
7021     }
7023   [(set (attr "type")
7024      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7025         (const_string "incdec")
7026         (const_string "alu")))
7027    (set_attr "mode" "SI")])
7030 (define_insn "*addhi_5"
7031   [(set (reg FLAGS_REG)
7032         (compare
7033           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7034                    (match_operand:HI 2 "general_operand" "rmn"))
7035           (const_int 0)))
7036    (clobber (match_scratch:HI 0 "=r"))]
7037   "ix86_match_ccmode (insn, CCGOCmode)
7038    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7040   switch (get_attr_type (insn))
7041     {
7042     case TYPE_INCDEC:
7043       if (operands[2] == const1_rtx)
7044         return "inc{w}\t%0";
7045       else
7046         {
7047           gcc_assert (operands[2] == constm1_rtx);
7048           return "dec{w}\t%0";
7049         }
7051     default:
7052       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7053          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7054       if (CONST_INT_P (operands[2])
7055           && (INTVAL (operands[2]) == 128
7056               || (INTVAL (operands[2]) < 0
7057                   && INTVAL (operands[2]) != -128)))
7058         {
7059           operands[2] = GEN_INT (-INTVAL (operands[2]));
7060           return "sub{w}\t{%2, %0|%0, %2}";
7061         }
7062       return "add{w}\t{%2, %0|%0, %2}";
7063     }
7065   [(set (attr "type")
7066      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7067         (const_string "incdec")
7068         (const_string "alu")))
7069    (set_attr "mode" "HI")])
7071 (define_expand "addqi3"
7072   [(set (match_operand:QI 0 "nonimmediate_operand" "")
7073         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7074                  (match_operand:QI 2 "general_operand" "")))]
7075   "TARGET_QIMODE_MATH"
7076   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
7078 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7079 (define_insn "*addqi_1_lea"
7080   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
7081         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
7082                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
7083    (clobber (reg:CC FLAGS_REG))]
7084   "!TARGET_PARTIAL_REG_STALL
7085    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7087   int widen = (which_alternative == 2);
7088   switch (get_attr_type (insn))
7089     {
7090     case TYPE_LEA:
7091       return "#";
7092     case TYPE_INCDEC:
7093       if (operands[2] == const1_rtx)
7094         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7095       else
7096         {
7097           gcc_assert (operands[2] == constm1_rtx);
7098           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7099         }
7101     default:
7102       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7103          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7104       if (CONST_INT_P (operands[2])
7105           && (INTVAL (operands[2]) == 128
7106               || (INTVAL (operands[2]) < 0
7107                   && INTVAL (operands[2]) != -128)))
7108         {
7109           operands[2] = GEN_INT (-INTVAL (operands[2]));
7110           if (widen)
7111             return "sub{l}\t{%2, %k0|%k0, %2}";
7112           else
7113             return "sub{b}\t{%2, %0|%0, %2}";
7114         }
7115       if (widen)
7116         return "add{l}\t{%k2, %k0|%k0, %k2}";
7117       else
7118         return "add{b}\t{%2, %0|%0, %2}";
7119     }
7121   [(set (attr "type")
7122      (if_then_else (eq_attr "alternative" "3")
7123         (const_string "lea")
7124         (if_then_else (match_operand:QI 2 "incdec_operand" "")
7125            (const_string "incdec")
7126            (const_string "alu"))))
7127    (set_attr "mode" "QI,QI,SI,SI")])
7129 (define_insn "*addqi_1"
7130   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7131         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7132                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7133    (clobber (reg:CC FLAGS_REG))]
7134   "TARGET_PARTIAL_REG_STALL
7135    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7137   int widen = (which_alternative == 2);
7138   switch (get_attr_type (insn))
7139     {
7140     case TYPE_INCDEC:
7141       if (operands[2] == const1_rtx)
7142         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7143       else
7144         {
7145           gcc_assert (operands[2] == constm1_rtx);
7146           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7147         }
7149     default:
7150       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7151          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7152       if (CONST_INT_P (operands[2])
7153           && (INTVAL (operands[2]) == 128
7154               || (INTVAL (operands[2]) < 0
7155                   && INTVAL (operands[2]) != -128)))
7156         {
7157           operands[2] = GEN_INT (-INTVAL (operands[2]));
7158           if (widen)
7159             return "sub{l}\t{%2, %k0|%k0, %2}";
7160           else
7161             return "sub{b}\t{%2, %0|%0, %2}";
7162         }
7163       if (widen)
7164         return "add{l}\t{%k2, %k0|%k0, %k2}";
7165       else
7166         return "add{b}\t{%2, %0|%0, %2}";
7167     }
7169   [(set (attr "type")
7170      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7171         (const_string "incdec")
7172         (const_string "alu")))
7173    (set_attr "mode" "QI,QI,SI")])
7175 (define_insn "*addqi_1_slp"
7176   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7177         (plus:QI (match_dup 0)
7178                  (match_operand:QI 1 "general_operand" "qn,qnm")))
7179    (clobber (reg:CC FLAGS_REG))]
7180   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7181    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7183   switch (get_attr_type (insn))
7184     {
7185     case TYPE_INCDEC:
7186       if (operands[1] == const1_rtx)
7187         return "inc{b}\t%0";
7188       else
7189         {
7190           gcc_assert (operands[1] == constm1_rtx);
7191           return "dec{b}\t%0";
7192         }
7194     default:
7195       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
7196       if (CONST_INT_P (operands[1])
7197           && INTVAL (operands[1]) < 0)
7198         {
7199           operands[1] = GEN_INT (-INTVAL (operands[1]));
7200           return "sub{b}\t{%1, %0|%0, %1}";
7201         }
7202       return "add{b}\t{%1, %0|%0, %1}";
7203     }
7205   [(set (attr "type")
7206      (if_then_else (match_operand:QI 1 "incdec_operand" "")
7207         (const_string "incdec")
7208         (const_string "alu1")))
7209    (set (attr "memory")
7210      (if_then_else (match_operand 1 "memory_operand" "")
7211         (const_string "load")
7212         (const_string "none")))
7213    (set_attr "mode" "QI")])
7215 (define_insn "*addqi_2"
7216   [(set (reg FLAGS_REG)
7217         (compare
7218           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7219                    (match_operand:QI 2 "general_operand" "qmn,qn"))
7220           (const_int 0)))
7221    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7222         (plus:QI (match_dup 1) (match_dup 2)))]
7223   "ix86_match_ccmode (insn, CCGOCmode)
7224    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7226   switch (get_attr_type (insn))
7227     {
7228     case TYPE_INCDEC:
7229       if (operands[2] == const1_rtx)
7230         return "inc{b}\t%0";
7231       else
7232         {
7233           gcc_assert (operands[2] == constm1_rtx
7234                       || (CONST_INT_P (operands[2])
7235                           && INTVAL (operands[2]) == 255));
7236           return "dec{b}\t%0";
7237         }
7239     default:
7240       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7241       if (CONST_INT_P (operands[2])
7242           && INTVAL (operands[2]) < 0)
7243         {
7244           operands[2] = GEN_INT (-INTVAL (operands[2]));
7245           return "sub{b}\t{%2, %0|%0, %2}";
7246         }
7247       return "add{b}\t{%2, %0|%0, %2}";
7248     }
7250   [(set (attr "type")
7251      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7252         (const_string "incdec")
7253         (const_string "alu")))
7254    (set_attr "mode" "QI")])
7256 (define_insn "*addqi_3"
7257   [(set (reg FLAGS_REG)
7258         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7259                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
7260    (clobber (match_scratch:QI 0 "=q"))]
7261   "ix86_match_ccmode (insn, CCZmode)
7262    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7264   switch (get_attr_type (insn))
7265     {
7266     case TYPE_INCDEC:
7267       if (operands[2] == const1_rtx)
7268         return "inc{b}\t%0";
7269       else
7270         {
7271           gcc_assert (operands[2] == constm1_rtx
7272                       || (CONST_INT_P (operands[2])
7273                           && INTVAL (operands[2]) == 255));
7274           return "dec{b}\t%0";
7275         }
7277     default:
7278       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7279       if (CONST_INT_P (operands[2])
7280           && INTVAL (operands[2]) < 0)
7281         {
7282           operands[2] = GEN_INT (-INTVAL (operands[2]));
7283           return "sub{b}\t{%2, %0|%0, %2}";
7284         }
7285       return "add{b}\t{%2, %0|%0, %2}";
7286     }
7288   [(set (attr "type")
7289      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7290         (const_string "incdec")
7291         (const_string "alu")))
7292    (set_attr "mode" "QI")])
7294 ; See comments above addsi_4 for details.
7295 (define_insn "*addqi_4"
7296   [(set (reg FLAGS_REG)
7297         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7298                  (match_operand:QI 2 "const_int_operand" "n")))
7299    (clobber (match_scratch:QI 0 "=qm"))]
7300   "ix86_match_ccmode (insn, CCGCmode)
7301    && (INTVAL (operands[2]) & 0xff) != 0x80"
7303   switch (get_attr_type (insn))
7304     {
7305     case TYPE_INCDEC:
7306       if (operands[2] == constm1_rtx
7307           || (CONST_INT_P (operands[2])
7308               && INTVAL (operands[2]) == 255))
7309         return "inc{b}\t%0";
7310       else
7311         {
7312           gcc_assert (operands[2] == const1_rtx);
7313           return "dec{b}\t%0";
7314         }
7316     default:
7317       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7318       if (INTVAL (operands[2]) < 0)
7319         {
7320           operands[2] = GEN_INT (-INTVAL (operands[2]));
7321           return "add{b}\t{%2, %0|%0, %2}";
7322         }
7323       return "sub{b}\t{%2, %0|%0, %2}";
7324     }
7326   [(set (attr "type")
7327      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7328         (const_string "incdec")
7329         (const_string "alu")))
7330    (set_attr "mode" "QI")])
7333 (define_insn "*addqi_5"
7334   [(set (reg FLAGS_REG)
7335         (compare
7336           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7337                    (match_operand:QI 2 "general_operand" "qmn"))
7338           (const_int 0)))
7339    (clobber (match_scratch:QI 0 "=q"))]
7340   "ix86_match_ccmode (insn, CCGOCmode)
7341    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7343   switch (get_attr_type (insn))
7344     {
7345     case TYPE_INCDEC:
7346       if (operands[2] == const1_rtx)
7347         return "inc{b}\t%0";
7348       else
7349         {
7350           gcc_assert (operands[2] == constm1_rtx
7351                       || (CONST_INT_P (operands[2])
7352                           && INTVAL (operands[2]) == 255));
7353           return "dec{b}\t%0";
7354         }
7356     default:
7357       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7358       if (CONST_INT_P (operands[2])
7359           && INTVAL (operands[2]) < 0)
7360         {
7361           operands[2] = GEN_INT (-INTVAL (operands[2]));
7362           return "sub{b}\t{%2, %0|%0, %2}";
7363         }
7364       return "add{b}\t{%2, %0|%0, %2}";
7365     }
7367   [(set (attr "type")
7368      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7369         (const_string "incdec")
7370         (const_string "alu")))
7371    (set_attr "mode" "QI")])
7374 (define_insn "addqi_ext_1"
7375   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7376                          (const_int 8)
7377                          (const_int 8))
7378         (plus:SI
7379           (zero_extract:SI
7380             (match_operand 1 "ext_register_operand" "0")
7381             (const_int 8)
7382             (const_int 8))
7383           (match_operand:QI 2 "general_operand" "Qmn")))
7384    (clobber (reg:CC FLAGS_REG))]
7385   "!TARGET_64BIT"
7387   switch (get_attr_type (insn))
7388     {
7389     case TYPE_INCDEC:
7390       if (operands[2] == const1_rtx)
7391         return "inc{b}\t%h0";
7392       else
7393         {
7394           gcc_assert (operands[2] == constm1_rtx
7395                       || (CONST_INT_P (operands[2])
7396                           && INTVAL (operands[2]) == 255));
7397           return "dec{b}\t%h0";
7398         }
7400     default:
7401       return "add{b}\t{%2, %h0|%h0, %2}";
7402     }
7404   [(set (attr "type")
7405      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7406         (const_string "incdec")
7407         (const_string "alu")))
7408    (set_attr "mode" "QI")])
7410 (define_insn "*addqi_ext_1_rex64"
7411   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7412                          (const_int 8)
7413                          (const_int 8))
7414         (plus:SI
7415           (zero_extract:SI
7416             (match_operand 1 "ext_register_operand" "0")
7417             (const_int 8)
7418             (const_int 8))
7419           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7420    (clobber (reg:CC FLAGS_REG))]
7421   "TARGET_64BIT"
7423   switch (get_attr_type (insn))
7424     {
7425     case TYPE_INCDEC:
7426       if (operands[2] == const1_rtx)
7427         return "inc{b}\t%h0";
7428       else
7429         {
7430           gcc_assert (operands[2] == constm1_rtx
7431                       || (CONST_INT_P (operands[2])
7432                           && INTVAL (operands[2]) == 255));
7433           return "dec{b}\t%h0";
7434         }
7436     default:
7437       return "add{b}\t{%2, %h0|%h0, %2}";
7438     }
7440   [(set (attr "type")
7441      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7442         (const_string "incdec")
7443         (const_string "alu")))
7444    (set_attr "mode" "QI")])
7446 (define_insn "*addqi_ext_2"
7447   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7448                          (const_int 8)
7449                          (const_int 8))
7450         (plus:SI
7451           (zero_extract:SI
7452             (match_operand 1 "ext_register_operand" "%0")
7453             (const_int 8)
7454             (const_int 8))
7455           (zero_extract:SI
7456             (match_operand 2 "ext_register_operand" "Q")
7457             (const_int 8)
7458             (const_int 8))))
7459    (clobber (reg:CC FLAGS_REG))]
7460   ""
7461   "add{b}\t{%h2, %h0|%h0, %h2}"
7462   [(set_attr "type" "alu")
7463    (set_attr "mode" "QI")])
7465 ;; The patterns that match these are at the end of this file.
7467 (define_expand "addxf3"
7468   [(set (match_operand:XF 0 "register_operand" "")
7469         (plus:XF (match_operand:XF 1 "register_operand" "")
7470                  (match_operand:XF 2 "register_operand" "")))]
7471   "TARGET_80387"
7472   "")
7474 (define_expand "add<mode>3"
7475   [(set (match_operand:MODEF 0 "register_operand" "")
7476         (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7477                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7478   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7479   "")
7481 ;; Subtract instructions
7483 ;; %%% splits for subditi3
7485 (define_expand "subti3"
7486   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7487         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7488                   (match_operand:TI 2 "x86_64_general_operand" "")))]
7489   "TARGET_64BIT"
7490   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7492 (define_insn "*subti3_1"
7493   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7494         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7495                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7496    (clobber (reg:CC FLAGS_REG))]
7497   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7498   "#")
7500 (define_split
7501   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7502         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7503                   (match_operand:TI 2 "x86_64_general_operand" "")))
7504    (clobber (reg:CC FLAGS_REG))]
7505   "TARGET_64BIT && reload_completed"
7506   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7507               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7508    (parallel [(set (match_dup 3)
7509                    (minus:DI (match_dup 4)
7510                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7511                                       (match_dup 5))))
7512               (clobber (reg:CC FLAGS_REG))])]
7513   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7515 ;; %%% splits for subsidi3
7517 (define_expand "subdi3"
7518   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7519         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7520                   (match_operand:DI 2 "x86_64_general_operand" "")))]
7521   ""
7522   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7524 (define_insn "*subdi3_1"
7525   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7526         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7527                   (match_operand:DI 2 "general_operand" "roiF,riF")))
7528    (clobber (reg:CC FLAGS_REG))]
7529   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7530   "#")
7532 (define_split
7533   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7534         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7535                   (match_operand:DI 2 "general_operand" "")))
7536    (clobber (reg:CC FLAGS_REG))]
7537   "!TARGET_64BIT && reload_completed"
7538   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7539               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7540    (parallel [(set (match_dup 3)
7541                    (minus:SI (match_dup 4)
7542                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7543                                       (match_dup 5))))
7544               (clobber (reg:CC FLAGS_REG))])]
7545   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7547 (define_insn "subdi3_carry_rex64"
7548   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7549           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7550             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7551                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7552    (clobber (reg:CC FLAGS_REG))]
7553   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7554   "sbb{q}\t{%2, %0|%0, %2}"
7555   [(set_attr "type" "alu")
7556    (set_attr "pent_pair" "pu")
7557    (set_attr "mode" "DI")])
7559 (define_insn "*subdi_1_rex64"
7560   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7561         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7562                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7563    (clobber (reg:CC FLAGS_REG))]
7564   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7565   "sub{q}\t{%2, %0|%0, %2}"
7566   [(set_attr "type" "alu")
7567    (set_attr "mode" "DI")])
7569 (define_insn "*subdi_2_rex64"
7570   [(set (reg FLAGS_REG)
7571         (compare
7572           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7573                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7574           (const_int 0)))
7575    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7576         (minus:DI (match_dup 1) (match_dup 2)))]
7577   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7578    && ix86_binary_operator_ok (MINUS, DImode, operands)"
7579   "sub{q}\t{%2, %0|%0, %2}"
7580   [(set_attr "type" "alu")
7581    (set_attr "mode" "DI")])
7583 (define_insn "*subdi_3_rex63"
7584   [(set (reg FLAGS_REG)
7585         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7586                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7587    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7588         (minus:DI (match_dup 1) (match_dup 2)))]
7589   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7590    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7591   "sub{q}\t{%2, %0|%0, %2}"
7592   [(set_attr "type" "alu")
7593    (set_attr "mode" "DI")])
7595 (define_insn "subqi3_carry"
7596   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7597           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7598             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7599                (match_operand:QI 2 "general_operand" "qn,qm"))))
7600    (clobber (reg:CC FLAGS_REG))]
7601   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7602   "sbb{b}\t{%2, %0|%0, %2}"
7603   [(set_attr "type" "alu")
7604    (set_attr "pent_pair" "pu")
7605    (set_attr "mode" "QI")])
7607 (define_insn "subhi3_carry"
7608   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7609           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7610             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7611                (match_operand:HI 2 "general_operand" "rn,rm"))))
7612    (clobber (reg:CC FLAGS_REG))]
7613   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7614   "sbb{w}\t{%2, %0|%0, %2}"
7615   [(set_attr "type" "alu")
7616    (set_attr "pent_pair" "pu")
7617    (set_attr "mode" "HI")])
7619 (define_insn "subsi3_carry"
7620   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7621           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7622             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7623                (match_operand:SI 2 "general_operand" "ri,rm"))))
7624    (clobber (reg:CC FLAGS_REG))]
7625   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7626   "sbb{l}\t{%2, %0|%0, %2}"
7627   [(set_attr "type" "alu")
7628    (set_attr "pent_pair" "pu")
7629    (set_attr "mode" "SI")])
7631 (define_insn "subsi3_carry_zext"
7632   [(set (match_operand:DI 0 "register_operand" "=r")
7633           (zero_extend:DI
7634             (minus:SI (match_operand:SI 1 "register_operand" "0")
7635               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7636                  (match_operand:SI 2 "general_operand" "g")))))
7637    (clobber (reg:CC FLAGS_REG))]
7638   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7639   "sbb{l}\t{%2, %k0|%k0, %2}"
7640   [(set_attr "type" "alu")
7641    (set_attr "pent_pair" "pu")
7642    (set_attr "mode" "SI")])
7644 (define_expand "subsi3"
7645   [(set (match_operand:SI 0 "nonimmediate_operand" "")
7646         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7647                   (match_operand:SI 2 "general_operand" "")))]
7648   ""
7649   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7651 (define_insn "*subsi_1"
7652   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7653         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7654                   (match_operand:SI 2 "general_operand" "ri,rm")))
7655    (clobber (reg:CC FLAGS_REG))]
7656   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7657   "sub{l}\t{%2, %0|%0, %2}"
7658   [(set_attr "type" "alu")
7659    (set_attr "mode" "SI")])
7661 (define_insn "*subsi_1_zext"
7662   [(set (match_operand:DI 0 "register_operand" "=r")
7663         (zero_extend:DI
7664           (minus:SI (match_operand:SI 1 "register_operand" "0")
7665                     (match_operand:SI 2 "general_operand" "g"))))
7666    (clobber (reg:CC FLAGS_REG))]
7667   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7668   "sub{l}\t{%2, %k0|%k0, %2}"
7669   [(set_attr "type" "alu")
7670    (set_attr "mode" "SI")])
7672 (define_insn "*subsi_2"
7673   [(set (reg FLAGS_REG)
7674         (compare
7675           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7676                     (match_operand:SI 2 "general_operand" "ri,rm"))
7677           (const_int 0)))
7678    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7679         (minus:SI (match_dup 1) (match_dup 2)))]
7680   "ix86_match_ccmode (insn, CCGOCmode)
7681    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7682   "sub{l}\t{%2, %0|%0, %2}"
7683   [(set_attr "type" "alu")
7684    (set_attr "mode" "SI")])
7686 (define_insn "*subsi_2_zext"
7687   [(set (reg FLAGS_REG)
7688         (compare
7689           (minus:SI (match_operand:SI 1 "register_operand" "0")
7690                     (match_operand:SI 2 "general_operand" "g"))
7691           (const_int 0)))
7692    (set (match_operand:DI 0 "register_operand" "=r")
7693         (zero_extend:DI
7694           (minus:SI (match_dup 1)
7695                     (match_dup 2))))]
7696   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7697    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7698   "sub{l}\t{%2, %k0|%k0, %2}"
7699   [(set_attr "type" "alu")
7700    (set_attr "mode" "SI")])
7702 (define_insn "*subsi_3"
7703   [(set (reg FLAGS_REG)
7704         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7705                  (match_operand:SI 2 "general_operand" "ri,rm")))
7706    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7707         (minus:SI (match_dup 1) (match_dup 2)))]
7708   "ix86_match_ccmode (insn, CCmode)
7709    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7710   "sub{l}\t{%2, %0|%0, %2}"
7711   [(set_attr "type" "alu")
7712    (set_attr "mode" "SI")])
7714 (define_insn "*subsi_3_zext"
7715   [(set (reg FLAGS_REG)
7716         (compare (match_operand:SI 1 "register_operand" "0")
7717                  (match_operand:SI 2 "general_operand" "g")))
7718    (set (match_operand:DI 0 "register_operand" "=r")
7719         (zero_extend:DI
7720           (minus:SI (match_dup 1)
7721                     (match_dup 2))))]
7722   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7723    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7724   "sub{l}\t{%2, %1|%1, %2}"
7725   [(set_attr "type" "alu")
7726    (set_attr "mode" "DI")])
7728 (define_expand "subhi3"
7729   [(set (match_operand:HI 0 "nonimmediate_operand" "")
7730         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7731                   (match_operand:HI 2 "general_operand" "")))]
7732   "TARGET_HIMODE_MATH"
7733   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7735 (define_insn "*subhi_1"
7736   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7737         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7738                   (match_operand:HI 2 "general_operand" "rn,rm")))
7739    (clobber (reg:CC FLAGS_REG))]
7740   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7741   "sub{w}\t{%2, %0|%0, %2}"
7742   [(set_attr "type" "alu")
7743    (set_attr "mode" "HI")])
7745 (define_insn "*subhi_2"
7746   [(set (reg FLAGS_REG)
7747         (compare
7748           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7749                     (match_operand:HI 2 "general_operand" "rn,rm"))
7750           (const_int 0)))
7751    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7752         (minus:HI (match_dup 1) (match_dup 2)))]
7753   "ix86_match_ccmode (insn, CCGOCmode)
7754    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7755   "sub{w}\t{%2, %0|%0, %2}"
7756   [(set_attr "type" "alu")
7757    (set_attr "mode" "HI")])
7759 (define_insn "*subhi_3"
7760   [(set (reg FLAGS_REG)
7761         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7762                  (match_operand:HI 2 "general_operand" "rn,rm")))
7763    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7764         (minus:HI (match_dup 1) (match_dup 2)))]
7765   "ix86_match_ccmode (insn, CCmode)
7766    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7767   "sub{w}\t{%2, %0|%0, %2}"
7768   [(set_attr "type" "alu")
7769    (set_attr "mode" "HI")])
7771 (define_expand "subqi3"
7772   [(set (match_operand:QI 0 "nonimmediate_operand" "")
7773         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7774                   (match_operand:QI 2 "general_operand" "")))]
7775   "TARGET_QIMODE_MATH"
7776   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7778 (define_insn "*subqi_1"
7779   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7780         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7781                   (match_operand:QI 2 "general_operand" "qn,qm")))
7782    (clobber (reg:CC FLAGS_REG))]
7783   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7784   "sub{b}\t{%2, %0|%0, %2}"
7785   [(set_attr "type" "alu")
7786    (set_attr "mode" "QI")])
7788 (define_insn "*subqi_1_slp"
7789   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7790         (minus:QI (match_dup 0)
7791                   (match_operand:QI 1 "general_operand" "qn,qm")))
7792    (clobber (reg:CC FLAGS_REG))]
7793   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7794    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7795   "sub{b}\t{%1, %0|%0, %1}"
7796   [(set_attr "type" "alu1")
7797    (set_attr "mode" "QI")])
7799 (define_insn "*subqi_2"
7800   [(set (reg FLAGS_REG)
7801         (compare
7802           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7803                     (match_operand:QI 2 "general_operand" "qn,qm"))
7804           (const_int 0)))
7805    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7806         (minus:QI (match_dup 1) (match_dup 2)))]
7807   "ix86_match_ccmode (insn, CCGOCmode)
7808    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7809   "sub{b}\t{%2, %0|%0, %2}"
7810   [(set_attr "type" "alu")
7811    (set_attr "mode" "QI")])
7813 (define_insn "*subqi_3"
7814   [(set (reg FLAGS_REG)
7815         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7816                  (match_operand:QI 2 "general_operand" "qn,qm")))
7817    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7818         (minus:QI (match_dup 1) (match_dup 2)))]
7819   "ix86_match_ccmode (insn, CCmode)
7820    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7821   "sub{b}\t{%2, %0|%0, %2}"
7822   [(set_attr "type" "alu")
7823    (set_attr "mode" "QI")])
7825 ;; The patterns that match these are at the end of this file.
7827 (define_expand "subxf3"
7828   [(set (match_operand:XF 0 "register_operand" "")
7829         (minus:XF (match_operand:XF 1 "register_operand" "")
7830                   (match_operand:XF 2 "register_operand" "")))]
7831   "TARGET_80387"
7832   "")
7834 (define_expand "sub<mode>3"
7835   [(set (match_operand:MODEF 0 "register_operand" "")
7836         (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7837                      (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7838   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7839   "")
7841 ;; Multiply instructions
7843 (define_expand "muldi3"
7844   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7845                    (mult:DI (match_operand:DI 1 "register_operand" "")
7846                             (match_operand:DI 2 "x86_64_general_operand" "")))
7847               (clobber (reg:CC FLAGS_REG))])]
7848   "TARGET_64BIT"
7849   "")
7851 ;; On AMDFAM10
7852 ;; IMUL reg64, reg64, imm8      Direct
7853 ;; IMUL reg64, mem64, imm8      VectorPath
7854 ;; IMUL reg64, reg64, imm32     Direct
7855 ;; IMUL reg64, mem64, imm32     VectorPath
7856 ;; IMUL reg64, reg64            Direct
7857 ;; IMUL reg64, mem64            Direct
7859 (define_insn "*muldi3_1_rex64"
7860   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7861         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7862                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7863    (clobber (reg:CC FLAGS_REG))]
7864   "TARGET_64BIT
7865    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7866   "@
7867    imul{q}\t{%2, %1, %0|%0, %1, %2}
7868    imul{q}\t{%2, %1, %0|%0, %1, %2}
7869    imul{q}\t{%2, %0|%0, %2}"
7870   [(set_attr "type" "imul")
7871    (set_attr "prefix_0f" "0,0,1")
7872    (set (attr "athlon_decode")
7873         (cond [(eq_attr "cpu" "athlon")
7874                   (const_string "vector")
7875                (eq_attr "alternative" "1")
7876                   (const_string "vector")
7877                (and (eq_attr "alternative" "2")
7878                     (match_operand 1 "memory_operand" ""))
7879                   (const_string "vector")]
7880               (const_string "direct")))
7881    (set (attr "amdfam10_decode")
7882         (cond [(and (eq_attr "alternative" "0,1")
7883                     (match_operand 1 "memory_operand" ""))
7884                   (const_string "vector")]
7885               (const_string "direct")))
7886    (set_attr "mode" "DI")])
7888 (define_expand "mulsi3"
7889   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7890                    (mult:SI (match_operand:SI 1 "register_operand" "")
7891                             (match_operand:SI 2 "general_operand" "")))
7892               (clobber (reg:CC FLAGS_REG))])]
7893   ""
7894   "")
7896 ;; On AMDFAM10
7897 ;; IMUL reg32, reg32, imm8      Direct
7898 ;; IMUL reg32, mem32, imm8      VectorPath
7899 ;; IMUL reg32, reg32, imm32     Direct
7900 ;; IMUL reg32, mem32, imm32     VectorPath
7901 ;; IMUL reg32, reg32            Direct
7902 ;; IMUL reg32, mem32            Direct
7904 (define_insn "*mulsi3_1"
7905   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7906         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7907                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7908    (clobber (reg:CC FLAGS_REG))]
7909   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7910   "@
7911    imul{l}\t{%2, %1, %0|%0, %1, %2}
7912    imul{l}\t{%2, %1, %0|%0, %1, %2}
7913    imul{l}\t{%2, %0|%0, %2}"
7914   [(set_attr "type" "imul")
7915    (set_attr "prefix_0f" "0,0,1")
7916    (set (attr "athlon_decode")
7917         (cond [(eq_attr "cpu" "athlon")
7918                   (const_string "vector")
7919                (eq_attr "alternative" "1")
7920                   (const_string "vector")
7921                (and (eq_attr "alternative" "2")
7922                     (match_operand 1 "memory_operand" ""))
7923                   (const_string "vector")]
7924               (const_string "direct")))
7925    (set (attr "amdfam10_decode")
7926         (cond [(and (eq_attr "alternative" "0,1")
7927                     (match_operand 1 "memory_operand" ""))
7928                   (const_string "vector")]
7929               (const_string "direct")))
7930    (set_attr "mode" "SI")])
7932 (define_insn "*mulsi3_1_zext"
7933   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7934         (zero_extend:DI
7935           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7936                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7937    (clobber (reg:CC FLAGS_REG))]
7938   "TARGET_64BIT
7939    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7940   "@
7941    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7942    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7943    imul{l}\t{%2, %k0|%k0, %2}"
7944   [(set_attr "type" "imul")
7945    (set_attr "prefix_0f" "0,0,1")
7946    (set (attr "athlon_decode")
7947         (cond [(eq_attr "cpu" "athlon")
7948                   (const_string "vector")
7949                (eq_attr "alternative" "1")
7950                   (const_string "vector")
7951                (and (eq_attr "alternative" "2")
7952                     (match_operand 1 "memory_operand" ""))
7953                   (const_string "vector")]
7954               (const_string "direct")))
7955    (set (attr "amdfam10_decode")
7956         (cond [(and (eq_attr "alternative" "0,1")
7957                     (match_operand 1 "memory_operand" ""))
7958                   (const_string "vector")]
7959               (const_string "direct")))
7960    (set_attr "mode" "SI")])
7962 (define_expand "mulhi3"
7963   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7964                    (mult:HI (match_operand:HI 1 "register_operand" "")
7965                             (match_operand:HI 2 "general_operand" "")))
7966               (clobber (reg:CC FLAGS_REG))])]
7967   "TARGET_HIMODE_MATH"
7968   "")
7970 ;; On AMDFAM10
7971 ;; IMUL reg16, reg16, imm8      VectorPath
7972 ;; IMUL reg16, mem16, imm8      VectorPath
7973 ;; IMUL reg16, reg16, imm16     VectorPath
7974 ;; IMUL reg16, mem16, imm16     VectorPath
7975 ;; IMUL reg16, reg16            Direct
7976 ;; IMUL reg16, mem16            Direct
7977 (define_insn "*mulhi3_1"
7978   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7979         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7980                  (match_operand:HI 2 "general_operand" "K,n,mr")))
7981    (clobber (reg:CC FLAGS_REG))]
7982   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7983   "@
7984    imul{w}\t{%2, %1, %0|%0, %1, %2}
7985    imul{w}\t{%2, %1, %0|%0, %1, %2}
7986    imul{w}\t{%2, %0|%0, %2}"
7987   [(set_attr "type" "imul")
7988    (set_attr "prefix_0f" "0,0,1")
7989    (set (attr "athlon_decode")
7990         (cond [(eq_attr "cpu" "athlon")
7991                   (const_string "vector")
7992                (eq_attr "alternative" "1,2")
7993                   (const_string "vector")]
7994               (const_string "direct")))
7995    (set (attr "amdfam10_decode")
7996         (cond [(eq_attr "alternative" "0,1")
7997                   (const_string "vector")]
7998               (const_string "direct")))
7999    (set_attr "mode" "HI")])
8001 (define_expand "mulqi3"
8002   [(parallel [(set (match_operand:QI 0 "register_operand" "")
8003                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
8004                             (match_operand:QI 2 "register_operand" "")))
8005               (clobber (reg:CC FLAGS_REG))])]
8006   "TARGET_QIMODE_MATH"
8007   "")
8009 ;;On AMDFAM10
8010 ;; MUL reg8     Direct
8011 ;; MUL mem8     Direct
8013 (define_insn "*mulqi3_1"
8014   [(set (match_operand:QI 0 "register_operand" "=a")
8015         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8016                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8017    (clobber (reg:CC FLAGS_REG))]
8018   "TARGET_QIMODE_MATH
8019    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8020   "mul{b}\t%2"
8021   [(set_attr "type" "imul")
8022    (set_attr "length_immediate" "0")
8023    (set (attr "athlon_decode")
8024      (if_then_else (eq_attr "cpu" "athlon")
8025         (const_string "vector")
8026         (const_string "direct")))
8027    (set_attr "amdfam10_decode" "direct")
8028    (set_attr "mode" "QI")])
8030 (define_expand "umulqihi3"
8031   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8032                    (mult:HI (zero_extend:HI
8033                               (match_operand:QI 1 "nonimmediate_operand" ""))
8034                             (zero_extend:HI
8035                               (match_operand:QI 2 "register_operand" ""))))
8036               (clobber (reg:CC FLAGS_REG))])]
8037   "TARGET_QIMODE_MATH"
8038   "")
8040 (define_insn "*umulqihi3_1"
8041   [(set (match_operand:HI 0 "register_operand" "=a")
8042         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8043                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8044    (clobber (reg:CC FLAGS_REG))]
8045   "TARGET_QIMODE_MATH
8046    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8047   "mul{b}\t%2"
8048   [(set_attr "type" "imul")
8049    (set_attr "length_immediate" "0")
8050    (set (attr "athlon_decode")
8051      (if_then_else (eq_attr "cpu" "athlon")
8052         (const_string "vector")
8053         (const_string "direct")))
8054    (set_attr "amdfam10_decode" "direct")
8055    (set_attr "mode" "QI")])
8057 (define_expand "mulqihi3"
8058   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8059                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
8060                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
8061               (clobber (reg:CC FLAGS_REG))])]
8062   "TARGET_QIMODE_MATH"
8063   "")
8065 (define_insn "*mulqihi3_insn"
8066   [(set (match_operand:HI 0 "register_operand" "=a")
8067         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8068                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8069    (clobber (reg:CC FLAGS_REG))]
8070   "TARGET_QIMODE_MATH
8071    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8072   "imul{b}\t%2"
8073   [(set_attr "type" "imul")
8074    (set_attr "length_immediate" "0")
8075    (set (attr "athlon_decode")
8076      (if_then_else (eq_attr "cpu" "athlon")
8077         (const_string "vector")
8078         (const_string "direct")))
8079    (set_attr "amdfam10_decode" "direct")
8080    (set_attr "mode" "QI")])
8082 (define_expand "umulditi3"
8083   [(parallel [(set (match_operand:TI 0 "register_operand" "")
8084                    (mult:TI (zero_extend:TI
8085                               (match_operand:DI 1 "nonimmediate_operand" ""))
8086                             (zero_extend:TI
8087                               (match_operand:DI 2 "register_operand" ""))))
8088               (clobber (reg:CC FLAGS_REG))])]
8089   "TARGET_64BIT"
8090   "")
8092 (define_insn "*umulditi3_insn"
8093   [(set (match_operand:TI 0 "register_operand" "=A")
8094         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8095                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8096    (clobber (reg:CC FLAGS_REG))]
8097   "TARGET_64BIT
8098    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8099   "mul{q}\t%2"
8100   [(set_attr "type" "imul")
8101    (set_attr "length_immediate" "0")
8102    (set (attr "athlon_decode")
8103      (if_then_else (eq_attr "cpu" "athlon")
8104         (const_string "vector")
8105         (const_string "double")))
8106    (set_attr "amdfam10_decode" "double")
8107    (set_attr "mode" "DI")])
8109 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
8110 (define_expand "umulsidi3"
8111   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8112                    (mult:DI (zero_extend:DI
8113                               (match_operand:SI 1 "nonimmediate_operand" ""))
8114                             (zero_extend:DI
8115                               (match_operand:SI 2 "register_operand" ""))))
8116               (clobber (reg:CC FLAGS_REG))])]
8117   "!TARGET_64BIT"
8118   "")
8120 (define_insn "*umulsidi3_insn"
8121   [(set (match_operand:DI 0 "register_operand" "=A")
8122         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8123                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8124    (clobber (reg:CC FLAGS_REG))]
8125   "!TARGET_64BIT
8126    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8127   "mul{l}\t%2"
8128   [(set_attr "type" "imul")
8129    (set_attr "length_immediate" "0")
8130    (set (attr "athlon_decode")
8131      (if_then_else (eq_attr "cpu" "athlon")
8132         (const_string "vector")
8133         (const_string "double")))
8134    (set_attr "amdfam10_decode" "double")
8135    (set_attr "mode" "SI")])
8137 (define_expand "mulditi3"
8138   [(parallel [(set (match_operand:TI 0 "register_operand" "")
8139                    (mult:TI (sign_extend:TI
8140                               (match_operand:DI 1 "nonimmediate_operand" ""))
8141                             (sign_extend:TI
8142                               (match_operand:DI 2 "register_operand" ""))))
8143               (clobber (reg:CC FLAGS_REG))])]
8144   "TARGET_64BIT"
8145   "")
8147 (define_insn "*mulditi3_insn"
8148   [(set (match_operand:TI 0 "register_operand" "=A")
8149         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8150                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8151    (clobber (reg:CC FLAGS_REG))]
8152   "TARGET_64BIT
8153    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8154   "imul{q}\t%2"
8155   [(set_attr "type" "imul")
8156    (set_attr "length_immediate" "0")
8157    (set (attr "athlon_decode")
8158      (if_then_else (eq_attr "cpu" "athlon")
8159         (const_string "vector")
8160         (const_string "double")))
8161    (set_attr "amdfam10_decode" "double")
8162    (set_attr "mode" "DI")])
8164 (define_expand "mulsidi3"
8165   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8166                    (mult:DI (sign_extend:DI
8167                               (match_operand:SI 1 "nonimmediate_operand" ""))
8168                             (sign_extend:DI
8169                               (match_operand:SI 2 "register_operand" ""))))
8170               (clobber (reg:CC FLAGS_REG))])]
8171   "!TARGET_64BIT"
8172   "")
8174 (define_insn "*mulsidi3_insn"
8175   [(set (match_operand:DI 0 "register_operand" "=A")
8176         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8177                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8178    (clobber (reg:CC FLAGS_REG))]
8179   "!TARGET_64BIT
8180    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8181   "imul{l}\t%2"
8182   [(set_attr "type" "imul")
8183    (set_attr "length_immediate" "0")
8184    (set (attr "athlon_decode")
8185      (if_then_else (eq_attr "cpu" "athlon")
8186         (const_string "vector")
8187         (const_string "double")))
8188    (set_attr "amdfam10_decode" "double")
8189    (set_attr "mode" "SI")])
8191 (define_expand "umuldi3_highpart"
8192   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8193                    (truncate:DI
8194                      (lshiftrt:TI
8195                        (mult:TI (zero_extend:TI
8196                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8197                                 (zero_extend:TI
8198                                   (match_operand:DI 2 "register_operand" "")))
8199                        (const_int 64))))
8200               (clobber (match_scratch:DI 3 ""))
8201               (clobber (reg:CC FLAGS_REG))])]
8202   "TARGET_64BIT"
8203   "")
8205 (define_insn "*umuldi3_highpart_rex64"
8206   [(set (match_operand:DI 0 "register_operand" "=d")
8207         (truncate:DI
8208           (lshiftrt:TI
8209             (mult:TI (zero_extend:TI
8210                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8211                      (zero_extend:TI
8212                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8213             (const_int 64))))
8214    (clobber (match_scratch:DI 3 "=1"))
8215    (clobber (reg:CC FLAGS_REG))]
8216   "TARGET_64BIT
8217    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8218   "mul{q}\t%2"
8219   [(set_attr "type" "imul")
8220    (set_attr "length_immediate" "0")
8221    (set (attr "athlon_decode")
8222      (if_then_else (eq_attr "cpu" "athlon")
8223         (const_string "vector")
8224         (const_string "double")))
8225    (set_attr "amdfam10_decode" "double")
8226    (set_attr "mode" "DI")])
8228 (define_expand "umulsi3_highpart"
8229   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8230                    (truncate:SI
8231                      (lshiftrt:DI
8232                        (mult:DI (zero_extend:DI
8233                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8234                                 (zero_extend:DI
8235                                   (match_operand:SI 2 "register_operand" "")))
8236                        (const_int 32))))
8237               (clobber (match_scratch:SI 3 ""))
8238               (clobber (reg:CC FLAGS_REG))])]
8239   ""
8240   "")
8242 (define_insn "*umulsi3_highpart_insn"
8243   [(set (match_operand:SI 0 "register_operand" "=d")
8244         (truncate:SI
8245           (lshiftrt:DI
8246             (mult:DI (zero_extend:DI
8247                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8248                      (zero_extend:DI
8249                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8250             (const_int 32))))
8251    (clobber (match_scratch:SI 3 "=1"))
8252    (clobber (reg:CC FLAGS_REG))]
8253   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8254   "mul{l}\t%2"
8255   [(set_attr "type" "imul")
8256    (set_attr "length_immediate" "0")
8257    (set (attr "athlon_decode")
8258      (if_then_else (eq_attr "cpu" "athlon")
8259         (const_string "vector")
8260         (const_string "double")))
8261    (set_attr "amdfam10_decode" "double")
8262    (set_attr "mode" "SI")])
8264 (define_insn "*umulsi3_highpart_zext"
8265   [(set (match_operand:DI 0 "register_operand" "=d")
8266         (zero_extend:DI (truncate:SI
8267           (lshiftrt:DI
8268             (mult:DI (zero_extend:DI
8269                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8270                      (zero_extend:DI
8271                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8272             (const_int 32)))))
8273    (clobber (match_scratch:SI 3 "=1"))
8274    (clobber (reg:CC FLAGS_REG))]
8275   "TARGET_64BIT
8276    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8277   "mul{l}\t%2"
8278   [(set_attr "type" "imul")
8279    (set_attr "length_immediate" "0")
8280    (set (attr "athlon_decode")
8281      (if_then_else (eq_attr "cpu" "athlon")
8282         (const_string "vector")
8283         (const_string "double")))
8284    (set_attr "amdfam10_decode" "double")
8285    (set_attr "mode" "SI")])
8287 (define_expand "smuldi3_highpart"
8288   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8289                    (truncate:DI
8290                      (lshiftrt:TI
8291                        (mult:TI (sign_extend:TI
8292                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8293                                 (sign_extend:TI
8294                                   (match_operand:DI 2 "register_operand" "")))
8295                        (const_int 64))))
8296               (clobber (match_scratch:DI 3 ""))
8297               (clobber (reg:CC FLAGS_REG))])]
8298   "TARGET_64BIT"
8299   "")
8301 (define_insn "*smuldi3_highpart_rex64"
8302   [(set (match_operand:DI 0 "register_operand" "=d")
8303         (truncate:DI
8304           (lshiftrt:TI
8305             (mult:TI (sign_extend:TI
8306                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8307                      (sign_extend:TI
8308                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8309             (const_int 64))))
8310    (clobber (match_scratch:DI 3 "=1"))
8311    (clobber (reg:CC FLAGS_REG))]
8312   "TARGET_64BIT
8313    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8314   "imul{q}\t%2"
8315   [(set_attr "type" "imul")
8316    (set (attr "athlon_decode")
8317      (if_then_else (eq_attr "cpu" "athlon")
8318         (const_string "vector")
8319         (const_string "double")))
8320    (set_attr "amdfam10_decode" "double")
8321    (set_attr "mode" "DI")])
8323 (define_expand "smulsi3_highpart"
8324   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8325                    (truncate:SI
8326                      (lshiftrt:DI
8327                        (mult:DI (sign_extend:DI
8328                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8329                                 (sign_extend:DI
8330                                   (match_operand:SI 2 "register_operand" "")))
8331                        (const_int 32))))
8332               (clobber (match_scratch:SI 3 ""))
8333               (clobber (reg:CC FLAGS_REG))])]
8334   ""
8335   "")
8337 (define_insn "*smulsi3_highpart_insn"
8338   [(set (match_operand:SI 0 "register_operand" "=d")
8339         (truncate:SI
8340           (lshiftrt:DI
8341             (mult:DI (sign_extend:DI
8342                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8343                      (sign_extend:DI
8344                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8345             (const_int 32))))
8346    (clobber (match_scratch:SI 3 "=1"))
8347    (clobber (reg:CC FLAGS_REG))]
8348   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8349   "imul{l}\t%2"
8350   [(set_attr "type" "imul")
8351    (set (attr "athlon_decode")
8352      (if_then_else (eq_attr "cpu" "athlon")
8353         (const_string "vector")
8354         (const_string "double")))
8355    (set_attr "amdfam10_decode" "double")
8356    (set_attr "mode" "SI")])
8358 (define_insn "*smulsi3_highpart_zext"
8359   [(set (match_operand:DI 0 "register_operand" "=d")
8360         (zero_extend:DI (truncate:SI
8361           (lshiftrt:DI
8362             (mult:DI (sign_extend:DI
8363                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8364                      (sign_extend:DI
8365                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8366             (const_int 32)))))
8367    (clobber (match_scratch:SI 3 "=1"))
8368    (clobber (reg:CC FLAGS_REG))]
8369   "TARGET_64BIT
8370    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8371   "imul{l}\t%2"
8372   [(set_attr "type" "imul")
8373    (set (attr "athlon_decode")
8374      (if_then_else (eq_attr "cpu" "athlon")
8375         (const_string "vector")
8376         (const_string "double")))
8377    (set_attr "amdfam10_decode" "double")
8378    (set_attr "mode" "SI")])
8380 ;; The patterns that match these are at the end of this file.
8382 (define_expand "mulxf3"
8383   [(set (match_operand:XF 0 "register_operand" "")
8384         (mult:XF (match_operand:XF 1 "register_operand" "")
8385                  (match_operand:XF 2 "register_operand" "")))]
8386   "TARGET_80387"
8387   "")
8389 (define_expand "mul<mode>3"
8390   [(set (match_operand:MODEF 0 "register_operand" "")
8391         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8392                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8393   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8394   "")
8396 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8399 ;; Divide instructions
8401 (define_insn "divqi3"
8402   [(set (match_operand:QI 0 "register_operand" "=a")
8403         (div:QI (match_operand:HI 1 "register_operand" "0")
8404                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8405    (clobber (reg:CC FLAGS_REG))]
8406   "TARGET_QIMODE_MATH"
8407   "idiv{b}\t%2"
8408   [(set_attr "type" "idiv")
8409    (set_attr "mode" "QI")])
8411 (define_insn "udivqi3"
8412   [(set (match_operand:QI 0 "register_operand" "=a")
8413         (udiv:QI (match_operand:HI 1 "register_operand" "0")
8414                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8415    (clobber (reg:CC FLAGS_REG))]
8416   "TARGET_QIMODE_MATH"
8417   "div{b}\t%2"
8418   [(set_attr "type" "idiv")
8419    (set_attr "mode" "QI")])
8421 ;; The patterns that match these are at the end of this file.
8423 (define_expand "divxf3"
8424   [(set (match_operand:XF 0 "register_operand" "")
8425         (div:XF (match_operand:XF 1 "register_operand" "")
8426                 (match_operand:XF 2 "register_operand" "")))]
8427   "TARGET_80387"
8428   "")
8430 (define_expand "divdf3"
8431   [(set (match_operand:DF 0 "register_operand" "")
8432         (div:DF (match_operand:DF 1 "register_operand" "")
8433                 (match_operand:DF 2 "nonimmediate_operand" "")))]
8434    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8435    "")
8437 (define_expand "divsf3"
8438   [(set (match_operand:SF 0 "register_operand" "")
8439         (div:SF (match_operand:SF 1 "register_operand" "")
8440                 (match_operand:SF 2 "nonimmediate_operand" "")))]
8441   "TARGET_80387 || TARGET_SSE_MATH"
8443   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
8444       && flag_finite_math_only && !flag_trapping_math
8445       && flag_unsafe_math_optimizations)
8446     {
8447       ix86_emit_swdivsf (operands[0], operands[1],
8448                          operands[2], SFmode);
8449       DONE;
8450     }
8453 ;; Remainder instructions.
8455 (define_expand "divmoddi4"
8456   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8457                    (div:DI (match_operand:DI 1 "register_operand" "")
8458                            (match_operand:DI 2 "nonimmediate_operand" "")))
8459               (set (match_operand:DI 3 "register_operand" "")
8460                    (mod:DI (match_dup 1) (match_dup 2)))
8461               (clobber (reg:CC FLAGS_REG))])]
8462   "TARGET_64BIT"
8463   "")
8465 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8466 ;; Penalize eax case slightly because it results in worse scheduling
8467 ;; of code.
8468 (define_insn "*divmoddi4_nocltd_rex64"
8469   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8470         (div:DI (match_operand:DI 2 "register_operand" "1,0")
8471                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8472    (set (match_operand:DI 1 "register_operand" "=&d,&d")
8473         (mod:DI (match_dup 2) (match_dup 3)))
8474    (clobber (reg:CC FLAGS_REG))]
8475   "TARGET_64BIT && optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8476   "#"
8477   [(set_attr "type" "multi")])
8479 (define_insn "*divmoddi4_cltd_rex64"
8480   [(set (match_operand:DI 0 "register_operand" "=a")
8481         (div:DI (match_operand:DI 2 "register_operand" "a")
8482                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8483    (set (match_operand:DI 1 "register_operand" "=&d")
8484         (mod:DI (match_dup 2) (match_dup 3)))
8485    (clobber (reg:CC FLAGS_REG))]
8486   "TARGET_64BIT && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)"
8487   "#"
8488   [(set_attr "type" "multi")])
8490 (define_insn "*divmoddi_noext_rex64"
8491   [(set (match_operand:DI 0 "register_operand" "=a")
8492         (div:DI (match_operand:DI 1 "register_operand" "0")
8493                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8494    (set (match_operand:DI 3 "register_operand" "=d")
8495         (mod:DI (match_dup 1) (match_dup 2)))
8496    (use (match_operand:DI 4 "register_operand" "3"))
8497    (clobber (reg:CC FLAGS_REG))]
8498   "TARGET_64BIT"
8499   "idiv{q}\t%2"
8500   [(set_attr "type" "idiv")
8501    (set_attr "mode" "DI")])
8503 (define_split
8504   [(set (match_operand:DI 0 "register_operand" "")
8505         (div:DI (match_operand:DI 1 "register_operand" "")
8506                 (match_operand:DI 2 "nonimmediate_operand" "")))
8507    (set (match_operand:DI 3 "register_operand" "")
8508         (mod:DI (match_dup 1) (match_dup 2)))
8509    (clobber (reg:CC FLAGS_REG))]
8510   "TARGET_64BIT && reload_completed"
8511   [(parallel [(set (match_dup 3)
8512                    (ashiftrt:DI (match_dup 4) (const_int 63)))
8513               (clobber (reg:CC FLAGS_REG))])
8514    (parallel [(set (match_dup 0)
8515                    (div:DI (reg:DI 0) (match_dup 2)))
8516               (set (match_dup 3)
8517                    (mod:DI (reg:DI 0) (match_dup 2)))
8518               (use (match_dup 3))
8519               (clobber (reg:CC FLAGS_REG))])]
8521   /* Avoid use of cltd in favor of a mov+shift.  */
8522   if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8523     {
8524       if (true_regnum (operands[1]))
8525         emit_move_insn (operands[0], operands[1]);
8526       else
8527         emit_move_insn (operands[3], operands[1]);
8528       operands[4] = operands[3];
8529     }
8530   else
8531     {
8532       gcc_assert (!true_regnum (operands[1]));
8533       operands[4] = operands[1];
8534     }
8538 (define_expand "divmodsi4"
8539   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8540                    (div:SI (match_operand:SI 1 "register_operand" "")
8541                            (match_operand:SI 2 "nonimmediate_operand" "")))
8542               (set (match_operand:SI 3 "register_operand" "")
8543                    (mod:SI (match_dup 1) (match_dup 2)))
8544               (clobber (reg:CC FLAGS_REG))])]
8545   ""
8546   "")
8548 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8549 ;; Penalize eax case slightly because it results in worse scheduling
8550 ;; of code.
8551 (define_insn "*divmodsi4_nocltd"
8552   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8553         (div:SI (match_operand:SI 2 "register_operand" "1,0")
8554                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8555    (set (match_operand:SI 1 "register_operand" "=&d,&d")
8556         (mod:SI (match_dup 2) (match_dup 3)))
8557    (clobber (reg:CC FLAGS_REG))]
8558   "optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8559   "#"
8560   [(set_attr "type" "multi")])
8562 (define_insn "*divmodsi4_cltd"
8563   [(set (match_operand:SI 0 "register_operand" "=a")
8564         (div:SI (match_operand:SI 2 "register_operand" "a")
8565                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8566    (set (match_operand:SI 1 "register_operand" "=&d")
8567         (mod:SI (match_dup 2) (match_dup 3)))
8568    (clobber (reg:CC FLAGS_REG))]
8569   "optimize_function_for_size_p (cfun) || TARGET_USE_CLTD"
8570   "#"
8571   [(set_attr "type" "multi")])
8573 (define_insn "*divmodsi_noext"
8574   [(set (match_operand:SI 0 "register_operand" "=a")
8575         (div:SI (match_operand:SI 1 "register_operand" "0")
8576                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8577    (set (match_operand:SI 3 "register_operand" "=d")
8578         (mod:SI (match_dup 1) (match_dup 2)))
8579    (use (match_operand:SI 4 "register_operand" "3"))
8580    (clobber (reg:CC FLAGS_REG))]
8581   ""
8582   "idiv{l}\t%2"
8583   [(set_attr "type" "idiv")
8584    (set_attr "mode" "SI")])
8586 (define_split
8587   [(set (match_operand:SI 0 "register_operand" "")
8588         (div:SI (match_operand:SI 1 "register_operand" "")
8589                 (match_operand:SI 2 "nonimmediate_operand" "")))
8590    (set (match_operand:SI 3 "register_operand" "")
8591         (mod:SI (match_dup 1) (match_dup 2)))
8592    (clobber (reg:CC FLAGS_REG))]
8593   "reload_completed"
8594   [(parallel [(set (match_dup 3)
8595                    (ashiftrt:SI (match_dup 4) (const_int 31)))
8596               (clobber (reg:CC FLAGS_REG))])
8597    (parallel [(set (match_dup 0)
8598                    (div:SI (reg:SI 0) (match_dup 2)))
8599               (set (match_dup 3)
8600                    (mod:SI (reg:SI 0) (match_dup 2)))
8601               (use (match_dup 3))
8602               (clobber (reg:CC FLAGS_REG))])]
8604   /* Avoid use of cltd in favor of a mov+shift.  */
8605   if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8606     {
8607       if (true_regnum (operands[1]))
8608         emit_move_insn (operands[0], operands[1]);
8609       else
8610         emit_move_insn (operands[3], operands[1]);
8611       operands[4] = operands[3];
8612     }
8613   else
8614     {
8615       gcc_assert (!true_regnum (operands[1]));
8616       operands[4] = operands[1];
8617     }
8619 ;; %%% Split me.
8620 (define_insn "divmodhi4"
8621   [(set (match_operand:HI 0 "register_operand" "=a")
8622         (div:HI (match_operand:HI 1 "register_operand" "0")
8623                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8624    (set (match_operand:HI 3 "register_operand" "=&d")
8625         (mod:HI (match_dup 1) (match_dup 2)))
8626    (clobber (reg:CC FLAGS_REG))]
8627   "TARGET_HIMODE_MATH"
8628   "cwtd\;idiv{w}\t%2"
8629   [(set_attr "type" "multi")
8630    (set_attr "length_immediate" "0")
8631    (set_attr "mode" "SI")])
8633 (define_insn "udivmoddi4"
8634   [(set (match_operand:DI 0 "register_operand" "=a")
8635         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8636                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8637    (set (match_operand:DI 3 "register_operand" "=&d")
8638         (umod:DI (match_dup 1) (match_dup 2)))
8639    (clobber (reg:CC FLAGS_REG))]
8640   "TARGET_64BIT"
8641   "xor{q}\t%3, %3\;div{q}\t%2"
8642   [(set_attr "type" "multi")
8643    (set_attr "length_immediate" "0")
8644    (set_attr "mode" "DI")])
8646 (define_insn "*udivmoddi4_noext"
8647   [(set (match_operand:DI 0 "register_operand" "=a")
8648         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8649                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8650    (set (match_operand:DI 3 "register_operand" "=d")
8651         (umod:DI (match_dup 1) (match_dup 2)))
8652    (use (match_dup 3))
8653    (clobber (reg:CC FLAGS_REG))]
8654   "TARGET_64BIT"
8655   "div{q}\t%2"
8656   [(set_attr "type" "idiv")
8657    (set_attr "mode" "DI")])
8659 (define_split
8660   [(set (match_operand:DI 0 "register_operand" "")
8661         (udiv:DI (match_operand:DI 1 "register_operand" "")
8662                  (match_operand:DI 2 "nonimmediate_operand" "")))
8663    (set (match_operand:DI 3 "register_operand" "")
8664         (umod:DI (match_dup 1) (match_dup 2)))
8665    (clobber (reg:CC FLAGS_REG))]
8666   "TARGET_64BIT && reload_completed"
8667   [(set (match_dup 3) (const_int 0))
8668    (parallel [(set (match_dup 0)
8669                    (udiv:DI (match_dup 1) (match_dup 2)))
8670               (set (match_dup 3)
8671                    (umod:DI (match_dup 1) (match_dup 2)))
8672               (use (match_dup 3))
8673               (clobber (reg:CC FLAGS_REG))])]
8674   "")
8676 (define_insn "udivmodsi4"
8677   [(set (match_operand:SI 0 "register_operand" "=a")
8678         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8679                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8680    (set (match_operand:SI 3 "register_operand" "=&d")
8681         (umod:SI (match_dup 1) (match_dup 2)))
8682    (clobber (reg:CC FLAGS_REG))]
8683   ""
8684   "xor{l}\t%3, %3\;div{l}\t%2"
8685   [(set_attr "type" "multi")
8686    (set_attr "length_immediate" "0")
8687    (set_attr "mode" "SI")])
8689 (define_insn "*udivmodsi4_noext"
8690   [(set (match_operand:SI 0 "register_operand" "=a")
8691         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8692                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8693    (set (match_operand:SI 3 "register_operand" "=d")
8694         (umod:SI (match_dup 1) (match_dup 2)))
8695    (use (match_dup 3))
8696    (clobber (reg:CC FLAGS_REG))]
8697   ""
8698   "div{l}\t%2"
8699   [(set_attr "type" "idiv")
8700    (set_attr "mode" "SI")])
8702 (define_split
8703   [(set (match_operand:SI 0 "register_operand" "")
8704         (udiv:SI (match_operand:SI 1 "register_operand" "")
8705                  (match_operand:SI 2 "nonimmediate_operand" "")))
8706    (set (match_operand:SI 3 "register_operand" "")
8707         (umod:SI (match_dup 1) (match_dup 2)))
8708    (clobber (reg:CC FLAGS_REG))]
8709   "reload_completed"
8710   [(set (match_dup 3) (const_int 0))
8711    (parallel [(set (match_dup 0)
8712                    (udiv:SI (match_dup 1) (match_dup 2)))
8713               (set (match_dup 3)
8714                    (umod:SI (match_dup 1) (match_dup 2)))
8715               (use (match_dup 3))
8716               (clobber (reg:CC FLAGS_REG))])]
8717   "")
8719 (define_expand "udivmodhi4"
8720   [(set (match_dup 4) (const_int 0))
8721    (parallel [(set (match_operand:HI 0 "register_operand" "")
8722                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8723                             (match_operand:HI 2 "nonimmediate_operand" "")))
8724               (set (match_operand:HI 3 "register_operand" "")
8725                    (umod:HI (match_dup 1) (match_dup 2)))
8726               (use (match_dup 4))
8727               (clobber (reg:CC FLAGS_REG))])]
8728   "TARGET_HIMODE_MATH"
8729   "operands[4] = gen_reg_rtx (HImode);")
8731 (define_insn "*udivmodhi_noext"
8732   [(set (match_operand:HI 0 "register_operand" "=a")
8733         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8734                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8735    (set (match_operand:HI 3 "register_operand" "=d")
8736         (umod:HI (match_dup 1) (match_dup 2)))
8737    (use (match_operand:HI 4 "register_operand" "3"))
8738    (clobber (reg:CC FLAGS_REG))]
8739   ""
8740   "div{w}\t%2"
8741   [(set_attr "type" "idiv")
8742    (set_attr "mode" "HI")])
8744 ;; We cannot use div/idiv for double division, because it causes
8745 ;; "division by zero" on the overflow and that's not what we expect
8746 ;; from truncate.  Because true (non truncating) double division is
8747 ;; never generated, we can't create this insn anyway.
8749 ;(define_insn ""
8750 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8751 ;       (truncate:SI
8752 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8753 ;                  (zero_extend:DI
8754 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8755 ;   (set (match_operand:SI 3 "register_operand" "=d")
8756 ;       (truncate:SI
8757 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8758 ;   (clobber (reg:CC FLAGS_REG))]
8759 ;  ""
8760 ;  "div{l}\t{%2, %0|%0, %2}"
8761 ;  [(set_attr "type" "idiv")])
8763 ;;- Logical AND instructions
8765 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8766 ;; Note that this excludes ah.
8768 (define_insn "*testdi_1_rex64"
8769   [(set (reg FLAGS_REG)
8770         (compare
8771           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8772                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8773           (const_int 0)))]
8774   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8775    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8776   "@
8777    test{l}\t{%k1, %k0|%k0, %k1}
8778    test{l}\t{%k1, %k0|%k0, %k1}
8779    test{q}\t{%1, %0|%0, %1}
8780    test{q}\t{%1, %0|%0, %1}
8781    test{q}\t{%1, %0|%0, %1}"
8782   [(set_attr "type" "test")
8783    (set_attr "modrm" "0,1,0,1,1")
8784    (set_attr "mode" "SI,SI,DI,DI,DI")
8785    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8787 (define_insn "testsi_1"
8788   [(set (reg FLAGS_REG)
8789         (compare
8790           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8791                   (match_operand:SI 1 "general_operand" "i,i,ri"))
8792           (const_int 0)))]
8793   "ix86_match_ccmode (insn, CCNOmode)
8794    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8795   "test{l}\t{%1, %0|%0, %1}"
8796   [(set_attr "type" "test")
8797    (set_attr "modrm" "0,1,1")
8798    (set_attr "mode" "SI")
8799    (set_attr "pent_pair" "uv,np,uv")])
8801 (define_expand "testsi_ccno_1"
8802   [(set (reg:CCNO FLAGS_REG)
8803         (compare:CCNO
8804           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8805                   (match_operand:SI 1 "nonmemory_operand" ""))
8806           (const_int 0)))]
8807   ""
8808   "")
8810 (define_insn "*testhi_1"
8811   [(set (reg FLAGS_REG)
8812         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8813                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8814                  (const_int 0)))]
8815   "ix86_match_ccmode (insn, CCNOmode)
8816    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8817   "test{w}\t{%1, %0|%0, %1}"
8818   [(set_attr "type" "test")
8819    (set_attr "modrm" "0,1,1")
8820    (set_attr "mode" "HI")
8821    (set_attr "pent_pair" "uv,np,uv")])
8823 (define_expand "testqi_ccz_1"
8824   [(set (reg:CCZ FLAGS_REG)
8825         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8826                              (match_operand:QI 1 "nonmemory_operand" ""))
8827                  (const_int 0)))]
8828   ""
8829   "")
8831 (define_insn "*testqi_1_maybe_si"
8832   [(set (reg FLAGS_REG)
8833         (compare
8834           (and:QI
8835             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8836             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8837           (const_int 0)))]
8838    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8839     && ix86_match_ccmode (insn,
8840                          CONST_INT_P (operands[1])
8841                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8843   if (which_alternative == 3)
8844     {
8845       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8846         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8847       return "test{l}\t{%1, %k0|%k0, %1}";
8848     }
8849   return "test{b}\t{%1, %0|%0, %1}";
8851   [(set_attr "type" "test")
8852    (set_attr "modrm" "0,1,1,1")
8853    (set_attr "mode" "QI,QI,QI,SI")
8854    (set_attr "pent_pair" "uv,np,uv,np")])
8856 (define_insn "*testqi_1"
8857   [(set (reg FLAGS_REG)
8858         (compare
8859           (and:QI
8860             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8861             (match_operand:QI 1 "general_operand" "n,n,qn"))
8862           (const_int 0)))]
8863   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8864    && ix86_match_ccmode (insn, CCNOmode)"
8865   "test{b}\t{%1, %0|%0, %1}"
8866   [(set_attr "type" "test")
8867    (set_attr "modrm" "0,1,1")
8868    (set_attr "mode" "QI")
8869    (set_attr "pent_pair" "uv,np,uv")])
8871 (define_expand "testqi_ext_ccno_0"
8872   [(set (reg:CCNO FLAGS_REG)
8873         (compare:CCNO
8874           (and:SI
8875             (zero_extract:SI
8876               (match_operand 0 "ext_register_operand" "")
8877               (const_int 8)
8878               (const_int 8))
8879             (match_operand 1 "const_int_operand" ""))
8880           (const_int 0)))]
8881   ""
8882   "")
8884 (define_insn "*testqi_ext_0"
8885   [(set (reg FLAGS_REG)
8886         (compare
8887           (and:SI
8888             (zero_extract:SI
8889               (match_operand 0 "ext_register_operand" "Q")
8890               (const_int 8)
8891               (const_int 8))
8892             (match_operand 1 "const_int_operand" "n"))
8893           (const_int 0)))]
8894   "ix86_match_ccmode (insn, CCNOmode)"
8895   "test{b}\t{%1, %h0|%h0, %1}"
8896   [(set_attr "type" "test")
8897    (set_attr "mode" "QI")
8898    (set_attr "length_immediate" "1")
8899    (set_attr "pent_pair" "np")])
8901 (define_insn "*testqi_ext_1"
8902   [(set (reg FLAGS_REG)
8903         (compare
8904           (and:SI
8905             (zero_extract:SI
8906               (match_operand 0 "ext_register_operand" "Q")
8907               (const_int 8)
8908               (const_int 8))
8909             (zero_extend:SI
8910               (match_operand:QI 1 "general_operand" "Qm")))
8911           (const_int 0)))]
8912   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8913    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8914   "test{b}\t{%1, %h0|%h0, %1}"
8915   [(set_attr "type" "test")
8916    (set_attr "mode" "QI")])
8918 (define_insn "*testqi_ext_1_rex64"
8919   [(set (reg FLAGS_REG)
8920         (compare
8921           (and:SI
8922             (zero_extract:SI
8923               (match_operand 0 "ext_register_operand" "Q")
8924               (const_int 8)
8925               (const_int 8))
8926             (zero_extend:SI
8927               (match_operand:QI 1 "register_operand" "Q")))
8928           (const_int 0)))]
8929   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8930   "test{b}\t{%1, %h0|%h0, %1}"
8931   [(set_attr "type" "test")
8932    (set_attr "mode" "QI")])
8934 (define_insn "*testqi_ext_2"
8935   [(set (reg FLAGS_REG)
8936         (compare
8937           (and:SI
8938             (zero_extract:SI
8939               (match_operand 0 "ext_register_operand" "Q")
8940               (const_int 8)
8941               (const_int 8))
8942             (zero_extract:SI
8943               (match_operand 1 "ext_register_operand" "Q")
8944               (const_int 8)
8945               (const_int 8)))
8946           (const_int 0)))]
8947   "ix86_match_ccmode (insn, CCNOmode)"
8948   "test{b}\t{%h1, %h0|%h0, %h1}"
8949   [(set_attr "type" "test")
8950    (set_attr "mode" "QI")])
8952 ;; Combine likes to form bit extractions for some tests.  Humor it.
8953 (define_insn "*testqi_ext_3"
8954   [(set (reg FLAGS_REG)
8955         (compare (zero_extract:SI
8956                    (match_operand 0 "nonimmediate_operand" "rm")
8957                    (match_operand:SI 1 "const_int_operand" "")
8958                    (match_operand:SI 2 "const_int_operand" ""))
8959                  (const_int 0)))]
8960   "ix86_match_ccmode (insn, CCNOmode)
8961    && INTVAL (operands[1]) > 0
8962    && INTVAL (operands[2]) >= 0
8963    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8964    && (GET_MODE (operands[0]) == SImode
8965        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8966        || GET_MODE (operands[0]) == HImode
8967        || GET_MODE (operands[0]) == QImode)"
8968   "#")
8970 (define_insn "*testqi_ext_3_rex64"
8971   [(set (reg FLAGS_REG)
8972         (compare (zero_extract:DI
8973                    (match_operand 0 "nonimmediate_operand" "rm")
8974                    (match_operand:DI 1 "const_int_operand" "")
8975                    (match_operand:DI 2 "const_int_operand" ""))
8976                  (const_int 0)))]
8977   "TARGET_64BIT
8978    && ix86_match_ccmode (insn, CCNOmode)
8979    && INTVAL (operands[1]) > 0
8980    && INTVAL (operands[2]) >= 0
8981    /* Ensure that resulting mask is zero or sign extended operand.  */
8982    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8983        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8984            && INTVAL (operands[1]) > 32))
8985    && (GET_MODE (operands[0]) == SImode
8986        || GET_MODE (operands[0]) == DImode
8987        || GET_MODE (operands[0]) == HImode
8988        || GET_MODE (operands[0]) == QImode)"
8989   "#")
8991 (define_split
8992   [(set (match_operand 0 "flags_reg_operand" "")
8993         (match_operator 1 "compare_operator"
8994           [(zero_extract
8995              (match_operand 2 "nonimmediate_operand" "")
8996              (match_operand 3 "const_int_operand" "")
8997              (match_operand 4 "const_int_operand" ""))
8998            (const_int 0)]))]
8999   "ix86_match_ccmode (insn, CCNOmode)"
9000   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
9002   rtx val = operands[2];
9003   HOST_WIDE_INT len = INTVAL (operands[3]);
9004   HOST_WIDE_INT pos = INTVAL (operands[4]);
9005   HOST_WIDE_INT mask;
9006   enum machine_mode mode, submode;
9008   mode = GET_MODE (val);
9009   if (MEM_P (val))
9010     {
9011       /* ??? Combine likes to put non-volatile mem extractions in QImode
9012          no matter the size of the test.  So find a mode that works.  */
9013       if (! MEM_VOLATILE_P (val))
9014         {
9015           mode = smallest_mode_for_size (pos + len, MODE_INT);
9016           val = adjust_address (val, mode, 0);
9017         }
9018     }
9019   else if (GET_CODE (val) == SUBREG
9020            && (submode = GET_MODE (SUBREG_REG (val)),
9021                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
9022            && pos + len <= GET_MODE_BITSIZE (submode))
9023     {
9024       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
9025       mode = submode;
9026       val = SUBREG_REG (val);
9027     }
9028   else if (mode == HImode && pos + len <= 8)
9029     {
9030       /* Small HImode tests can be converted to QImode.  */
9031       mode = QImode;
9032       val = gen_lowpart (QImode, val);
9033     }
9035   if (len == HOST_BITS_PER_WIDE_INT)
9036     mask = -1;
9037   else
9038     mask = ((HOST_WIDE_INT)1 << len) - 1;
9039   mask <<= pos;
9041   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
9044 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
9045 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
9046 ;; this is relatively important trick.
9047 ;; Do the conversion only post-reload to avoid limiting of the register class
9048 ;; to QI regs.
9049 (define_split
9050   [(set (match_operand 0 "flags_reg_operand" "")
9051         (match_operator 1 "compare_operator"
9052           [(and (match_operand 2 "register_operand" "")
9053                 (match_operand 3 "const_int_operand" ""))
9054            (const_int 0)]))]
9055    "reload_completed
9056     && QI_REG_P (operands[2])
9057     && GET_MODE (operands[2]) != QImode
9058     && ((ix86_match_ccmode (insn, CCZmode)
9059          && !(INTVAL (operands[3]) & ~(255 << 8)))
9060         || (ix86_match_ccmode (insn, CCNOmode)
9061             && !(INTVAL (operands[3]) & ~(127 << 8))))"
9062   [(set (match_dup 0)
9063         (match_op_dup 1
9064           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
9065                    (match_dup 3))
9066            (const_int 0)]))]
9067   "operands[2] = gen_lowpart (SImode, operands[2]);
9068    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
9070 (define_split
9071   [(set (match_operand 0 "flags_reg_operand" "")
9072         (match_operator 1 "compare_operator"
9073           [(and (match_operand 2 "nonimmediate_operand" "")
9074                 (match_operand 3 "const_int_operand" ""))
9075            (const_int 0)]))]
9076    "reload_completed
9077     && GET_MODE (operands[2]) != QImode
9078     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
9079     && ((ix86_match_ccmode (insn, CCZmode)
9080          && !(INTVAL (operands[3]) & ~255))
9081         || (ix86_match_ccmode (insn, CCNOmode)
9082             && !(INTVAL (operands[3]) & ~127)))"
9083   [(set (match_dup 0)
9084         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
9085                          (const_int 0)]))]
9086   "operands[2] = gen_lowpart (QImode, operands[2]);
9087    operands[3] = gen_lowpart (QImode, operands[3]);")
9090 ;; %%% This used to optimize known byte-wide and operations to memory,
9091 ;; and sometimes to QImode registers.  If this is considered useful,
9092 ;; it should be done with splitters.
9094 (define_expand "anddi3"
9095   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9096         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
9097                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
9098   "TARGET_64BIT"
9099   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
9101 (define_insn "*anddi_1_rex64"
9102   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
9103         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
9104                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
9105    (clobber (reg:CC FLAGS_REG))]
9106   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9108   switch (get_attr_type (insn))
9109     {
9110     case TYPE_IMOVX:
9111       {
9112         enum machine_mode mode;
9114         gcc_assert (CONST_INT_P (operands[2]));
9115         if (INTVAL (operands[2]) == 0xff)
9116           mode = QImode;
9117         else
9118           {
9119             gcc_assert (INTVAL (operands[2]) == 0xffff);
9120             mode = HImode;
9121           }
9123         operands[1] = gen_lowpart (mode, operands[1]);
9124         if (mode == QImode)
9125           return "movz{bq|x}\t{%1,%0|%0, %1}";
9126         else
9127           return "movz{wq|x}\t{%1,%0|%0, %1}";
9128       }
9130     default:
9131       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9132       if (get_attr_mode (insn) == MODE_SI)
9133         return "and{l}\t{%k2, %k0|%k0, %k2}";
9134       else
9135         return "and{q}\t{%2, %0|%0, %2}";
9136     }
9138   [(set_attr "type" "alu,alu,alu,imovx")
9139    (set_attr "length_immediate" "*,*,*,0")
9140    (set_attr "mode" "SI,DI,DI,DI")])
9142 (define_insn "*anddi_2"
9143   [(set (reg FLAGS_REG)
9144         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9145                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9146                  (const_int 0)))
9147    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9148         (and:DI (match_dup 1) (match_dup 2)))]
9149   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9150    && ix86_binary_operator_ok (AND, DImode, operands)"
9151   "@
9152    and{l}\t{%k2, %k0|%k0, %k2}
9153    and{q}\t{%2, %0|%0, %2}
9154    and{q}\t{%2, %0|%0, %2}"
9155   [(set_attr "type" "alu")
9156    (set_attr "mode" "SI,DI,DI")])
9158 (define_expand "andsi3"
9159   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9160         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
9161                 (match_operand:SI 2 "general_operand" "")))]
9162   ""
9163   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
9165 (define_insn "*andsi_1"
9166   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
9167         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
9168                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
9169    (clobber (reg:CC FLAGS_REG))]
9170   "ix86_binary_operator_ok (AND, SImode, operands)"
9172   switch (get_attr_type (insn))
9173     {
9174     case TYPE_IMOVX:
9175       {
9176         enum machine_mode mode;
9178         gcc_assert (CONST_INT_P (operands[2]));
9179         if (INTVAL (operands[2]) == 0xff)
9180           mode = QImode;
9181         else
9182           {
9183             gcc_assert (INTVAL (operands[2]) == 0xffff);
9184             mode = HImode;
9185           }
9187         operands[1] = gen_lowpart (mode, operands[1]);
9188         if (mode == QImode)
9189           return "movz{bl|x}\t{%1,%0|%0, %1}";
9190         else
9191           return "movz{wl|x}\t{%1,%0|%0, %1}";
9192       }
9194     default:
9195       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9196       return "and{l}\t{%2, %0|%0, %2}";
9197     }
9199   [(set_attr "type" "alu,alu,imovx")
9200    (set_attr "length_immediate" "*,*,0")
9201    (set_attr "mode" "SI")])
9203 (define_split
9204   [(set (match_operand 0 "register_operand" "")
9205         (and (match_dup 0)
9206              (const_int -65536)))
9207    (clobber (reg:CC FLAGS_REG))]
9208   "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9209   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9210   "operands[1] = gen_lowpart (HImode, operands[0]);")
9212 (define_split
9213   [(set (match_operand 0 "ext_register_operand" "")
9214         (and (match_dup 0)
9215              (const_int -256)))
9216    (clobber (reg:CC FLAGS_REG))]
9217   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9218   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9219   "operands[1] = gen_lowpart (QImode, operands[0]);")
9221 (define_split
9222   [(set (match_operand 0 "ext_register_operand" "")
9223         (and (match_dup 0)
9224              (const_int -65281)))
9225    (clobber (reg:CC FLAGS_REG))]
9226   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9227   [(parallel [(set (zero_extract:SI (match_dup 0)
9228                                     (const_int 8)
9229                                     (const_int 8))
9230                    (xor:SI
9231                      (zero_extract:SI (match_dup 0)
9232                                       (const_int 8)
9233                                       (const_int 8))
9234                      (zero_extract:SI (match_dup 0)
9235                                       (const_int 8)
9236                                       (const_int 8))))
9237               (clobber (reg:CC FLAGS_REG))])]
9238   "operands[0] = gen_lowpart (SImode, operands[0]);")
9240 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9241 (define_insn "*andsi_1_zext"
9242   [(set (match_operand:DI 0 "register_operand" "=r")
9243         (zero_extend:DI
9244           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9245                   (match_operand:SI 2 "general_operand" "g"))))
9246    (clobber (reg:CC FLAGS_REG))]
9247   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9248   "and{l}\t{%2, %k0|%k0, %2}"
9249   [(set_attr "type" "alu")
9250    (set_attr "mode" "SI")])
9252 (define_insn "*andsi_2"
9253   [(set (reg FLAGS_REG)
9254         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9255                          (match_operand:SI 2 "general_operand" "g,ri"))
9256                  (const_int 0)))
9257    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9258         (and:SI (match_dup 1) (match_dup 2)))]
9259   "ix86_match_ccmode (insn, CCNOmode)
9260    && ix86_binary_operator_ok (AND, SImode, operands)"
9261   "and{l}\t{%2, %0|%0, %2}"
9262   [(set_attr "type" "alu")
9263    (set_attr "mode" "SI")])
9265 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9266 (define_insn "*andsi_2_zext"
9267   [(set (reg FLAGS_REG)
9268         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9269                          (match_operand:SI 2 "general_operand" "g"))
9270                  (const_int 0)))
9271    (set (match_operand:DI 0 "register_operand" "=r")
9272         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9273   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9274    && ix86_binary_operator_ok (AND, SImode, operands)"
9275   "and{l}\t{%2, %k0|%k0, %2}"
9276   [(set_attr "type" "alu")
9277    (set_attr "mode" "SI")])
9279 (define_expand "andhi3"
9280   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9281         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9282                 (match_operand:HI 2 "general_operand" "")))]
9283   "TARGET_HIMODE_MATH"
9284   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9286 (define_insn "*andhi_1"
9287   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9288         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9289                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9290    (clobber (reg:CC FLAGS_REG))]
9291   "ix86_binary_operator_ok (AND, HImode, operands)"
9293   switch (get_attr_type (insn))
9294     {
9295     case TYPE_IMOVX:
9296       gcc_assert (CONST_INT_P (operands[2]));
9297       gcc_assert (INTVAL (operands[2]) == 0xff);
9298       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9300     default:
9301       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9303       return "and{w}\t{%2, %0|%0, %2}";
9304     }
9306   [(set_attr "type" "alu,alu,imovx")
9307    (set_attr "length_immediate" "*,*,0")
9308    (set_attr "mode" "HI,HI,SI")])
9310 (define_insn "*andhi_2"
9311   [(set (reg FLAGS_REG)
9312         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9313                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9314                  (const_int 0)))
9315    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9316         (and:HI (match_dup 1) (match_dup 2)))]
9317   "ix86_match_ccmode (insn, CCNOmode)
9318    && ix86_binary_operator_ok (AND, HImode, operands)"
9319   "and{w}\t{%2, %0|%0, %2}"
9320   [(set_attr "type" "alu")
9321    (set_attr "mode" "HI")])
9323 (define_expand "andqi3"
9324   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9325         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9326                 (match_operand:QI 2 "general_operand" "")))]
9327   "TARGET_QIMODE_MATH"
9328   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9330 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9331 (define_insn "*andqi_1"
9332   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9333         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9334                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9335    (clobber (reg:CC FLAGS_REG))]
9336   "ix86_binary_operator_ok (AND, QImode, operands)"
9337   "@
9338    and{b}\t{%2, %0|%0, %2}
9339    and{b}\t{%2, %0|%0, %2}
9340    and{l}\t{%k2, %k0|%k0, %k2}"
9341   [(set_attr "type" "alu")
9342    (set_attr "mode" "QI,QI,SI")])
9344 (define_insn "*andqi_1_slp"
9345   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9346         (and:QI (match_dup 0)
9347                 (match_operand:QI 1 "general_operand" "qn,qmn")))
9348    (clobber (reg:CC FLAGS_REG))]
9349   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9350    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9351   "and{b}\t{%1, %0|%0, %1}"
9352   [(set_attr "type" "alu1")
9353    (set_attr "mode" "QI")])
9355 (define_insn "*andqi_2_maybe_si"
9356   [(set (reg FLAGS_REG)
9357         (compare (and:QI
9358                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9359                       (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9360                  (const_int 0)))
9361    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9362         (and:QI (match_dup 1) (match_dup 2)))]
9363   "ix86_binary_operator_ok (AND, QImode, operands)
9364    && ix86_match_ccmode (insn,
9365                          CONST_INT_P (operands[2])
9366                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9368   if (which_alternative == 2)
9369     {
9370       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9371         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9372       return "and{l}\t{%2, %k0|%k0, %2}";
9373     }
9374   return "and{b}\t{%2, %0|%0, %2}";
9376   [(set_attr "type" "alu")
9377    (set_attr "mode" "QI,QI,SI")])
9379 (define_insn "*andqi_2"
9380   [(set (reg FLAGS_REG)
9381         (compare (and:QI
9382                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9383                    (match_operand:QI 2 "general_operand" "qmn,qn"))
9384                  (const_int 0)))
9385    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9386         (and:QI (match_dup 1) (match_dup 2)))]
9387   "ix86_match_ccmode (insn, CCNOmode)
9388    && ix86_binary_operator_ok (AND, QImode, operands)"
9389   "and{b}\t{%2, %0|%0, %2}"
9390   [(set_attr "type" "alu")
9391    (set_attr "mode" "QI")])
9393 (define_insn "*andqi_2_slp"
9394   [(set (reg FLAGS_REG)
9395         (compare (and:QI
9396                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9397                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9398                  (const_int 0)))
9399    (set (strict_low_part (match_dup 0))
9400         (and:QI (match_dup 0) (match_dup 1)))]
9401   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9402    && ix86_match_ccmode (insn, CCNOmode)
9403    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9404   "and{b}\t{%1, %0|%0, %1}"
9405   [(set_attr "type" "alu1")
9406    (set_attr "mode" "QI")])
9408 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9409 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
9410 ;; for a QImode operand, which of course failed.
9412 (define_insn "andqi_ext_0"
9413   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9414                          (const_int 8)
9415                          (const_int 8))
9416         (and:SI
9417           (zero_extract:SI
9418             (match_operand 1 "ext_register_operand" "0")
9419             (const_int 8)
9420             (const_int 8))
9421           (match_operand 2 "const_int_operand" "n")))
9422    (clobber (reg:CC FLAGS_REG))]
9423   ""
9424   "and{b}\t{%2, %h0|%h0, %2}"
9425   [(set_attr "type" "alu")
9426    (set_attr "length_immediate" "1")
9427    (set_attr "mode" "QI")])
9429 ;; Generated by peephole translating test to and.  This shows up
9430 ;; often in fp comparisons.
9432 (define_insn "*andqi_ext_0_cc"
9433   [(set (reg FLAGS_REG)
9434         (compare
9435           (and:SI
9436             (zero_extract:SI
9437               (match_operand 1 "ext_register_operand" "0")
9438               (const_int 8)
9439               (const_int 8))
9440             (match_operand 2 "const_int_operand" "n"))
9441           (const_int 0)))
9442    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9443                          (const_int 8)
9444                          (const_int 8))
9445         (and:SI
9446           (zero_extract:SI
9447             (match_dup 1)
9448             (const_int 8)
9449             (const_int 8))
9450           (match_dup 2)))]
9451   "ix86_match_ccmode (insn, CCNOmode)"
9452   "and{b}\t{%2, %h0|%h0, %2}"
9453   [(set_attr "type" "alu")
9454    (set_attr "length_immediate" "1")
9455    (set_attr "mode" "QI")])
9457 (define_insn "*andqi_ext_1"
9458   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9459                          (const_int 8)
9460                          (const_int 8))
9461         (and:SI
9462           (zero_extract:SI
9463             (match_operand 1 "ext_register_operand" "0")
9464             (const_int 8)
9465             (const_int 8))
9466           (zero_extend:SI
9467             (match_operand:QI 2 "general_operand" "Qm"))))
9468    (clobber (reg:CC FLAGS_REG))]
9469   "!TARGET_64BIT"
9470   "and{b}\t{%2, %h0|%h0, %2}"
9471   [(set_attr "type" "alu")
9472    (set_attr "length_immediate" "0")
9473    (set_attr "mode" "QI")])
9475 (define_insn "*andqi_ext_1_rex64"
9476   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9477                          (const_int 8)
9478                          (const_int 8))
9479         (and:SI
9480           (zero_extract:SI
9481             (match_operand 1 "ext_register_operand" "0")
9482             (const_int 8)
9483             (const_int 8))
9484           (zero_extend:SI
9485             (match_operand 2 "ext_register_operand" "Q"))))
9486    (clobber (reg:CC FLAGS_REG))]
9487   "TARGET_64BIT"
9488   "and{b}\t{%2, %h0|%h0, %2}"
9489   [(set_attr "type" "alu")
9490    (set_attr "length_immediate" "0")
9491    (set_attr "mode" "QI")])
9493 (define_insn "*andqi_ext_2"
9494   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9495                          (const_int 8)
9496                          (const_int 8))
9497         (and:SI
9498           (zero_extract:SI
9499             (match_operand 1 "ext_register_operand" "%0")
9500             (const_int 8)
9501             (const_int 8))
9502           (zero_extract:SI
9503             (match_operand 2 "ext_register_operand" "Q")
9504             (const_int 8)
9505             (const_int 8))))
9506    (clobber (reg:CC FLAGS_REG))]
9507   ""
9508   "and{b}\t{%h2, %h0|%h0, %h2}"
9509   [(set_attr "type" "alu")
9510    (set_attr "length_immediate" "0")
9511    (set_attr "mode" "QI")])
9513 ;; Convert wide AND instructions with immediate operand to shorter QImode
9514 ;; equivalents when possible.
9515 ;; Don't do the splitting with memory operands, since it introduces risk
9516 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9517 ;; for size, but that can (should?) be handled by generic code instead.
9518 (define_split
9519   [(set (match_operand 0 "register_operand" "")
9520         (and (match_operand 1 "register_operand" "")
9521              (match_operand 2 "const_int_operand" "")))
9522    (clobber (reg:CC FLAGS_REG))]
9523    "reload_completed
9524     && QI_REG_P (operands[0])
9525     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9526     && !(~INTVAL (operands[2]) & ~(255 << 8))
9527     && GET_MODE (operands[0]) != QImode"
9528   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9529                    (and:SI (zero_extract:SI (match_dup 1)
9530                                             (const_int 8) (const_int 8))
9531                            (match_dup 2)))
9532               (clobber (reg:CC FLAGS_REG))])]
9533   "operands[0] = gen_lowpart (SImode, operands[0]);
9534    operands[1] = gen_lowpart (SImode, operands[1]);
9535    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9537 ;; Since AND can be encoded with sign extended immediate, this is only
9538 ;; profitable when 7th bit is not set.
9539 (define_split
9540   [(set (match_operand 0 "register_operand" "")
9541         (and (match_operand 1 "general_operand" "")
9542              (match_operand 2 "const_int_operand" "")))
9543    (clobber (reg:CC FLAGS_REG))]
9544    "reload_completed
9545     && ANY_QI_REG_P (operands[0])
9546     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9547     && !(~INTVAL (operands[2]) & ~255)
9548     && !(INTVAL (operands[2]) & 128)
9549     && GET_MODE (operands[0]) != QImode"
9550   [(parallel [(set (strict_low_part (match_dup 0))
9551                    (and:QI (match_dup 1)
9552                            (match_dup 2)))
9553               (clobber (reg:CC FLAGS_REG))])]
9554   "operands[0] = gen_lowpart (QImode, operands[0]);
9555    operands[1] = gen_lowpart (QImode, operands[1]);
9556    operands[2] = gen_lowpart (QImode, operands[2]);")
9558 ;; Logical inclusive OR instructions
9560 ;; %%% This used to optimize known byte-wide and operations to memory.
9561 ;; If this is considered useful, it should be done with splitters.
9563 (define_expand "iordi3"
9564   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9565         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9566                 (match_operand:DI 2 "x86_64_general_operand" "")))]
9567   "TARGET_64BIT"
9568   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9570 (define_insn "*iordi_1_rex64"
9571   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9572         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9573                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9574    (clobber (reg:CC FLAGS_REG))]
9575   "TARGET_64BIT
9576    && ix86_binary_operator_ok (IOR, DImode, operands)"
9577   "or{q}\t{%2, %0|%0, %2}"
9578   [(set_attr "type" "alu")
9579    (set_attr "mode" "DI")])
9581 (define_insn "*iordi_2_rex64"
9582   [(set (reg FLAGS_REG)
9583         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9584                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9585                  (const_int 0)))
9586    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9587         (ior:DI (match_dup 1) (match_dup 2)))]
9588   "TARGET_64BIT
9589    && ix86_match_ccmode (insn, CCNOmode)
9590    && ix86_binary_operator_ok (IOR, DImode, operands)"
9591   "or{q}\t{%2, %0|%0, %2}"
9592   [(set_attr "type" "alu")
9593    (set_attr "mode" "DI")])
9595 (define_insn "*iordi_3_rex64"
9596   [(set (reg FLAGS_REG)
9597         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9598                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9599                  (const_int 0)))
9600    (clobber (match_scratch:DI 0 "=r"))]
9601   "TARGET_64BIT
9602    && ix86_match_ccmode (insn, CCNOmode)
9603    && ix86_binary_operator_ok (IOR, DImode, operands)"
9604   "or{q}\t{%2, %0|%0, %2}"
9605   [(set_attr "type" "alu")
9606    (set_attr "mode" "DI")])
9609 (define_expand "iorsi3"
9610   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9611         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9612                 (match_operand:SI 2 "general_operand" "")))]
9613   ""
9614   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9616 (define_insn "*iorsi_1"
9617   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9618         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9619                 (match_operand:SI 2 "general_operand" "ri,g")))
9620    (clobber (reg:CC FLAGS_REG))]
9621   "ix86_binary_operator_ok (IOR, SImode, operands)"
9622   "or{l}\t{%2, %0|%0, %2}"
9623   [(set_attr "type" "alu")
9624    (set_attr "mode" "SI")])
9626 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9627 (define_insn "*iorsi_1_zext"
9628   [(set (match_operand:DI 0 "register_operand" "=r")
9629         (zero_extend:DI
9630           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9631                   (match_operand:SI 2 "general_operand" "g"))))
9632    (clobber (reg:CC FLAGS_REG))]
9633   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9634   "or{l}\t{%2, %k0|%k0, %2}"
9635   [(set_attr "type" "alu")
9636    (set_attr "mode" "SI")])
9638 (define_insn "*iorsi_1_zext_imm"
9639   [(set (match_operand:DI 0 "register_operand" "=r")
9640         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9641                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9642    (clobber (reg:CC FLAGS_REG))]
9643   "TARGET_64BIT"
9644   "or{l}\t{%2, %k0|%k0, %2}"
9645   [(set_attr "type" "alu")
9646    (set_attr "mode" "SI")])
9648 (define_insn "*iorsi_2"
9649   [(set (reg FLAGS_REG)
9650         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9651                          (match_operand:SI 2 "general_operand" "g,ri"))
9652                  (const_int 0)))
9653    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9654         (ior:SI (match_dup 1) (match_dup 2)))]
9655   "ix86_match_ccmode (insn, CCNOmode)
9656    && ix86_binary_operator_ok (IOR, SImode, operands)"
9657   "or{l}\t{%2, %0|%0, %2}"
9658   [(set_attr "type" "alu")
9659    (set_attr "mode" "SI")])
9661 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9662 ;; ??? Special case for immediate operand is missing - it is tricky.
9663 (define_insn "*iorsi_2_zext"
9664   [(set (reg FLAGS_REG)
9665         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9666                          (match_operand:SI 2 "general_operand" "g"))
9667                  (const_int 0)))
9668    (set (match_operand:DI 0 "register_operand" "=r")
9669         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9670   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9671    && ix86_binary_operator_ok (IOR, SImode, operands)"
9672   "or{l}\t{%2, %k0|%k0, %2}"
9673   [(set_attr "type" "alu")
9674    (set_attr "mode" "SI")])
9676 (define_insn "*iorsi_2_zext_imm"
9677   [(set (reg FLAGS_REG)
9678         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9679                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9680                  (const_int 0)))
9681    (set (match_operand:DI 0 "register_operand" "=r")
9682         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9683   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9684    && ix86_binary_operator_ok (IOR, SImode, operands)"
9685   "or{l}\t{%2, %k0|%k0, %2}"
9686   [(set_attr "type" "alu")
9687    (set_attr "mode" "SI")])
9689 (define_insn "*iorsi_3"
9690   [(set (reg FLAGS_REG)
9691         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9692                          (match_operand:SI 2 "general_operand" "g"))
9693                  (const_int 0)))
9694    (clobber (match_scratch:SI 0 "=r"))]
9695   "ix86_match_ccmode (insn, CCNOmode)
9696    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9697   "or{l}\t{%2, %0|%0, %2}"
9698   [(set_attr "type" "alu")
9699    (set_attr "mode" "SI")])
9701 (define_expand "iorhi3"
9702   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9703         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9704                 (match_operand:HI 2 "general_operand" "")))]
9705   "TARGET_HIMODE_MATH"
9706   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9708 (define_insn "*iorhi_1"
9709   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9710         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9711                 (match_operand:HI 2 "general_operand" "rmn,rn")))
9712    (clobber (reg:CC FLAGS_REG))]
9713   "ix86_binary_operator_ok (IOR, HImode, operands)"
9714   "or{w}\t{%2, %0|%0, %2}"
9715   [(set_attr "type" "alu")
9716    (set_attr "mode" "HI")])
9718 (define_insn "*iorhi_2"
9719   [(set (reg FLAGS_REG)
9720         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9721                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9722                  (const_int 0)))
9723    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9724         (ior:HI (match_dup 1) (match_dup 2)))]
9725   "ix86_match_ccmode (insn, CCNOmode)
9726    && ix86_binary_operator_ok (IOR, HImode, operands)"
9727   "or{w}\t{%2, %0|%0, %2}"
9728   [(set_attr "type" "alu")
9729    (set_attr "mode" "HI")])
9731 (define_insn "*iorhi_3"
9732   [(set (reg FLAGS_REG)
9733         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9734                          (match_operand:HI 2 "general_operand" "rmn"))
9735                  (const_int 0)))
9736    (clobber (match_scratch:HI 0 "=r"))]
9737   "ix86_match_ccmode (insn, CCNOmode)
9738    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9739   "or{w}\t{%2, %0|%0, %2}"
9740   [(set_attr "type" "alu")
9741    (set_attr "mode" "HI")])
9743 (define_expand "iorqi3"
9744   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9745         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9746                 (match_operand:QI 2 "general_operand" "")))]
9747   "TARGET_QIMODE_MATH"
9748   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9750 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9751 (define_insn "*iorqi_1"
9752   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9753         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9754                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9755    (clobber (reg:CC FLAGS_REG))]
9756   "ix86_binary_operator_ok (IOR, QImode, operands)"
9757   "@
9758    or{b}\t{%2, %0|%0, %2}
9759    or{b}\t{%2, %0|%0, %2}
9760    or{l}\t{%k2, %k0|%k0, %k2}"
9761   [(set_attr "type" "alu")
9762    (set_attr "mode" "QI,QI,SI")])
9764 (define_insn "*iorqi_1_slp"
9765   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9766         (ior:QI (match_dup 0)
9767                 (match_operand:QI 1 "general_operand" "qmn,qn")))
9768    (clobber (reg:CC FLAGS_REG))]
9769   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9770    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9771   "or{b}\t{%1, %0|%0, %1}"
9772   [(set_attr "type" "alu1")
9773    (set_attr "mode" "QI")])
9775 (define_insn "*iorqi_2"
9776   [(set (reg FLAGS_REG)
9777         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9778                          (match_operand:QI 2 "general_operand" "qmn,qn"))
9779                  (const_int 0)))
9780    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9781         (ior:QI (match_dup 1) (match_dup 2)))]
9782   "ix86_match_ccmode (insn, CCNOmode)
9783    && ix86_binary_operator_ok (IOR, QImode, operands)"
9784   "or{b}\t{%2, %0|%0, %2}"
9785   [(set_attr "type" "alu")
9786    (set_attr "mode" "QI")])
9788 (define_insn "*iorqi_2_slp"
9789   [(set (reg FLAGS_REG)
9790         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9791                          (match_operand:QI 1 "general_operand" "qmn,qn"))
9792                  (const_int 0)))
9793    (set (strict_low_part (match_dup 0))
9794         (ior:QI (match_dup 0) (match_dup 1)))]
9795   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9796    && ix86_match_ccmode (insn, CCNOmode)
9797    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9798   "or{b}\t{%1, %0|%0, %1}"
9799   [(set_attr "type" "alu1")
9800    (set_attr "mode" "QI")])
9802 (define_insn "*iorqi_3"
9803   [(set (reg FLAGS_REG)
9804         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9805                          (match_operand:QI 2 "general_operand" "qmn"))
9806                  (const_int 0)))
9807    (clobber (match_scratch:QI 0 "=q"))]
9808   "ix86_match_ccmode (insn, CCNOmode)
9809    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9810   "or{b}\t{%2, %0|%0, %2}"
9811   [(set_attr "type" "alu")
9812    (set_attr "mode" "QI")])
9814 (define_insn "*iorqi_ext_0"
9815   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9816                          (const_int 8)
9817                          (const_int 8))
9818         (ior:SI
9819           (zero_extract:SI
9820             (match_operand 1 "ext_register_operand" "0")
9821             (const_int 8)
9822             (const_int 8))
9823           (match_operand 2 "const_int_operand" "n")))
9824    (clobber (reg:CC FLAGS_REG))]
9825   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9826   "or{b}\t{%2, %h0|%h0, %2}"
9827   [(set_attr "type" "alu")
9828    (set_attr "length_immediate" "1")
9829    (set_attr "mode" "QI")])
9831 (define_insn "*iorqi_ext_1"
9832   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9833                          (const_int 8)
9834                          (const_int 8))
9835         (ior:SI
9836           (zero_extract:SI
9837             (match_operand 1 "ext_register_operand" "0")
9838             (const_int 8)
9839             (const_int 8))
9840           (zero_extend:SI
9841             (match_operand:QI 2 "general_operand" "Qm"))))
9842    (clobber (reg:CC FLAGS_REG))]
9843   "!TARGET_64BIT
9844    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9845   "or{b}\t{%2, %h0|%h0, %2}"
9846   [(set_attr "type" "alu")
9847    (set_attr "length_immediate" "0")
9848    (set_attr "mode" "QI")])
9850 (define_insn "*iorqi_ext_1_rex64"
9851   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9852                          (const_int 8)
9853                          (const_int 8))
9854         (ior:SI
9855           (zero_extract:SI
9856             (match_operand 1 "ext_register_operand" "0")
9857             (const_int 8)
9858             (const_int 8))
9859           (zero_extend:SI
9860             (match_operand 2 "ext_register_operand" "Q"))))
9861    (clobber (reg:CC FLAGS_REG))]
9862   "TARGET_64BIT
9863    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9864   "or{b}\t{%2, %h0|%h0, %2}"
9865   [(set_attr "type" "alu")
9866    (set_attr "length_immediate" "0")
9867    (set_attr "mode" "QI")])
9869 (define_insn "*iorqi_ext_2"
9870   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9871                          (const_int 8)
9872                          (const_int 8))
9873         (ior:SI
9874           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9875                            (const_int 8)
9876                            (const_int 8))
9877           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9878                            (const_int 8)
9879                            (const_int 8))))
9880    (clobber (reg:CC FLAGS_REG))]
9881   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9882   "ior{b}\t{%h2, %h0|%h0, %h2}"
9883   [(set_attr "type" "alu")
9884    (set_attr "length_immediate" "0")
9885    (set_attr "mode" "QI")])
9887 (define_split
9888   [(set (match_operand 0 "register_operand" "")
9889         (ior (match_operand 1 "register_operand" "")
9890              (match_operand 2 "const_int_operand" "")))
9891    (clobber (reg:CC FLAGS_REG))]
9892    "reload_completed
9893     && QI_REG_P (operands[0])
9894     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9895     && !(INTVAL (operands[2]) & ~(255 << 8))
9896     && GET_MODE (operands[0]) != QImode"
9897   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9898                    (ior:SI (zero_extract:SI (match_dup 1)
9899                                             (const_int 8) (const_int 8))
9900                            (match_dup 2)))
9901               (clobber (reg:CC FLAGS_REG))])]
9902   "operands[0] = gen_lowpart (SImode, operands[0]);
9903    operands[1] = gen_lowpart (SImode, operands[1]);
9904    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9906 ;; Since OR can be encoded with sign extended immediate, this is only
9907 ;; profitable when 7th bit is set.
9908 (define_split
9909   [(set (match_operand 0 "register_operand" "")
9910         (ior (match_operand 1 "general_operand" "")
9911              (match_operand 2 "const_int_operand" "")))
9912    (clobber (reg:CC FLAGS_REG))]
9913    "reload_completed
9914     && ANY_QI_REG_P (operands[0])
9915     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9916     && !(INTVAL (operands[2]) & ~255)
9917     && (INTVAL (operands[2]) & 128)
9918     && GET_MODE (operands[0]) != QImode"
9919   [(parallel [(set (strict_low_part (match_dup 0))
9920                    (ior:QI (match_dup 1)
9921                            (match_dup 2)))
9922               (clobber (reg:CC FLAGS_REG))])]
9923   "operands[0] = gen_lowpart (QImode, operands[0]);
9924    operands[1] = gen_lowpart (QImode, operands[1]);
9925    operands[2] = gen_lowpart (QImode, operands[2]);")
9927 ;; Logical XOR instructions
9929 ;; %%% This used to optimize known byte-wide and operations to memory.
9930 ;; If this is considered useful, it should be done with splitters.
9932 (define_expand "xordi3"
9933   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9934         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9935                 (match_operand:DI 2 "x86_64_general_operand" "")))]
9936   "TARGET_64BIT"
9937   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9939 (define_insn "*xordi_1_rex64"
9940   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9941         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9942                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9943    (clobber (reg:CC FLAGS_REG))]
9944   "TARGET_64BIT
9945    && ix86_binary_operator_ok (XOR, DImode, operands)"
9946   "xor{q}\t{%2, %0|%0, %2}"
9947   [(set_attr "type" "alu")
9948    (set_attr "mode" "DI")])
9950 (define_insn "*xordi_2_rex64"
9951   [(set (reg FLAGS_REG)
9952         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9953                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9954                  (const_int 0)))
9955    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9956         (xor:DI (match_dup 1) (match_dup 2)))]
9957   "TARGET_64BIT
9958    && ix86_match_ccmode (insn, CCNOmode)
9959    && ix86_binary_operator_ok (XOR, DImode, operands)"
9960   "xor{q}\t{%2, %0|%0, %2}"
9961   [(set_attr "type" "alu")
9962    (set_attr "mode" "DI")])
9964 (define_insn "*xordi_3_rex64"
9965   [(set (reg FLAGS_REG)
9966         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9967                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9968                  (const_int 0)))
9969    (clobber (match_scratch:DI 0 "=r"))]
9970   "TARGET_64BIT
9971    && ix86_match_ccmode (insn, CCNOmode)
9972    && ix86_binary_operator_ok (XOR, DImode, operands)"
9973   "xor{q}\t{%2, %0|%0, %2}"
9974   [(set_attr "type" "alu")
9975    (set_attr "mode" "DI")])
9977 (define_expand "xorsi3"
9978   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9979         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9980                 (match_operand:SI 2 "general_operand" "")))]
9981   ""
9982   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9984 (define_insn "*xorsi_1"
9985   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9986         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9987                 (match_operand:SI 2 "general_operand" "ri,rm")))
9988    (clobber (reg:CC FLAGS_REG))]
9989   "ix86_binary_operator_ok (XOR, SImode, operands)"
9990   "xor{l}\t{%2, %0|%0, %2}"
9991   [(set_attr "type" "alu")
9992    (set_attr "mode" "SI")])
9994 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9995 ;; Add speccase for immediates
9996 (define_insn "*xorsi_1_zext"
9997   [(set (match_operand:DI 0 "register_operand" "=r")
9998         (zero_extend:DI
9999           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10000                   (match_operand:SI 2 "general_operand" "g"))))
10001    (clobber (reg:CC FLAGS_REG))]
10002   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10003   "xor{l}\t{%2, %k0|%k0, %2}"
10004   [(set_attr "type" "alu")
10005    (set_attr "mode" "SI")])
10007 (define_insn "*xorsi_1_zext_imm"
10008   [(set (match_operand:DI 0 "register_operand" "=r")
10009         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
10010                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
10011    (clobber (reg:CC FLAGS_REG))]
10012   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10013   "xor{l}\t{%2, %k0|%k0, %2}"
10014   [(set_attr "type" "alu")
10015    (set_attr "mode" "SI")])
10017 (define_insn "*xorsi_2"
10018   [(set (reg FLAGS_REG)
10019         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10020                          (match_operand:SI 2 "general_operand" "g,ri"))
10021                  (const_int 0)))
10022    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10023         (xor:SI (match_dup 1) (match_dup 2)))]
10024   "ix86_match_ccmode (insn, CCNOmode)
10025    && ix86_binary_operator_ok (XOR, SImode, operands)"
10026   "xor{l}\t{%2, %0|%0, %2}"
10027   [(set_attr "type" "alu")
10028    (set_attr "mode" "SI")])
10030 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10031 ;; ??? Special case for immediate operand is missing - it is tricky.
10032 (define_insn "*xorsi_2_zext"
10033   [(set (reg FLAGS_REG)
10034         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10035                          (match_operand:SI 2 "general_operand" "g"))
10036                  (const_int 0)))
10037    (set (match_operand:DI 0 "register_operand" "=r")
10038         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
10039   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10040    && ix86_binary_operator_ok (XOR, SImode, operands)"
10041   "xor{l}\t{%2, %k0|%k0, %2}"
10042   [(set_attr "type" "alu")
10043    (set_attr "mode" "SI")])
10045 (define_insn "*xorsi_2_zext_imm"
10046   [(set (reg FLAGS_REG)
10047         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10048                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10049                  (const_int 0)))
10050    (set (match_operand:DI 0 "register_operand" "=r")
10051         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10052   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10053    && ix86_binary_operator_ok (XOR, SImode, operands)"
10054   "xor{l}\t{%2, %k0|%k0, %2}"
10055   [(set_attr "type" "alu")
10056    (set_attr "mode" "SI")])
10058 (define_insn "*xorsi_3"
10059   [(set (reg FLAGS_REG)
10060         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10061                          (match_operand:SI 2 "general_operand" "g"))
10062                  (const_int 0)))
10063    (clobber (match_scratch:SI 0 "=r"))]
10064   "ix86_match_ccmode (insn, CCNOmode)
10065    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10066   "xor{l}\t{%2, %0|%0, %2}"
10067   [(set_attr "type" "alu")
10068    (set_attr "mode" "SI")])
10070 (define_expand "xorhi3"
10071   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10072         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
10073                 (match_operand:HI 2 "general_operand" "")))]
10074   "TARGET_HIMODE_MATH"
10075   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
10077 (define_insn "*xorhi_1"
10078   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10079         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10080                 (match_operand:HI 2 "general_operand" "rmn,rn")))
10081    (clobber (reg:CC FLAGS_REG))]
10082   "ix86_binary_operator_ok (XOR, HImode, operands)"
10083   "xor{w}\t{%2, %0|%0, %2}"
10084   [(set_attr "type" "alu")
10085    (set_attr "mode" "HI")])
10087 (define_insn "*xorhi_2"
10088   [(set (reg FLAGS_REG)
10089         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10090                          (match_operand:HI 2 "general_operand" "rmn,rn"))
10091                  (const_int 0)))
10092    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10093         (xor:HI (match_dup 1) (match_dup 2)))]
10094   "ix86_match_ccmode (insn, CCNOmode)
10095    && ix86_binary_operator_ok (XOR, HImode, operands)"
10096   "xor{w}\t{%2, %0|%0, %2}"
10097   [(set_attr "type" "alu")
10098    (set_attr "mode" "HI")])
10100 (define_insn "*xorhi_3"
10101   [(set (reg FLAGS_REG)
10102         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
10103                          (match_operand:HI 2 "general_operand" "rmn"))
10104                  (const_int 0)))
10105    (clobber (match_scratch:HI 0 "=r"))]
10106   "ix86_match_ccmode (insn, CCNOmode)
10107    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10108   "xor{w}\t{%2, %0|%0, %2}"
10109   [(set_attr "type" "alu")
10110    (set_attr "mode" "HI")])
10112 (define_expand "xorqi3"
10113   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10114         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
10115                 (match_operand:QI 2 "general_operand" "")))]
10116   "TARGET_QIMODE_MATH"
10117   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
10119 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10120 (define_insn "*xorqi_1"
10121   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10122         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10123                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10124    (clobber (reg:CC FLAGS_REG))]
10125   "ix86_binary_operator_ok (XOR, QImode, operands)"
10126   "@
10127    xor{b}\t{%2, %0|%0, %2}
10128    xor{b}\t{%2, %0|%0, %2}
10129    xor{l}\t{%k2, %k0|%k0, %k2}"
10130   [(set_attr "type" "alu")
10131    (set_attr "mode" "QI,QI,SI")])
10133 (define_insn "*xorqi_1_slp"
10134   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
10135         (xor:QI (match_dup 0)
10136                 (match_operand:QI 1 "general_operand" "qn,qmn")))
10137    (clobber (reg:CC FLAGS_REG))]
10138   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10139    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10140   "xor{b}\t{%1, %0|%0, %1}"
10141   [(set_attr "type" "alu1")
10142    (set_attr "mode" "QI")])
10144 (define_insn "*xorqi_ext_0"
10145   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10146                          (const_int 8)
10147                          (const_int 8))
10148         (xor:SI
10149           (zero_extract:SI
10150             (match_operand 1 "ext_register_operand" "0")
10151             (const_int 8)
10152             (const_int 8))
10153           (match_operand 2 "const_int_operand" "n")))
10154    (clobber (reg:CC FLAGS_REG))]
10155   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10156   "xor{b}\t{%2, %h0|%h0, %2}"
10157   [(set_attr "type" "alu")
10158    (set_attr "length_immediate" "1")
10159    (set_attr "mode" "QI")])
10161 (define_insn "*xorqi_ext_1"
10162   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10163                          (const_int 8)
10164                          (const_int 8))
10165         (xor:SI
10166           (zero_extract:SI
10167             (match_operand 1 "ext_register_operand" "0")
10168             (const_int 8)
10169             (const_int 8))
10170           (zero_extend:SI
10171             (match_operand:QI 2 "general_operand" "Qm"))))
10172    (clobber (reg:CC FLAGS_REG))]
10173   "!TARGET_64BIT
10174    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10175   "xor{b}\t{%2, %h0|%h0, %2}"
10176   [(set_attr "type" "alu")
10177    (set_attr "length_immediate" "0")
10178    (set_attr "mode" "QI")])
10180 (define_insn "*xorqi_ext_1_rex64"
10181   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10182                          (const_int 8)
10183                          (const_int 8))
10184         (xor:SI
10185           (zero_extract:SI
10186             (match_operand 1 "ext_register_operand" "0")
10187             (const_int 8)
10188             (const_int 8))
10189           (zero_extend:SI
10190             (match_operand 2 "ext_register_operand" "Q"))))
10191    (clobber (reg:CC FLAGS_REG))]
10192   "TARGET_64BIT
10193    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10194   "xor{b}\t{%2, %h0|%h0, %2}"
10195   [(set_attr "type" "alu")
10196    (set_attr "length_immediate" "0")
10197    (set_attr "mode" "QI")])
10199 (define_insn "*xorqi_ext_2"
10200   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10201                          (const_int 8)
10202                          (const_int 8))
10203         (xor:SI
10204           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10205                            (const_int 8)
10206                            (const_int 8))
10207           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10208                            (const_int 8)
10209                            (const_int 8))))
10210    (clobber (reg:CC FLAGS_REG))]
10211   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10212   "xor{b}\t{%h2, %h0|%h0, %h2}"
10213   [(set_attr "type" "alu")
10214    (set_attr "length_immediate" "0")
10215    (set_attr "mode" "QI")])
10217 (define_insn "*xorqi_cc_1"
10218   [(set (reg FLAGS_REG)
10219         (compare
10220           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10221                   (match_operand:QI 2 "general_operand" "qmn,qn"))
10222           (const_int 0)))
10223    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10224         (xor:QI (match_dup 1) (match_dup 2)))]
10225   "ix86_match_ccmode (insn, CCNOmode)
10226    && ix86_binary_operator_ok (XOR, QImode, operands)"
10227   "xor{b}\t{%2, %0|%0, %2}"
10228   [(set_attr "type" "alu")
10229    (set_attr "mode" "QI")])
10231 (define_insn "*xorqi_2_slp"
10232   [(set (reg FLAGS_REG)
10233         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10234                          (match_operand:QI 1 "general_operand" "qmn,qn"))
10235                  (const_int 0)))
10236    (set (strict_low_part (match_dup 0))
10237         (xor:QI (match_dup 0) (match_dup 1)))]
10238   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10239    && ix86_match_ccmode (insn, CCNOmode)
10240    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10241   "xor{b}\t{%1, %0|%0, %1}"
10242   [(set_attr "type" "alu1")
10243    (set_attr "mode" "QI")])
10245 (define_insn "*xorqi_cc_2"
10246   [(set (reg FLAGS_REG)
10247         (compare
10248           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10249                   (match_operand:QI 2 "general_operand" "qmn"))
10250           (const_int 0)))
10251    (clobber (match_scratch:QI 0 "=q"))]
10252   "ix86_match_ccmode (insn, CCNOmode)
10253    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10254   "xor{b}\t{%2, %0|%0, %2}"
10255   [(set_attr "type" "alu")
10256    (set_attr "mode" "QI")])
10258 (define_insn "*xorqi_cc_ext_1"
10259   [(set (reg FLAGS_REG)
10260         (compare
10261           (xor:SI
10262             (zero_extract:SI
10263               (match_operand 1 "ext_register_operand" "0")
10264               (const_int 8)
10265               (const_int 8))
10266             (match_operand:QI 2 "general_operand" "qmn"))
10267           (const_int 0)))
10268    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10269                          (const_int 8)
10270                          (const_int 8))
10271         (xor:SI
10272           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10273           (match_dup 2)))]
10274   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10275   "xor{b}\t{%2, %h0|%h0, %2}"
10276   [(set_attr "type" "alu")
10277    (set_attr "mode" "QI")])
10279 (define_insn "*xorqi_cc_ext_1_rex64"
10280   [(set (reg FLAGS_REG)
10281         (compare
10282           (xor:SI
10283             (zero_extract:SI
10284               (match_operand 1 "ext_register_operand" "0")
10285               (const_int 8)
10286               (const_int 8))
10287             (match_operand:QI 2 "nonmemory_operand" "Qn"))
10288           (const_int 0)))
10289    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10290                          (const_int 8)
10291                          (const_int 8))
10292         (xor:SI
10293           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10294           (match_dup 2)))]
10295   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10296   "xor{b}\t{%2, %h0|%h0, %2}"
10297   [(set_attr "type" "alu")
10298    (set_attr "mode" "QI")])
10300 (define_expand "xorqi_cc_ext_1"
10301   [(parallel [
10302      (set (reg:CCNO FLAGS_REG)
10303           (compare:CCNO
10304             (xor:SI
10305               (zero_extract:SI
10306                 (match_operand 1 "ext_register_operand" "")
10307                 (const_int 8)
10308                 (const_int 8))
10309               (match_operand:QI 2 "general_operand" ""))
10310             (const_int 0)))
10311      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10312                            (const_int 8)
10313                            (const_int 8))
10314           (xor:SI
10315             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10316             (match_dup 2)))])]
10317   ""
10318   "")
10320 (define_split
10321   [(set (match_operand 0 "register_operand" "")
10322         (xor (match_operand 1 "register_operand" "")
10323              (match_operand 2 "const_int_operand" "")))
10324    (clobber (reg:CC FLAGS_REG))]
10325    "reload_completed
10326     && QI_REG_P (operands[0])
10327     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10328     && !(INTVAL (operands[2]) & ~(255 << 8))
10329     && GET_MODE (operands[0]) != QImode"
10330   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10331                    (xor:SI (zero_extract:SI (match_dup 1)
10332                                             (const_int 8) (const_int 8))
10333                            (match_dup 2)))
10334               (clobber (reg:CC FLAGS_REG))])]
10335   "operands[0] = gen_lowpart (SImode, operands[0]);
10336    operands[1] = gen_lowpart (SImode, operands[1]);
10337    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10339 ;; Since XOR can be encoded with sign extended immediate, this is only
10340 ;; profitable when 7th bit is set.
10341 (define_split
10342   [(set (match_operand 0 "register_operand" "")
10343         (xor (match_operand 1 "general_operand" "")
10344              (match_operand 2 "const_int_operand" "")))
10345    (clobber (reg:CC FLAGS_REG))]
10346    "reload_completed
10347     && ANY_QI_REG_P (operands[0])
10348     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10349     && !(INTVAL (operands[2]) & ~255)
10350     && (INTVAL (operands[2]) & 128)
10351     && GET_MODE (operands[0]) != QImode"
10352   [(parallel [(set (strict_low_part (match_dup 0))
10353                    (xor:QI (match_dup 1)
10354                            (match_dup 2)))
10355               (clobber (reg:CC FLAGS_REG))])]
10356   "operands[0] = gen_lowpart (QImode, operands[0]);
10357    operands[1] = gen_lowpart (QImode, operands[1]);
10358    operands[2] = gen_lowpart (QImode, operands[2]);")
10360 ;; Negation instructions
10362 (define_expand "negti2"
10363   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10364         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10365   "TARGET_64BIT"
10366   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10368 (define_insn "*negti2_1"
10369   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10370         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10371    (clobber (reg:CC FLAGS_REG))]
10372   "TARGET_64BIT
10373    && ix86_unary_operator_ok (NEG, TImode, operands)"
10374   "#")
10376 (define_split
10377   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10378         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10379    (clobber (reg:CC FLAGS_REG))]
10380   "TARGET_64BIT && reload_completed"
10381   [(parallel
10382     [(set (reg:CCZ FLAGS_REG)
10383           (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10384      (set (match_dup 0) (neg:DI (match_dup 1)))])
10385    (parallel
10386     [(set (match_dup 2)
10387           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10388                             (match_dup 3))
10389                    (const_int 0)))
10390      (clobber (reg:CC FLAGS_REG))])
10391    (parallel
10392     [(set (match_dup 2)
10393           (neg:DI (match_dup 2)))
10394      (clobber (reg:CC FLAGS_REG))])]
10395   "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10397 (define_expand "negdi2"
10398   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10399         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10400   ""
10401   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10403 (define_insn "*negdi2_1"
10404   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10405         (neg:DI (match_operand:DI 1 "general_operand" "0")))
10406    (clobber (reg:CC FLAGS_REG))]
10407   "!TARGET_64BIT
10408    && ix86_unary_operator_ok (NEG, DImode, operands)"
10409   "#")
10411 (define_split
10412   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10413         (neg:DI (match_operand:DI 1 "general_operand" "")))
10414    (clobber (reg:CC FLAGS_REG))]
10415   "!TARGET_64BIT && reload_completed"
10416   [(parallel
10417     [(set (reg:CCZ FLAGS_REG)
10418           (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10419      (set (match_dup 0) (neg:SI (match_dup 1)))])
10420    (parallel
10421     [(set (match_dup 2)
10422           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10423                             (match_dup 3))
10424                    (const_int 0)))
10425      (clobber (reg:CC FLAGS_REG))])
10426    (parallel
10427     [(set (match_dup 2)
10428           (neg:SI (match_dup 2)))
10429      (clobber (reg:CC FLAGS_REG))])]
10430   "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10432 (define_insn "*negdi2_1_rex64"
10433   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10434         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10435    (clobber (reg:CC FLAGS_REG))]
10436   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10437   "neg{q}\t%0"
10438   [(set_attr "type" "negnot")
10439    (set_attr "mode" "DI")])
10441 ;; The problem with neg is that it does not perform (compare x 0),
10442 ;; it really performs (compare 0 x), which leaves us with the zero
10443 ;; flag being the only useful item.
10445 (define_insn "*negdi2_cmpz_rex64"
10446   [(set (reg:CCZ FLAGS_REG)
10447         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10448                      (const_int 0)))
10449    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10450         (neg:DI (match_dup 1)))]
10451   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10452   "neg{q}\t%0"
10453   [(set_attr "type" "negnot")
10454    (set_attr "mode" "DI")])
10457 (define_expand "negsi2"
10458   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10459         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10460   ""
10461   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10463 (define_insn "*negsi2_1"
10464   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10465         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10466    (clobber (reg:CC FLAGS_REG))]
10467   "ix86_unary_operator_ok (NEG, SImode, operands)"
10468   "neg{l}\t%0"
10469   [(set_attr "type" "negnot")
10470    (set_attr "mode" "SI")])
10472 ;; Combine is quite creative about this pattern.
10473 (define_insn "*negsi2_1_zext"
10474   [(set (match_operand:DI 0 "register_operand" "=r")
10475         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10476                                         (const_int 32)))
10477                      (const_int 32)))
10478    (clobber (reg:CC FLAGS_REG))]
10479   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10480   "neg{l}\t%k0"
10481   [(set_attr "type" "negnot")
10482    (set_attr "mode" "SI")])
10484 ;; The problem with neg is that it does not perform (compare x 0),
10485 ;; it really performs (compare 0 x), which leaves us with the zero
10486 ;; flag being the only useful item.
10488 (define_insn "*negsi2_cmpz"
10489   [(set (reg:CCZ FLAGS_REG)
10490         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10491                      (const_int 0)))
10492    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10493         (neg:SI (match_dup 1)))]
10494   "ix86_unary_operator_ok (NEG, SImode, operands)"
10495   "neg{l}\t%0"
10496   [(set_attr "type" "negnot")
10497    (set_attr "mode" "SI")])
10499 (define_insn "*negsi2_cmpz_zext"
10500   [(set (reg:CCZ FLAGS_REG)
10501         (compare:CCZ (lshiftrt:DI
10502                        (neg:DI (ashift:DI
10503                                  (match_operand:DI 1 "register_operand" "0")
10504                                  (const_int 32)))
10505                        (const_int 32))
10506                      (const_int 0)))
10507    (set (match_operand:DI 0 "register_operand" "=r")
10508         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10509                                         (const_int 32)))
10510                      (const_int 32)))]
10511   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10512   "neg{l}\t%k0"
10513   [(set_attr "type" "negnot")
10514    (set_attr "mode" "SI")])
10516 (define_expand "neghi2"
10517   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10518         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10519   "TARGET_HIMODE_MATH"
10520   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10522 (define_insn "*neghi2_1"
10523   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10524         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10525    (clobber (reg:CC FLAGS_REG))]
10526   "ix86_unary_operator_ok (NEG, HImode, operands)"
10527   "neg{w}\t%0"
10528   [(set_attr "type" "negnot")
10529    (set_attr "mode" "HI")])
10531 (define_insn "*neghi2_cmpz"
10532   [(set (reg:CCZ FLAGS_REG)
10533         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10534                      (const_int 0)))
10535    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10536         (neg:HI (match_dup 1)))]
10537   "ix86_unary_operator_ok (NEG, HImode, operands)"
10538   "neg{w}\t%0"
10539   [(set_attr "type" "negnot")
10540    (set_attr "mode" "HI")])
10542 (define_expand "negqi2"
10543   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10544         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10545   "TARGET_QIMODE_MATH"
10546   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10548 (define_insn "*negqi2_1"
10549   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10550         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10551    (clobber (reg:CC FLAGS_REG))]
10552   "ix86_unary_operator_ok (NEG, QImode, operands)"
10553   "neg{b}\t%0"
10554   [(set_attr "type" "negnot")
10555    (set_attr "mode" "QI")])
10557 (define_insn "*negqi2_cmpz"
10558   [(set (reg:CCZ FLAGS_REG)
10559         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10560                      (const_int 0)))
10561    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10562         (neg:QI (match_dup 1)))]
10563   "ix86_unary_operator_ok (NEG, QImode, operands)"
10564   "neg{b}\t%0"
10565   [(set_attr "type" "negnot")
10566    (set_attr "mode" "QI")])
10568 ;; Changing of sign for FP values is doable using integer unit too.
10570 (define_expand "<code><mode>2"
10571   [(set (match_operand:X87MODEF 0 "register_operand" "")
10572         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10573   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10574   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10576 (define_insn "*absneg<mode>2_mixed"
10577   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10578         (match_operator:MODEF 3 "absneg_operator"
10579           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10580    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10581    (clobber (reg:CC FLAGS_REG))]
10582   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10583   "#")
10585 (define_insn "*absneg<mode>2_sse"
10586   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10587         (match_operator:MODEF 3 "absneg_operator"
10588           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10589    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10590    (clobber (reg:CC FLAGS_REG))]
10591   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10592   "#")
10594 (define_insn "*absneg<mode>2_i387"
10595   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10596         (match_operator:X87MODEF 3 "absneg_operator"
10597           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10598    (use (match_operand 2 "" ""))
10599    (clobber (reg:CC FLAGS_REG))]
10600   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10601   "#")
10603 (define_expand "<code>tf2"
10604   [(set (match_operand:TF 0 "register_operand" "")
10605         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10606   "TARGET_SSE2"
10607   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10609 (define_insn "*absnegtf2_sse"
10610   [(set (match_operand:TF 0 "register_operand" "=x,x")
10611         (match_operator:TF 3 "absneg_operator"
10612           [(match_operand:TF 1 "register_operand" "0,x")]))
10613    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10614    (clobber (reg:CC FLAGS_REG))]
10615   "TARGET_SSE2"
10616   "#")
10618 ;; Splitters for fp abs and neg.
10620 (define_split
10621   [(set (match_operand 0 "fp_register_operand" "")
10622         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10623    (use (match_operand 2 "" ""))
10624    (clobber (reg:CC FLAGS_REG))]
10625   "reload_completed"
10626   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10628 (define_split
10629   [(set (match_operand 0 "register_operand" "")
10630         (match_operator 3 "absneg_operator"
10631           [(match_operand 1 "register_operand" "")]))
10632    (use (match_operand 2 "nonimmediate_operand" ""))
10633    (clobber (reg:CC FLAGS_REG))]
10634   "reload_completed && SSE_REG_P (operands[0])"
10635   [(set (match_dup 0) (match_dup 3))]
10637   enum machine_mode mode = GET_MODE (operands[0]);
10638   enum machine_mode vmode = GET_MODE (operands[2]);
10639   rtx tmp;
10641   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10642   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10643   if (operands_match_p (operands[0], operands[2]))
10644     {
10645       tmp = operands[1];
10646       operands[1] = operands[2];
10647       operands[2] = tmp;
10648     }
10649   if (GET_CODE (operands[3]) == ABS)
10650     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10651   else
10652     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10653   operands[3] = tmp;
10656 (define_split
10657   [(set (match_operand:SF 0 "register_operand" "")
10658         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10659    (use (match_operand:V4SF 2 "" ""))
10660    (clobber (reg:CC FLAGS_REG))]
10661   "reload_completed"
10662   [(parallel [(set (match_dup 0) (match_dup 1))
10663               (clobber (reg:CC FLAGS_REG))])]
10665   rtx tmp;
10666   operands[0] = gen_lowpart (SImode, operands[0]);
10667   if (GET_CODE (operands[1]) == ABS)
10668     {
10669       tmp = gen_int_mode (0x7fffffff, SImode);
10670       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10671     }
10672   else
10673     {
10674       tmp = gen_int_mode (0x80000000, SImode);
10675       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10676     }
10677   operands[1] = tmp;
10680 (define_split
10681   [(set (match_operand:DF 0 "register_operand" "")
10682         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10683    (use (match_operand 2 "" ""))
10684    (clobber (reg:CC FLAGS_REG))]
10685   "reload_completed"
10686   [(parallel [(set (match_dup 0) (match_dup 1))
10687               (clobber (reg:CC FLAGS_REG))])]
10689   rtx tmp;
10690   if (TARGET_64BIT)
10691     {
10692       tmp = gen_lowpart (DImode, operands[0]);
10693       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10694       operands[0] = tmp;
10696       if (GET_CODE (operands[1]) == ABS)
10697         tmp = const0_rtx;
10698       else
10699         tmp = gen_rtx_NOT (DImode, tmp);
10700     }
10701   else
10702     {
10703       operands[0] = gen_highpart (SImode, operands[0]);
10704       if (GET_CODE (operands[1]) == ABS)
10705         {
10706           tmp = gen_int_mode (0x7fffffff, SImode);
10707           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10708         }
10709       else
10710         {
10711           tmp = gen_int_mode (0x80000000, SImode);
10712           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10713         }
10714     }
10715   operands[1] = tmp;
10718 (define_split
10719   [(set (match_operand:XF 0 "register_operand" "")
10720         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10721    (use (match_operand 2 "" ""))
10722    (clobber (reg:CC FLAGS_REG))]
10723   "reload_completed"
10724   [(parallel [(set (match_dup 0) (match_dup 1))
10725               (clobber (reg:CC FLAGS_REG))])]
10727   rtx tmp;
10728   operands[0] = gen_rtx_REG (SImode,
10729                              true_regnum (operands[0])
10730                              + (TARGET_64BIT ? 1 : 2));
10731   if (GET_CODE (operands[1]) == ABS)
10732     {
10733       tmp = GEN_INT (0x7fff);
10734       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10735     }
10736   else
10737     {
10738       tmp = GEN_INT (0x8000);
10739       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10740     }
10741   operands[1] = tmp;
10744 ;; Conditionalize these after reload. If they match before reload, we
10745 ;; lose the clobber and ability to use integer instructions.
10747 (define_insn "*<code><mode>2_1"
10748   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10749         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10750   "TARGET_80387
10751    && (reload_completed
10752        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10753   "f<absnegprefix>"
10754   [(set_attr "type" "fsgn")
10755    (set_attr "mode" "<MODE>")])
10757 (define_insn "*<code>extendsfdf2"
10758   [(set (match_operand:DF 0 "register_operand" "=f")
10759         (absneg:DF (float_extend:DF
10760                      (match_operand:SF 1 "register_operand" "0"))))]
10761   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10762   "f<absnegprefix>"
10763   [(set_attr "type" "fsgn")
10764    (set_attr "mode" "DF")])
10766 (define_insn "*<code>extendsfxf2"
10767   [(set (match_operand:XF 0 "register_operand" "=f")
10768         (absneg:XF (float_extend:XF
10769                      (match_operand:SF 1 "register_operand" "0"))))]
10770   "TARGET_80387"
10771   "f<absnegprefix>"
10772   [(set_attr "type" "fsgn")
10773    (set_attr "mode" "XF")])
10775 (define_insn "*<code>extenddfxf2"
10776   [(set (match_operand:XF 0 "register_operand" "=f")
10777         (absneg:XF (float_extend:XF
10778                       (match_operand:DF 1 "register_operand" "0"))))]
10779   "TARGET_80387"
10780   "f<absnegprefix>"
10781   [(set_attr "type" "fsgn")
10782    (set_attr "mode" "XF")])
10784 ;; Copysign instructions
10786 (define_mode_iterator CSGNMODE [SF DF TF])
10787 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10789 (define_expand "copysign<mode>3"
10790   [(match_operand:CSGNMODE 0 "register_operand" "")
10791    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10792    (match_operand:CSGNMODE 2 "register_operand" "")]
10793   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10794    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10796   ix86_expand_copysign (operands);
10797   DONE;
10800 (define_insn_and_split "copysign<mode>3_const"
10801   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10802         (unspec:CSGNMODE
10803           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10804            (match_operand:CSGNMODE 2 "register_operand" "0")
10805            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10806           UNSPEC_COPYSIGN))]
10807   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10808    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10809   "#"
10810   "&& reload_completed"
10811   [(const_int 0)]
10813   ix86_split_copysign_const (operands);
10814   DONE;
10817 (define_insn "copysign<mode>3_var"
10818   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10819         (unspec:CSGNMODE
10820           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10821            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10822            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10823            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10824           UNSPEC_COPYSIGN))
10825    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10826   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10827    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10828   "#")
10830 (define_split
10831   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10832         (unspec:CSGNMODE
10833           [(match_operand:CSGNMODE 2 "register_operand" "")
10834            (match_operand:CSGNMODE 3 "register_operand" "")
10835            (match_operand:<CSGNVMODE> 4 "" "")
10836            (match_operand:<CSGNVMODE> 5 "" "")]
10837           UNSPEC_COPYSIGN))
10838    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10839   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10840     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10841    && reload_completed"
10842   [(const_int 0)]
10844   ix86_split_copysign_var (operands);
10845   DONE;
10848 ;; One complement instructions
10850 (define_expand "one_cmpldi2"
10851   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10852         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10853   "TARGET_64BIT"
10854   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10856 (define_insn "*one_cmpldi2_1_rex64"
10857   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10858         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10859   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10860   "not{q}\t%0"
10861   [(set_attr "type" "negnot")
10862    (set_attr "mode" "DI")])
10864 (define_insn "*one_cmpldi2_2_rex64"
10865   [(set (reg FLAGS_REG)
10866         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10867                  (const_int 0)))
10868    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10869         (not:DI (match_dup 1)))]
10870   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10871    && ix86_unary_operator_ok (NOT, DImode, operands)"
10872   "#"
10873   [(set_attr "type" "alu1")
10874    (set_attr "mode" "DI")])
10876 (define_split
10877   [(set (match_operand 0 "flags_reg_operand" "")
10878         (match_operator 2 "compare_operator"
10879           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10880            (const_int 0)]))
10881    (set (match_operand:DI 1 "nonimmediate_operand" "")
10882         (not:DI (match_dup 3)))]
10883   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10884   [(parallel [(set (match_dup 0)
10885                    (match_op_dup 2
10886                      [(xor:DI (match_dup 3) (const_int -1))
10887                       (const_int 0)]))
10888               (set (match_dup 1)
10889                    (xor:DI (match_dup 3) (const_int -1)))])]
10890   "")
10892 (define_expand "one_cmplsi2"
10893   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10894         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10895   ""
10896   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10898 (define_insn "*one_cmplsi2_1"
10899   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10900         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10901   "ix86_unary_operator_ok (NOT, SImode, operands)"
10902   "not{l}\t%0"
10903   [(set_attr "type" "negnot")
10904    (set_attr "mode" "SI")])
10906 ;; ??? Currently never generated - xor is used instead.
10907 (define_insn "*one_cmplsi2_1_zext"
10908   [(set (match_operand:DI 0 "register_operand" "=r")
10909         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10910   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10911   "not{l}\t%k0"
10912   [(set_attr "type" "negnot")
10913    (set_attr "mode" "SI")])
10915 (define_insn "*one_cmplsi2_2"
10916   [(set (reg FLAGS_REG)
10917         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10918                  (const_int 0)))
10919    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10920         (not:SI (match_dup 1)))]
10921   "ix86_match_ccmode (insn, CCNOmode)
10922    && ix86_unary_operator_ok (NOT, SImode, operands)"
10923   "#"
10924   [(set_attr "type" "alu1")
10925    (set_attr "mode" "SI")])
10927 (define_split
10928   [(set (match_operand 0 "flags_reg_operand" "")
10929         (match_operator 2 "compare_operator"
10930           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10931            (const_int 0)]))
10932    (set (match_operand:SI 1 "nonimmediate_operand" "")
10933         (not:SI (match_dup 3)))]
10934   "ix86_match_ccmode (insn, CCNOmode)"
10935   [(parallel [(set (match_dup 0)
10936                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10937                                     (const_int 0)]))
10938               (set (match_dup 1)
10939                    (xor:SI (match_dup 3) (const_int -1)))])]
10940   "")
10942 ;; ??? Currently never generated - xor is used instead.
10943 (define_insn "*one_cmplsi2_2_zext"
10944   [(set (reg FLAGS_REG)
10945         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10946                  (const_int 0)))
10947    (set (match_operand:DI 0 "register_operand" "=r")
10948         (zero_extend:DI (not:SI (match_dup 1))))]
10949   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10950    && ix86_unary_operator_ok (NOT, SImode, operands)"
10951   "#"
10952   [(set_attr "type" "alu1")
10953    (set_attr "mode" "SI")])
10955 (define_split
10956   [(set (match_operand 0 "flags_reg_operand" "")
10957         (match_operator 2 "compare_operator"
10958           [(not:SI (match_operand:SI 3 "register_operand" ""))
10959            (const_int 0)]))
10960    (set (match_operand:DI 1 "register_operand" "")
10961         (zero_extend:DI (not:SI (match_dup 3))))]
10962   "ix86_match_ccmode (insn, CCNOmode)"
10963   [(parallel [(set (match_dup 0)
10964                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10965                                     (const_int 0)]))
10966               (set (match_dup 1)
10967                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10968   "")
10970 (define_expand "one_cmplhi2"
10971   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10972         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10973   "TARGET_HIMODE_MATH"
10974   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10976 (define_insn "*one_cmplhi2_1"
10977   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10978         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10979   "ix86_unary_operator_ok (NOT, HImode, operands)"
10980   "not{w}\t%0"
10981   [(set_attr "type" "negnot")
10982    (set_attr "mode" "HI")])
10984 (define_insn "*one_cmplhi2_2"
10985   [(set (reg FLAGS_REG)
10986         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10987                  (const_int 0)))
10988    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10989         (not:HI (match_dup 1)))]
10990   "ix86_match_ccmode (insn, CCNOmode)
10991    && ix86_unary_operator_ok (NEG, HImode, operands)"
10992   "#"
10993   [(set_attr "type" "alu1")
10994    (set_attr "mode" "HI")])
10996 (define_split
10997   [(set (match_operand 0 "flags_reg_operand" "")
10998         (match_operator 2 "compare_operator"
10999           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
11000            (const_int 0)]))
11001    (set (match_operand:HI 1 "nonimmediate_operand" "")
11002         (not:HI (match_dup 3)))]
11003   "ix86_match_ccmode (insn, CCNOmode)"
11004   [(parallel [(set (match_dup 0)
11005                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
11006                                     (const_int 0)]))
11007               (set (match_dup 1)
11008                    (xor:HI (match_dup 3) (const_int -1)))])]
11009   "")
11011 ;; %%% Potential partial reg stall on alternative 1.  What to do?
11012 (define_expand "one_cmplqi2"
11013   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11014         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
11015   "TARGET_QIMODE_MATH"
11016   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
11018 (define_insn "*one_cmplqi2_1"
11019   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11020         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
11021   "ix86_unary_operator_ok (NOT, QImode, operands)"
11022   "@
11023    not{b}\t%0
11024    not{l}\t%k0"
11025   [(set_attr "type" "negnot")
11026    (set_attr "mode" "QI,SI")])
11028 (define_insn "*one_cmplqi2_2"
11029   [(set (reg FLAGS_REG)
11030         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11031                  (const_int 0)))
11032    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11033         (not:QI (match_dup 1)))]
11034   "ix86_match_ccmode (insn, CCNOmode)
11035    && ix86_unary_operator_ok (NOT, QImode, operands)"
11036   "#"
11037   [(set_attr "type" "alu1")
11038    (set_attr "mode" "QI")])
11040 (define_split
11041   [(set (match_operand 0 "flags_reg_operand" "")
11042         (match_operator 2 "compare_operator"
11043           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
11044            (const_int 0)]))
11045    (set (match_operand:QI 1 "nonimmediate_operand" "")
11046         (not:QI (match_dup 3)))]
11047   "ix86_match_ccmode (insn, CCNOmode)"
11048   [(parallel [(set (match_dup 0)
11049                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
11050                                     (const_int 0)]))
11051               (set (match_dup 1)
11052                    (xor:QI (match_dup 3) (const_int -1)))])]
11053   "")
11055 ;; Arithmetic shift instructions
11057 ;; DImode shifts are implemented using the i386 "shift double" opcode,
11058 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
11059 ;; is variable, then the count is in %cl and the "imm" operand is dropped
11060 ;; from the assembler input.
11062 ;; This instruction shifts the target reg/mem as usual, but instead of
11063 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
11064 ;; is a left shift double, bits are taken from the high order bits of
11065 ;; reg, else if the insn is a shift right double, bits are taken from the
11066 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
11067 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
11069 ;; Since sh[lr]d does not change the `reg' operand, that is done
11070 ;; separately, making all shifts emit pairs of shift double and normal
11071 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
11072 ;; support a 63 bit shift, each shift where the count is in a reg expands
11073 ;; to a pair of shifts, a branch, a shift by 32 and a label.
11075 ;; If the shift count is a constant, we need never emit more than one
11076 ;; shift pair, instead using moves and sign extension for counts greater
11077 ;; than 31.
11079 (define_expand "ashlti3"
11080   [(set (match_operand:TI 0 "register_operand" "")
11081         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
11082                    (match_operand:QI 2 "nonmemory_operand" "")))]
11083   "TARGET_64BIT"
11084   "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
11086 ;; This pattern must be defined before *ashlti3_1 to prevent
11087 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
11089 (define_insn "*avx_ashlti3"
11090   [(set (match_operand:TI 0 "register_operand" "=x")
11091         (ashift:TI (match_operand:TI 1 "register_operand" "x")
11092                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11093   "TARGET_AVX"
11095   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11096   return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
11098   [(set_attr "type" "sseishft")
11099    (set_attr "prefix" "vex")
11100    (set_attr "mode" "TI")])
11102 (define_insn "sse2_ashlti3"
11103   [(set (match_operand:TI 0 "register_operand" "=x")
11104         (ashift:TI (match_operand:TI 1 "register_operand" "0")
11105                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11106   "TARGET_SSE2"
11108   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11109   return "pslldq\t{%2, %0|%0, %2}";
11111   [(set_attr "type" "sseishft")
11112    (set_attr "prefix_data16" "1")
11113    (set_attr "mode" "TI")])
11115 (define_insn "*ashlti3_1"
11116   [(set (match_operand:TI 0 "register_operand" "=&r,r")
11117         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
11118                    (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
11119    (clobber (reg:CC FLAGS_REG))]
11120   "TARGET_64BIT"
11121   "#"
11122   [(set_attr "type" "multi")])
11124 (define_peephole2
11125   [(match_scratch:DI 3 "r")
11126    (parallel [(set (match_operand:TI 0 "register_operand" "")
11127                    (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11128                               (match_operand:QI 2 "nonmemory_operand" "")))
11129               (clobber (reg:CC FLAGS_REG))])
11130    (match_dup 3)]
11131   "TARGET_64BIT"
11132   [(const_int 0)]
11133   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
11135 (define_split
11136   [(set (match_operand:TI 0 "register_operand" "")
11137         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11138                    (match_operand:QI 2 "nonmemory_operand" "")))
11139    (clobber (reg:CC FLAGS_REG))]
11140   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11141                     ? epilogue_completed : reload_completed)"
11142   [(const_int 0)]
11143   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
11145 (define_insn "x86_64_shld"
11146   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11147         (ior:DI (ashift:DI (match_dup 0)
11148                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
11149                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
11150                   (minus:QI (const_int 64) (match_dup 2)))))
11151    (clobber (reg:CC FLAGS_REG))]
11152   "TARGET_64BIT"
11153   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
11154   [(set_attr "type" "ishift")
11155    (set_attr "prefix_0f" "1")
11156    (set_attr "mode" "DI")
11157    (set_attr "athlon_decode" "vector")
11158    (set_attr "amdfam10_decode" "vector")])
11160 (define_expand "x86_64_shift_adj_1"
11161   [(set (reg:CCZ FLAGS_REG)
11162         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11163                              (const_int 64))
11164                      (const_int 0)))
11165    (set (match_operand:DI 0 "register_operand" "")
11166         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11167                          (match_operand:DI 1 "register_operand" "")
11168                          (match_dup 0)))
11169    (set (match_dup 1)
11170         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11171                          (match_operand:DI 3 "register_operand" "r")
11172                          (match_dup 1)))]
11173   "TARGET_64BIT"
11174   "")
11176 (define_expand "x86_64_shift_adj_2"
11177   [(use (match_operand:DI 0 "register_operand" ""))
11178    (use (match_operand:DI 1 "register_operand" ""))
11179    (use (match_operand:QI 2 "register_operand" ""))]
11180   "TARGET_64BIT"
11182   rtx label = gen_label_rtx ();
11183   rtx tmp;
11185   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11187   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11188   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11189   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11190                               gen_rtx_LABEL_REF (VOIDmode, label),
11191                               pc_rtx);
11192   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11193   JUMP_LABEL (tmp) = label;
11195   emit_move_insn (operands[0], operands[1]);
11196   ix86_expand_clear (operands[1]);
11198   emit_label (label);
11199   LABEL_NUSES (label) = 1;
11201   DONE;
11204 (define_expand "ashldi3"
11205   [(set (match_operand:DI 0 "shiftdi_operand" "")
11206         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11207                    (match_operand:QI 2 "nonmemory_operand" "")))]
11208   ""
11209   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11211 (define_insn "*ashldi3_1_rex64"
11212   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11213         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11214                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11215    (clobber (reg:CC FLAGS_REG))]
11216   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11218   switch (get_attr_type (insn))
11219     {
11220     case TYPE_ALU:
11221       gcc_assert (operands[2] == const1_rtx);
11222       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11223       return "add{q}\t%0, %0";
11225     case TYPE_LEA:
11226       gcc_assert (CONST_INT_P (operands[2]));
11227       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11228       operands[1] = gen_rtx_MULT (DImode, operands[1],
11229                                   GEN_INT (1 << INTVAL (operands[2])));
11230       return "lea{q}\t{%a1, %0|%0, %a1}";
11232     default:
11233       if (REG_P (operands[2]))
11234         return "sal{q}\t{%b2, %0|%0, %b2}";
11235       else if (operands[2] == const1_rtx
11236                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11237         return "sal{q}\t%0";
11238       else
11239         return "sal{q}\t{%2, %0|%0, %2}";
11240     }
11242   [(set (attr "type")
11243      (cond [(eq_attr "alternative" "1")
11244               (const_string "lea")
11245             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11246                           (const_int 0))
11247                       (match_operand 0 "register_operand" ""))
11248                  (match_operand 2 "const1_operand" ""))
11249               (const_string "alu")
11250            ]
11251            (const_string "ishift")))
11252    (set_attr "mode" "DI")])
11254 ;; Convert lea to the lea pattern to avoid flags dependency.
11255 (define_split
11256   [(set (match_operand:DI 0 "register_operand" "")
11257         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11258                    (match_operand:QI 2 "immediate_operand" "")))
11259    (clobber (reg:CC FLAGS_REG))]
11260   "TARGET_64BIT && reload_completed
11261    && true_regnum (operands[0]) != true_regnum (operands[1])"
11262   [(set (match_dup 0)
11263         (mult:DI (match_dup 1)
11264                  (match_dup 2)))]
11265   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11267 ;; This pattern can't accept a variable shift count, since shifts by
11268 ;; zero don't affect the flags.  We assume that shifts by constant
11269 ;; zero are optimized away.
11270 (define_insn "*ashldi3_cmp_rex64"
11271   [(set (reg FLAGS_REG)
11272         (compare
11273           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11274                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11275           (const_int 0)))
11276    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11277         (ashift:DI (match_dup 1) (match_dup 2)))]
11278   "TARGET_64BIT
11279    && (optimize_function_for_size_p (cfun)
11280        || !TARGET_PARTIAL_FLAG_REG_STALL
11281        || (operands[2] == const1_rtx
11282            && (TARGET_SHIFT1
11283                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11284    && ix86_match_ccmode (insn, CCGOCmode)
11285    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11287   switch (get_attr_type (insn))
11288     {
11289     case TYPE_ALU:
11290       gcc_assert (operands[2] == const1_rtx);
11291       return "add{q}\t%0, %0";
11293     default:
11294       if (REG_P (operands[2]))
11295         return "sal{q}\t{%b2, %0|%0, %b2}";
11296       else if (operands[2] == const1_rtx
11297                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11298         return "sal{q}\t%0";
11299       else
11300         return "sal{q}\t{%2, %0|%0, %2}";
11301     }
11303   [(set (attr "type")
11304      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11305                           (const_int 0))
11306                       (match_operand 0 "register_operand" ""))
11307                  (match_operand 2 "const1_operand" ""))
11308               (const_string "alu")
11309            ]
11310            (const_string "ishift")))
11311    (set_attr "mode" "DI")])
11313 (define_insn "*ashldi3_cconly_rex64"
11314   [(set (reg FLAGS_REG)
11315         (compare
11316           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11317                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11318           (const_int 0)))
11319    (clobber (match_scratch:DI 0 "=r"))]
11320   "TARGET_64BIT
11321    && (optimize_function_for_size_p (cfun)
11322        || !TARGET_PARTIAL_FLAG_REG_STALL
11323        || (operands[2] == const1_rtx
11324            && (TARGET_SHIFT1
11325                || TARGET_DOUBLE_WITH_ADD)))
11326    && ix86_match_ccmode (insn, CCGOCmode)
11327    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11329   switch (get_attr_type (insn))
11330     {
11331     case TYPE_ALU:
11332       gcc_assert (operands[2] == const1_rtx);
11333       return "add{q}\t%0, %0";
11335     default:
11336       if (REG_P (operands[2]))
11337         return "sal{q}\t{%b2, %0|%0, %b2}";
11338       else if (operands[2] == const1_rtx
11339                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11340         return "sal{q}\t%0";
11341       else
11342         return "sal{q}\t{%2, %0|%0, %2}";
11343     }
11345   [(set (attr "type")
11346      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11347                           (const_int 0))
11348                       (match_operand 0 "register_operand" ""))
11349                  (match_operand 2 "const1_operand" ""))
11350               (const_string "alu")
11351            ]
11352            (const_string "ishift")))
11353    (set_attr "mode" "DI")])
11355 (define_insn "*ashldi3_1"
11356   [(set (match_operand:DI 0 "register_operand" "=&r,r")
11357         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11358                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11359    (clobber (reg:CC FLAGS_REG))]
11360   "!TARGET_64BIT"
11361   "#"
11362   [(set_attr "type" "multi")])
11364 ;; By default we don't ask for a scratch register, because when DImode
11365 ;; values are manipulated, registers are already at a premium.  But if
11366 ;; we have one handy, we won't turn it away.
11367 (define_peephole2
11368   [(match_scratch:SI 3 "r")
11369    (parallel [(set (match_operand:DI 0 "register_operand" "")
11370                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11371                               (match_operand:QI 2 "nonmemory_operand" "")))
11372               (clobber (reg:CC FLAGS_REG))])
11373    (match_dup 3)]
11374   "!TARGET_64BIT && TARGET_CMOVE"
11375   [(const_int 0)]
11376   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11378 (define_split
11379   [(set (match_operand:DI 0 "register_operand" "")
11380         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11381                    (match_operand:QI 2 "nonmemory_operand" "")))
11382    (clobber (reg:CC FLAGS_REG))]
11383   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11384                      ? epilogue_completed : reload_completed)"
11385   [(const_int 0)]
11386   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11388 (define_insn "x86_shld"
11389   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11390         (ior:SI (ashift:SI (match_dup 0)
11391                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
11392                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11393                   (minus:QI (const_int 32) (match_dup 2)))))
11394    (clobber (reg:CC FLAGS_REG))]
11395   ""
11396   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11397   [(set_attr "type" "ishift")
11398    (set_attr "prefix_0f" "1")
11399    (set_attr "mode" "SI")
11400    (set_attr "pent_pair" "np")
11401    (set_attr "athlon_decode" "vector")
11402    (set_attr "amdfam10_decode" "vector")])
11404 (define_expand "x86_shift_adj_1"
11405   [(set (reg:CCZ FLAGS_REG)
11406         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11407                              (const_int 32))
11408                      (const_int 0)))
11409    (set (match_operand:SI 0 "register_operand" "")
11410         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11411                          (match_operand:SI 1 "register_operand" "")
11412                          (match_dup 0)))
11413    (set (match_dup 1)
11414         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11415                          (match_operand:SI 3 "register_operand" "r")
11416                          (match_dup 1)))]
11417   "TARGET_CMOVE"
11418   "")
11420 (define_expand "x86_shift_adj_2"
11421   [(use (match_operand:SI 0 "register_operand" ""))
11422    (use (match_operand:SI 1 "register_operand" ""))
11423    (use (match_operand:QI 2 "register_operand" ""))]
11424   ""
11426   rtx label = gen_label_rtx ();
11427   rtx tmp;
11429   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11431   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11432   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11433   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11434                               gen_rtx_LABEL_REF (VOIDmode, label),
11435                               pc_rtx);
11436   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11437   JUMP_LABEL (tmp) = label;
11439   emit_move_insn (operands[0], operands[1]);
11440   ix86_expand_clear (operands[1]);
11442   emit_label (label);
11443   LABEL_NUSES (label) = 1;
11445   DONE;
11448 (define_expand "ashlsi3"
11449   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11450         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11451                    (match_operand:QI 2 "nonmemory_operand" "")))]
11452   ""
11453   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11455 (define_insn "*ashlsi3_1"
11456   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11457         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11458                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11459    (clobber (reg:CC FLAGS_REG))]
11460   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11462   switch (get_attr_type (insn))
11463     {
11464     case TYPE_ALU:
11465       gcc_assert (operands[2] == const1_rtx);
11466       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11467       return "add{l}\t%0, %0";
11469     case TYPE_LEA:
11470       return "#";
11472     default:
11473       if (REG_P (operands[2]))
11474         return "sal{l}\t{%b2, %0|%0, %b2}";
11475       else if (operands[2] == const1_rtx
11476                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11477         return "sal{l}\t%0";
11478       else
11479         return "sal{l}\t{%2, %0|%0, %2}";
11480     }
11482   [(set (attr "type")
11483      (cond [(eq_attr "alternative" "1")
11484               (const_string "lea")
11485             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11486                           (const_int 0))
11487                       (match_operand 0 "register_operand" ""))
11488                  (match_operand 2 "const1_operand" ""))
11489               (const_string "alu")
11490            ]
11491            (const_string "ishift")))
11492    (set_attr "mode" "SI")])
11494 ;; Convert lea to the lea pattern to avoid flags dependency.
11495 (define_split
11496   [(set (match_operand 0 "register_operand" "")
11497         (ashift (match_operand 1 "index_register_operand" "")
11498                 (match_operand:QI 2 "const_int_operand" "")))
11499    (clobber (reg:CC FLAGS_REG))]
11500   "reload_completed
11501    && true_regnum (operands[0]) != true_regnum (operands[1])
11502    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11503   [(const_int 0)]
11505   rtx pat;
11506   enum machine_mode mode = GET_MODE (operands[0]);
11508   if (GET_MODE_SIZE (mode) < 4)
11509     operands[0] = gen_lowpart (SImode, operands[0]);
11510   if (mode != Pmode)
11511     operands[1] = gen_lowpart (Pmode, operands[1]);
11512   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11514   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11515   if (Pmode != SImode)
11516     pat = gen_rtx_SUBREG (SImode, pat, 0);
11517   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11518   DONE;
11521 ;; Rare case of shifting RSP is handled by generating move and shift
11522 (define_split
11523   [(set (match_operand 0 "register_operand" "")
11524         (ashift (match_operand 1 "register_operand" "")
11525                 (match_operand:QI 2 "const_int_operand" "")))
11526    (clobber (reg:CC FLAGS_REG))]
11527   "reload_completed
11528    && true_regnum (operands[0]) != true_regnum (operands[1])"
11529   [(const_int 0)]
11531   rtx pat, clob;
11532   emit_move_insn (operands[0], operands[1]);
11533   pat = gen_rtx_SET (VOIDmode, operands[0],
11534                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11535                                      operands[0], operands[2]));
11536   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11537   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11538   DONE;
11541 (define_insn "*ashlsi3_1_zext"
11542   [(set (match_operand:DI 0 "register_operand" "=r,r")
11543         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11544                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11545    (clobber (reg:CC FLAGS_REG))]
11546   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11548   switch (get_attr_type (insn))
11549     {
11550     case TYPE_ALU:
11551       gcc_assert (operands[2] == const1_rtx);
11552       return "add{l}\t%k0, %k0";
11554     case TYPE_LEA:
11555       return "#";
11557     default:
11558       if (REG_P (operands[2]))
11559         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11560       else if (operands[2] == const1_rtx
11561                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11562         return "sal{l}\t%k0";
11563       else
11564         return "sal{l}\t{%2, %k0|%k0, %2}";
11565     }
11567   [(set (attr "type")
11568      (cond [(eq_attr "alternative" "1")
11569               (const_string "lea")
11570             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11571                      (const_int 0))
11572                  (match_operand 2 "const1_operand" ""))
11573               (const_string "alu")
11574            ]
11575            (const_string "ishift")))
11576    (set_attr "mode" "SI")])
11578 ;; Convert lea to the lea pattern to avoid flags dependency.
11579 (define_split
11580   [(set (match_operand:DI 0 "register_operand" "")
11581         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11582                                 (match_operand:QI 2 "const_int_operand" ""))))
11583    (clobber (reg:CC FLAGS_REG))]
11584   "TARGET_64BIT && reload_completed
11585    && true_regnum (operands[0]) != true_regnum (operands[1])"
11586   [(set (match_dup 0) (zero_extend:DI
11587                         (subreg:SI (mult:SI (match_dup 1)
11588                                             (match_dup 2)) 0)))]
11590   operands[1] = gen_lowpart (Pmode, operands[1]);
11591   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11594 ;; This pattern can't accept a variable shift count, since shifts by
11595 ;; zero don't affect the flags.  We assume that shifts by constant
11596 ;; zero are optimized away.
11597 (define_insn "*ashlsi3_cmp"
11598   [(set (reg FLAGS_REG)
11599         (compare
11600           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11601                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11602           (const_int 0)))
11603    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11604         (ashift:SI (match_dup 1) (match_dup 2)))]
11605    "(optimize_function_for_size_p (cfun)
11606      || !TARGET_PARTIAL_FLAG_REG_STALL
11607      || (operands[2] == const1_rtx
11608          && (TARGET_SHIFT1
11609              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11610    && ix86_match_ccmode (insn, CCGOCmode)
11611    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11613   switch (get_attr_type (insn))
11614     {
11615     case TYPE_ALU:
11616       gcc_assert (operands[2] == const1_rtx);
11617       return "add{l}\t%0, %0";
11619     default:
11620       if (REG_P (operands[2]))
11621         return "sal{l}\t{%b2, %0|%0, %b2}";
11622       else if (operands[2] == const1_rtx
11623                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11624         return "sal{l}\t%0";
11625       else
11626         return "sal{l}\t{%2, %0|%0, %2}";
11627     }
11629   [(set (attr "type")
11630      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11631                           (const_int 0))
11632                       (match_operand 0 "register_operand" ""))
11633                  (match_operand 2 "const1_operand" ""))
11634               (const_string "alu")
11635            ]
11636            (const_string "ishift")))
11637    (set_attr "mode" "SI")])
11639 (define_insn "*ashlsi3_cconly"
11640   [(set (reg FLAGS_REG)
11641         (compare
11642           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11643                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11644           (const_int 0)))
11645    (clobber (match_scratch:SI 0 "=r"))]
11646   "(optimize_function_for_size_p (cfun)
11647     || !TARGET_PARTIAL_FLAG_REG_STALL
11648     || (operands[2] == const1_rtx
11649         && (TARGET_SHIFT1
11650             || TARGET_DOUBLE_WITH_ADD)))
11651    && ix86_match_ccmode (insn, CCGOCmode)
11652    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11654   switch (get_attr_type (insn))
11655     {
11656     case TYPE_ALU:
11657       gcc_assert (operands[2] == const1_rtx);
11658       return "add{l}\t%0, %0";
11660     default:
11661       if (REG_P (operands[2]))
11662         return "sal{l}\t{%b2, %0|%0, %b2}";
11663       else if (operands[2] == const1_rtx
11664                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11665         return "sal{l}\t%0";
11666       else
11667         return "sal{l}\t{%2, %0|%0, %2}";
11668     }
11670   [(set (attr "type")
11671      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11672                           (const_int 0))
11673                       (match_operand 0 "register_operand" ""))
11674                  (match_operand 2 "const1_operand" ""))
11675               (const_string "alu")
11676            ]
11677            (const_string "ishift")))
11678    (set_attr "mode" "SI")])
11680 (define_insn "*ashlsi3_cmp_zext"
11681   [(set (reg FLAGS_REG)
11682         (compare
11683           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11684                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11685           (const_int 0)))
11686    (set (match_operand:DI 0 "register_operand" "=r")
11687         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11688   "TARGET_64BIT
11689    && (optimize_function_for_size_p (cfun)
11690        || !TARGET_PARTIAL_FLAG_REG_STALL
11691        || (operands[2] == const1_rtx
11692            && (TARGET_SHIFT1
11693                || TARGET_DOUBLE_WITH_ADD)))
11694    && ix86_match_ccmode (insn, CCGOCmode)
11695    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11697   switch (get_attr_type (insn))
11698     {
11699     case TYPE_ALU:
11700       gcc_assert (operands[2] == const1_rtx);
11701       return "add{l}\t%k0, %k0";
11703     default:
11704       if (REG_P (operands[2]))
11705         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11706       else if (operands[2] == const1_rtx
11707                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11708         return "sal{l}\t%k0";
11709       else
11710         return "sal{l}\t{%2, %k0|%k0, %2}";
11711     }
11713   [(set (attr "type")
11714      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11715                      (const_int 0))
11716                  (match_operand 2 "const1_operand" ""))
11717               (const_string "alu")
11718            ]
11719            (const_string "ishift")))
11720    (set_attr "mode" "SI")])
11722 (define_expand "ashlhi3"
11723   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11724         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11725                    (match_operand:QI 2 "nonmemory_operand" "")))]
11726   "TARGET_HIMODE_MATH"
11727   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11729 (define_insn "*ashlhi3_1_lea"
11730   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11731         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11732                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11733    (clobber (reg:CC FLAGS_REG))]
11734   "!TARGET_PARTIAL_REG_STALL
11735    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11737   switch (get_attr_type (insn))
11738     {
11739     case TYPE_LEA:
11740       return "#";
11741     case TYPE_ALU:
11742       gcc_assert (operands[2] == const1_rtx);
11743       return "add{w}\t%0, %0";
11745     default:
11746       if (REG_P (operands[2]))
11747         return "sal{w}\t{%b2, %0|%0, %b2}";
11748       else if (operands[2] == const1_rtx
11749                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11750         return "sal{w}\t%0";
11751       else
11752         return "sal{w}\t{%2, %0|%0, %2}";
11753     }
11755   [(set (attr "type")
11756      (cond [(eq_attr "alternative" "1")
11757               (const_string "lea")
11758             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11759                           (const_int 0))
11760                       (match_operand 0 "register_operand" ""))
11761                  (match_operand 2 "const1_operand" ""))
11762               (const_string "alu")
11763            ]
11764            (const_string "ishift")))
11765    (set_attr "mode" "HI,SI")])
11767 (define_insn "*ashlhi3_1"
11768   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11769         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11770                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11771    (clobber (reg:CC FLAGS_REG))]
11772   "TARGET_PARTIAL_REG_STALL
11773    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11775   switch (get_attr_type (insn))
11776     {
11777     case TYPE_ALU:
11778       gcc_assert (operands[2] == const1_rtx);
11779       return "add{w}\t%0, %0";
11781     default:
11782       if (REG_P (operands[2]))
11783         return "sal{w}\t{%b2, %0|%0, %b2}";
11784       else if (operands[2] == const1_rtx
11785                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11786         return "sal{w}\t%0";
11787       else
11788         return "sal{w}\t{%2, %0|%0, %2}";
11789     }
11791   [(set (attr "type")
11792      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11793                           (const_int 0))
11794                       (match_operand 0 "register_operand" ""))
11795                  (match_operand 2 "const1_operand" ""))
11796               (const_string "alu")
11797            ]
11798            (const_string "ishift")))
11799    (set_attr "mode" "HI")])
11801 ;; This pattern can't accept a variable shift count, since shifts by
11802 ;; zero don't affect the flags.  We assume that shifts by constant
11803 ;; zero are optimized away.
11804 (define_insn "*ashlhi3_cmp"
11805   [(set (reg FLAGS_REG)
11806         (compare
11807           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11808                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11809           (const_int 0)))
11810    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11811         (ashift:HI (match_dup 1) (match_dup 2)))]
11812   "(optimize_function_for_size_p (cfun)
11813     || !TARGET_PARTIAL_FLAG_REG_STALL
11814     || (operands[2] == const1_rtx
11815         && (TARGET_SHIFT1
11816             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11817    && ix86_match_ccmode (insn, CCGOCmode)
11818    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11820   switch (get_attr_type (insn))
11821     {
11822     case TYPE_ALU:
11823       gcc_assert (operands[2] == const1_rtx);
11824       return "add{w}\t%0, %0";
11826     default:
11827       if (REG_P (operands[2]))
11828         return "sal{w}\t{%b2, %0|%0, %b2}";
11829       else if (operands[2] == const1_rtx
11830                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11831         return "sal{w}\t%0";
11832       else
11833         return "sal{w}\t{%2, %0|%0, %2}";
11834     }
11836   [(set (attr "type")
11837      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11838                           (const_int 0))
11839                       (match_operand 0 "register_operand" ""))
11840                  (match_operand 2 "const1_operand" ""))
11841               (const_string "alu")
11842            ]
11843            (const_string "ishift")))
11844    (set_attr "mode" "HI")])
11846 (define_insn "*ashlhi3_cconly"
11847   [(set (reg FLAGS_REG)
11848         (compare
11849           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11850                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11851           (const_int 0)))
11852    (clobber (match_scratch:HI 0 "=r"))]
11853   "(optimize_function_for_size_p (cfun)
11854     || !TARGET_PARTIAL_FLAG_REG_STALL
11855     || (operands[2] == const1_rtx
11856         && (TARGET_SHIFT1
11857             || TARGET_DOUBLE_WITH_ADD)))
11858    && ix86_match_ccmode (insn, CCGOCmode)
11859    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11861   switch (get_attr_type (insn))
11862     {
11863     case TYPE_ALU:
11864       gcc_assert (operands[2] == const1_rtx);
11865       return "add{w}\t%0, %0";
11867     default:
11868       if (REG_P (operands[2]))
11869         return "sal{w}\t{%b2, %0|%0, %b2}";
11870       else if (operands[2] == const1_rtx
11871                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11872         return "sal{w}\t%0";
11873       else
11874         return "sal{w}\t{%2, %0|%0, %2}";
11875     }
11877   [(set (attr "type")
11878      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11879                           (const_int 0))
11880                       (match_operand 0 "register_operand" ""))
11881                  (match_operand 2 "const1_operand" ""))
11882               (const_string "alu")
11883            ]
11884            (const_string "ishift")))
11885    (set_attr "mode" "HI")])
11887 (define_expand "ashlqi3"
11888   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11889         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11890                    (match_operand:QI 2 "nonmemory_operand" "")))]
11891   "TARGET_QIMODE_MATH"
11892   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11894 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11896 (define_insn "*ashlqi3_1_lea"
11897   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11898         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11899                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11900    (clobber (reg:CC FLAGS_REG))]
11901   "!TARGET_PARTIAL_REG_STALL
11902    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11904   switch (get_attr_type (insn))
11905     {
11906     case TYPE_LEA:
11907       return "#";
11908     case TYPE_ALU:
11909       gcc_assert (operands[2] == const1_rtx);
11910       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11911         return "add{l}\t%k0, %k0";
11912       else
11913         return "add{b}\t%0, %0";
11915     default:
11916       if (REG_P (operands[2]))
11917         {
11918           if (get_attr_mode (insn) == MODE_SI)
11919             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11920           else
11921             return "sal{b}\t{%b2, %0|%0, %b2}";
11922         }
11923       else if (operands[2] == const1_rtx
11924                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11925         {
11926           if (get_attr_mode (insn) == MODE_SI)
11927             return "sal{l}\t%0";
11928           else
11929             return "sal{b}\t%0";
11930         }
11931       else
11932         {
11933           if (get_attr_mode (insn) == MODE_SI)
11934             return "sal{l}\t{%2, %k0|%k0, %2}";
11935           else
11936             return "sal{b}\t{%2, %0|%0, %2}";
11937         }
11938     }
11940   [(set (attr "type")
11941      (cond [(eq_attr "alternative" "2")
11942               (const_string "lea")
11943             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11944                           (const_int 0))
11945                       (match_operand 0 "register_operand" ""))
11946                  (match_operand 2 "const1_operand" ""))
11947               (const_string "alu")
11948            ]
11949            (const_string "ishift")))
11950    (set_attr "mode" "QI,SI,SI")])
11952 (define_insn "*ashlqi3_1"
11953   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11954         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11955                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11956    (clobber (reg:CC FLAGS_REG))]
11957   "TARGET_PARTIAL_REG_STALL
11958    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11960   switch (get_attr_type (insn))
11961     {
11962     case TYPE_ALU:
11963       gcc_assert (operands[2] == const1_rtx);
11964       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11965         return "add{l}\t%k0, %k0";
11966       else
11967         return "add{b}\t%0, %0";
11969     default:
11970       if (REG_P (operands[2]))
11971         {
11972           if (get_attr_mode (insn) == MODE_SI)
11973             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11974           else
11975             return "sal{b}\t{%b2, %0|%0, %b2}";
11976         }
11977       else if (operands[2] == const1_rtx
11978                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11979         {
11980           if (get_attr_mode (insn) == MODE_SI)
11981             return "sal{l}\t%0";
11982           else
11983             return "sal{b}\t%0";
11984         }
11985       else
11986         {
11987           if (get_attr_mode (insn) == MODE_SI)
11988             return "sal{l}\t{%2, %k0|%k0, %2}";
11989           else
11990             return "sal{b}\t{%2, %0|%0, %2}";
11991         }
11992     }
11994   [(set (attr "type")
11995      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11996                           (const_int 0))
11997                       (match_operand 0 "register_operand" ""))
11998                  (match_operand 2 "const1_operand" ""))
11999               (const_string "alu")
12000            ]
12001            (const_string "ishift")))
12002    (set_attr "mode" "QI,SI")])
12004 ;; This pattern can't accept a variable shift count, since shifts by
12005 ;; zero don't affect the flags.  We assume that shifts by constant
12006 ;; zero are optimized away.
12007 (define_insn "*ashlqi3_cmp"
12008   [(set (reg FLAGS_REG)
12009         (compare
12010           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12011                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12012           (const_int 0)))
12013    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12014         (ashift:QI (match_dup 1) (match_dup 2)))]
12015   "(optimize_function_for_size_p (cfun)
12016     || !TARGET_PARTIAL_FLAG_REG_STALL
12017     || (operands[2] == const1_rtx
12018         && (TARGET_SHIFT1
12019             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12020    && ix86_match_ccmode (insn, CCGOCmode)
12021    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12023   switch (get_attr_type (insn))
12024     {
12025     case TYPE_ALU:
12026       gcc_assert (operands[2] == const1_rtx);
12027       return "add{b}\t%0, %0";
12029     default:
12030       if (REG_P (operands[2]))
12031         return "sal{b}\t{%b2, %0|%0, %b2}";
12032       else if (operands[2] == const1_rtx
12033                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12034         return "sal{b}\t%0";
12035       else
12036         return "sal{b}\t{%2, %0|%0, %2}";
12037     }
12039   [(set (attr "type")
12040      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12041                           (const_int 0))
12042                       (match_operand 0 "register_operand" ""))
12043                  (match_operand 2 "const1_operand" ""))
12044               (const_string "alu")
12045            ]
12046            (const_string "ishift")))
12047    (set_attr "mode" "QI")])
12049 (define_insn "*ashlqi3_cconly"
12050   [(set (reg FLAGS_REG)
12051         (compare
12052           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12053                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12054           (const_int 0)))
12055    (clobber (match_scratch:QI 0 "=q"))]
12056   "(optimize_function_for_size_p (cfun)
12057     || !TARGET_PARTIAL_FLAG_REG_STALL
12058     || (operands[2] == const1_rtx
12059         && (TARGET_SHIFT1
12060             || TARGET_DOUBLE_WITH_ADD)))
12061    && ix86_match_ccmode (insn, CCGOCmode)
12062    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12064   switch (get_attr_type (insn))
12065     {
12066     case TYPE_ALU:
12067       gcc_assert (operands[2] == const1_rtx);
12068       return "add{b}\t%0, %0";
12070     default:
12071       if (REG_P (operands[2]))
12072         return "sal{b}\t{%b2, %0|%0, %b2}";
12073       else if (operands[2] == const1_rtx
12074                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12075         return "sal{b}\t%0";
12076       else
12077         return "sal{b}\t{%2, %0|%0, %2}";
12078     }
12080   [(set (attr "type")
12081      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12082                           (const_int 0))
12083                       (match_operand 0 "register_operand" ""))
12084                  (match_operand 2 "const1_operand" ""))
12085               (const_string "alu")
12086            ]
12087            (const_string "ishift")))
12088    (set_attr "mode" "QI")])
12090 ;; See comment above `ashldi3' about how this works.
12092 (define_expand "ashrti3"
12093   [(set (match_operand:TI 0 "register_operand" "")
12094         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12095                      (match_operand:QI 2 "nonmemory_operand" "")))]
12096   "TARGET_64BIT"
12097   "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
12099 (define_insn "*ashrti3_1"
12100   [(set (match_operand:TI 0 "register_operand" "=r")
12101         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
12102                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
12103    (clobber (reg:CC FLAGS_REG))]
12104   "TARGET_64BIT"
12105   "#"
12106   [(set_attr "type" "multi")])
12108 (define_peephole2
12109   [(match_scratch:DI 3 "r")
12110    (parallel [(set (match_operand:TI 0 "register_operand" "")
12111                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12112                                 (match_operand:QI 2 "nonmemory_operand" "")))
12113               (clobber (reg:CC FLAGS_REG))])
12114    (match_dup 3)]
12115   "TARGET_64BIT"
12116   [(const_int 0)]
12117   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
12119 (define_split
12120   [(set (match_operand:TI 0 "register_operand" "")
12121         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12122                      (match_operand:QI 2 "nonmemory_operand" "")))
12123    (clobber (reg:CC FLAGS_REG))]
12124   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12125                     ? epilogue_completed : reload_completed)"
12126   [(const_int 0)]
12127   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
12129 (define_insn "x86_64_shrd"
12130   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
12131         (ior:DI (ashiftrt:DI (match_dup 0)
12132                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
12133                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
12134                   (minus:QI (const_int 64) (match_dup 2)))))
12135    (clobber (reg:CC FLAGS_REG))]
12136   "TARGET_64BIT"
12137   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
12138   [(set_attr "type" "ishift")
12139    (set_attr "prefix_0f" "1")
12140    (set_attr "mode" "DI")
12141    (set_attr "athlon_decode" "vector")
12142    (set_attr "amdfam10_decode" "vector")])
12144 (define_expand "ashrdi3"
12145   [(set (match_operand:DI 0 "shiftdi_operand" "")
12146         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12147                      (match_operand:QI 2 "nonmemory_operand" "")))]
12148   ""
12149   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
12151 (define_expand "x86_64_shift_adj_3"
12152   [(use (match_operand:DI 0 "register_operand" ""))
12153    (use (match_operand:DI 1 "register_operand" ""))
12154    (use (match_operand:QI 2 "register_operand" ""))]
12155   ""
12157   rtx label = gen_label_rtx ();
12158   rtx tmp;
12160   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
12162   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12163   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12164   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12165                               gen_rtx_LABEL_REF (VOIDmode, label),
12166                               pc_rtx);
12167   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12168   JUMP_LABEL (tmp) = label;
12170   emit_move_insn (operands[0], operands[1]);
12171   emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
12173   emit_label (label);
12174   LABEL_NUSES (label) = 1;
12176   DONE;
12179 (define_insn "ashrdi3_63_rex64"
12180   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
12181         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
12182                      (match_operand:DI 2 "const_int_operand" "i,i")))
12183    (clobber (reg:CC FLAGS_REG))]
12184   "TARGET_64BIT && INTVAL (operands[2]) == 63
12185    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12186    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12187   "@
12188    {cqto|cqo}
12189    sar{q}\t{%2, %0|%0, %2}"
12190   [(set_attr "type" "imovx,ishift")
12191    (set_attr "prefix_0f" "0,*")
12192    (set_attr "length_immediate" "0,*")
12193    (set_attr "modrm" "0,1")
12194    (set_attr "mode" "DI")])
12196 (define_insn "*ashrdi3_1_one_bit_rex64"
12197   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12198         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12199                      (match_operand:QI 2 "const1_operand" "")))
12200    (clobber (reg:CC FLAGS_REG))]
12201   "TARGET_64BIT
12202    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12203    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12204   "sar{q}\t%0"
12205   [(set_attr "type" "ishift")
12206    (set (attr "length")
12207      (if_then_else (match_operand:DI 0 "register_operand" "")
12208         (const_string "2")
12209         (const_string "*")))])
12211 (define_insn "*ashrdi3_1_rex64"
12212   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12213         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12214                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12215    (clobber (reg:CC FLAGS_REG))]
12216   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12217   "@
12218    sar{q}\t{%2, %0|%0, %2}
12219    sar{q}\t{%b2, %0|%0, %b2}"
12220   [(set_attr "type" "ishift")
12221    (set_attr "mode" "DI")])
12223 ;; This pattern can't accept a variable shift count, since shifts by
12224 ;; zero don't affect the flags.  We assume that shifts by constant
12225 ;; zero are optimized away.
12226 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12227   [(set (reg FLAGS_REG)
12228         (compare
12229           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12230                        (match_operand:QI 2 "const1_operand" ""))
12231           (const_int 0)))
12232    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12233         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12234   "TARGET_64BIT
12235    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12236    && ix86_match_ccmode (insn, CCGOCmode)
12237    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12238   "sar{q}\t%0"
12239   [(set_attr "type" "ishift")
12240    (set (attr "length")
12241      (if_then_else (match_operand:DI 0 "register_operand" "")
12242         (const_string "2")
12243         (const_string "*")))])
12245 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12246   [(set (reg FLAGS_REG)
12247         (compare
12248           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12249                        (match_operand:QI 2 "const1_operand" ""))
12250           (const_int 0)))
12251    (clobber (match_scratch:DI 0 "=r"))]
12252   "TARGET_64BIT
12253    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12254    && ix86_match_ccmode (insn, CCGOCmode)
12255    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12256   "sar{q}\t%0"
12257   [(set_attr "type" "ishift")
12258    (set_attr "length" "2")])
12260 ;; This pattern can't accept a variable shift count, since shifts by
12261 ;; zero don't affect the flags.  We assume that shifts by constant
12262 ;; zero are optimized away.
12263 (define_insn "*ashrdi3_cmp_rex64"
12264   [(set (reg FLAGS_REG)
12265         (compare
12266           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12267                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12268           (const_int 0)))
12269    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12270         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12271   "TARGET_64BIT
12272    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12273    && ix86_match_ccmode (insn, CCGOCmode)
12274    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12275   "sar{q}\t{%2, %0|%0, %2}"
12276   [(set_attr "type" "ishift")
12277    (set_attr "mode" "DI")])
12279 (define_insn "*ashrdi3_cconly_rex64"
12280   [(set (reg FLAGS_REG)
12281         (compare
12282           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12283                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12284           (const_int 0)))
12285    (clobber (match_scratch:DI 0 "=r"))]
12286   "TARGET_64BIT
12287    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12288    && ix86_match_ccmode (insn, CCGOCmode)
12289    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12290   "sar{q}\t{%2, %0|%0, %2}"
12291   [(set_attr "type" "ishift")
12292    (set_attr "mode" "DI")])
12294 (define_insn "*ashrdi3_1"
12295   [(set (match_operand:DI 0 "register_operand" "=r")
12296         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12297                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12298    (clobber (reg:CC FLAGS_REG))]
12299   "!TARGET_64BIT"
12300   "#"
12301   [(set_attr "type" "multi")])
12303 ;; By default we don't ask for a scratch register, because when DImode
12304 ;; values are manipulated, registers are already at a premium.  But if
12305 ;; we have one handy, we won't turn it away.
12306 (define_peephole2
12307   [(match_scratch:SI 3 "r")
12308    (parallel [(set (match_operand:DI 0 "register_operand" "")
12309                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12310                                 (match_operand:QI 2 "nonmemory_operand" "")))
12311               (clobber (reg:CC FLAGS_REG))])
12312    (match_dup 3)]
12313   "!TARGET_64BIT && TARGET_CMOVE"
12314   [(const_int 0)]
12315   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12317 (define_split
12318   [(set (match_operand:DI 0 "register_operand" "")
12319         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12320                      (match_operand:QI 2 "nonmemory_operand" "")))
12321    (clobber (reg:CC FLAGS_REG))]
12322   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12323                      ? epilogue_completed : reload_completed)"
12324   [(const_int 0)]
12325   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12327 (define_insn "x86_shrd"
12328   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12329         (ior:SI (ashiftrt:SI (match_dup 0)
12330                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
12331                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12332                   (minus:QI (const_int 32) (match_dup 2)))))
12333    (clobber (reg:CC FLAGS_REG))]
12334   ""
12335   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12336   [(set_attr "type" "ishift")
12337    (set_attr "prefix_0f" "1")
12338    (set_attr "pent_pair" "np")
12339    (set_attr "mode" "SI")])
12341 (define_expand "x86_shift_adj_3"
12342   [(use (match_operand:SI 0 "register_operand" ""))
12343    (use (match_operand:SI 1 "register_operand" ""))
12344    (use (match_operand:QI 2 "register_operand" ""))]
12345   ""
12347   rtx label = gen_label_rtx ();
12348   rtx tmp;
12350   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12352   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12353   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12354   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12355                               gen_rtx_LABEL_REF (VOIDmode, label),
12356                               pc_rtx);
12357   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12358   JUMP_LABEL (tmp) = label;
12360   emit_move_insn (operands[0], operands[1]);
12361   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12363   emit_label (label);
12364   LABEL_NUSES (label) = 1;
12366   DONE;
12369 (define_expand "ashrsi3_31"
12370   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12371                    (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12372                                 (match_operand:SI 2 "const_int_operand" "i,i")))
12373               (clobber (reg:CC FLAGS_REG))])]
12374   "")
12376 (define_insn "*ashrsi3_31"
12377   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12378         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12379                      (match_operand:SI 2 "const_int_operand" "i,i")))
12380    (clobber (reg:CC FLAGS_REG))]
12381   "INTVAL (operands[2]) == 31
12382    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12383    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12384   "@
12385    {cltd|cdq}
12386    sar{l}\t{%2, %0|%0, %2}"
12387   [(set_attr "type" "imovx,ishift")
12388    (set_attr "prefix_0f" "0,*")
12389    (set_attr "length_immediate" "0,*")
12390    (set_attr "modrm" "0,1")
12391    (set_attr "mode" "SI")])
12393 (define_insn "*ashrsi3_31_zext"
12394   [(set (match_operand:DI 0 "register_operand" "=*d,r")
12395         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12396                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
12397    (clobber (reg:CC FLAGS_REG))]
12398   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12399    && INTVAL (operands[2]) == 31
12400    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12401   "@
12402    {cltd|cdq}
12403    sar{l}\t{%2, %k0|%k0, %2}"
12404   [(set_attr "type" "imovx,ishift")
12405    (set_attr "prefix_0f" "0,*")
12406    (set_attr "length_immediate" "0,*")
12407    (set_attr "modrm" "0,1")
12408    (set_attr "mode" "SI")])
12410 (define_expand "ashrsi3"
12411   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12412         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12413                      (match_operand:QI 2 "nonmemory_operand" "")))]
12414   ""
12415   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12417 (define_insn "*ashrsi3_1_one_bit"
12418   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12419         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12420                      (match_operand:QI 2 "const1_operand" "")))
12421    (clobber (reg:CC FLAGS_REG))]
12422   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12423    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12424   "sar{l}\t%0"
12425   [(set_attr "type" "ishift")
12426    (set (attr "length")
12427      (if_then_else (match_operand:SI 0 "register_operand" "")
12428         (const_string "2")
12429         (const_string "*")))])
12431 (define_insn "*ashrsi3_1_one_bit_zext"
12432   [(set (match_operand:DI 0 "register_operand" "=r")
12433         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12434                                      (match_operand:QI 2 "const1_operand" ""))))
12435    (clobber (reg:CC FLAGS_REG))]
12436   "TARGET_64BIT
12437    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12438    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12439   "sar{l}\t%k0"
12440   [(set_attr "type" "ishift")
12441    (set_attr "length" "2")])
12443 (define_insn "*ashrsi3_1"
12444   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12445         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12446                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12447    (clobber (reg:CC FLAGS_REG))]
12448   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12449   "@
12450    sar{l}\t{%2, %0|%0, %2}
12451    sar{l}\t{%b2, %0|%0, %b2}"
12452   [(set_attr "type" "ishift")
12453    (set_attr "mode" "SI")])
12455 (define_insn "*ashrsi3_1_zext"
12456   [(set (match_operand:DI 0 "register_operand" "=r,r")
12457         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12458                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12459    (clobber (reg:CC FLAGS_REG))]
12460   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12461   "@
12462    sar{l}\t{%2, %k0|%k0, %2}
12463    sar{l}\t{%b2, %k0|%k0, %b2}"
12464   [(set_attr "type" "ishift")
12465    (set_attr "mode" "SI")])
12467 ;; This pattern can't accept a variable shift count, since shifts by
12468 ;; zero don't affect the flags.  We assume that shifts by constant
12469 ;; zero are optimized away.
12470 (define_insn "*ashrsi3_one_bit_cmp"
12471   [(set (reg FLAGS_REG)
12472         (compare
12473           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12474                        (match_operand:QI 2 "const1_operand" ""))
12475           (const_int 0)))
12476    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12477         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12478   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12479    && ix86_match_ccmode (insn, CCGOCmode)
12480    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12481   "sar{l}\t%0"
12482   [(set_attr "type" "ishift")
12483    (set (attr "length")
12484      (if_then_else (match_operand:SI 0 "register_operand" "")
12485         (const_string "2")
12486         (const_string "*")))])
12488 (define_insn "*ashrsi3_one_bit_cconly"
12489   [(set (reg FLAGS_REG)
12490         (compare
12491           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12492                        (match_operand:QI 2 "const1_operand" ""))
12493           (const_int 0)))
12494    (clobber (match_scratch:SI 0 "=r"))]
12495   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12496    && ix86_match_ccmode (insn, CCGOCmode)
12497    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12498   "sar{l}\t%0"
12499   [(set_attr "type" "ishift")
12500    (set_attr "length" "2")])
12502 (define_insn "*ashrsi3_one_bit_cmp_zext"
12503   [(set (reg FLAGS_REG)
12504         (compare
12505           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12506                        (match_operand:QI 2 "const1_operand" ""))
12507           (const_int 0)))
12508    (set (match_operand:DI 0 "register_operand" "=r")
12509         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12510   "TARGET_64BIT
12511    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12512    && ix86_match_ccmode (insn, CCmode)
12513    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12514   "sar{l}\t%k0"
12515   [(set_attr "type" "ishift")
12516    (set_attr "length" "2")])
12518 ;; This pattern can't accept a variable shift count, since shifts by
12519 ;; zero don't affect the flags.  We assume that shifts by constant
12520 ;; zero are optimized away.
12521 (define_insn "*ashrsi3_cmp"
12522   [(set (reg FLAGS_REG)
12523         (compare
12524           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12525                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12526           (const_int 0)))
12527    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12528         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12529   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12530    && ix86_match_ccmode (insn, CCGOCmode)
12531    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12532   "sar{l}\t{%2, %0|%0, %2}"
12533   [(set_attr "type" "ishift")
12534    (set_attr "mode" "SI")])
12536 (define_insn "*ashrsi3_cconly"
12537   [(set (reg FLAGS_REG)
12538         (compare
12539           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12540                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12541           (const_int 0)))
12542    (clobber (match_scratch:SI 0 "=r"))]
12543   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12544    && ix86_match_ccmode (insn, CCGOCmode)
12545    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12546   "sar{l}\t{%2, %0|%0, %2}"
12547   [(set_attr "type" "ishift")
12548    (set_attr "mode" "SI")])
12550 (define_insn "*ashrsi3_cmp_zext"
12551   [(set (reg FLAGS_REG)
12552         (compare
12553           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12554                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12555           (const_int 0)))
12556    (set (match_operand:DI 0 "register_operand" "=r")
12557         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12558   "TARGET_64BIT
12559    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12560    && ix86_match_ccmode (insn, CCGOCmode)
12561    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12562   "sar{l}\t{%2, %k0|%k0, %2}"
12563   [(set_attr "type" "ishift")
12564    (set_attr "mode" "SI")])
12566 (define_expand "ashrhi3"
12567   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12568         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12569                      (match_operand:QI 2 "nonmemory_operand" "")))]
12570   "TARGET_HIMODE_MATH"
12571   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12573 (define_insn "*ashrhi3_1_one_bit"
12574   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12575         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12576                      (match_operand:QI 2 "const1_operand" "")))
12577    (clobber (reg:CC FLAGS_REG))]
12578   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12579    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12580   "sar{w}\t%0"
12581   [(set_attr "type" "ishift")
12582    (set (attr "length")
12583      (if_then_else (match_operand 0 "register_operand" "")
12584         (const_string "2")
12585         (const_string "*")))])
12587 (define_insn "*ashrhi3_1"
12588   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12589         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12590                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12591    (clobber (reg:CC FLAGS_REG))]
12592   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12593   "@
12594    sar{w}\t{%2, %0|%0, %2}
12595    sar{w}\t{%b2, %0|%0, %b2}"
12596   [(set_attr "type" "ishift")
12597    (set_attr "mode" "HI")])
12599 ;; This pattern can't accept a variable shift count, since shifts by
12600 ;; zero don't affect the flags.  We assume that shifts by constant
12601 ;; zero are optimized away.
12602 (define_insn "*ashrhi3_one_bit_cmp"
12603   [(set (reg FLAGS_REG)
12604         (compare
12605           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12606                        (match_operand:QI 2 "const1_operand" ""))
12607           (const_int 0)))
12608    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12609         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12610   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12611    && ix86_match_ccmode (insn, CCGOCmode)
12612    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12613   "sar{w}\t%0"
12614   [(set_attr "type" "ishift")
12615    (set (attr "length")
12616      (if_then_else (match_operand 0 "register_operand" "")
12617         (const_string "2")
12618         (const_string "*")))])
12620 (define_insn "*ashrhi3_one_bit_cconly"
12621   [(set (reg FLAGS_REG)
12622         (compare
12623           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12624                        (match_operand:QI 2 "const1_operand" ""))
12625           (const_int 0)))
12626    (clobber (match_scratch:HI 0 "=r"))]
12627   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12628    && ix86_match_ccmode (insn, CCGOCmode)
12629    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12630   "sar{w}\t%0"
12631   [(set_attr "type" "ishift")
12632    (set_attr "length" "2")])
12634 ;; This pattern can't accept a variable shift count, since shifts by
12635 ;; zero don't affect the flags.  We assume that shifts by constant
12636 ;; zero are optimized away.
12637 (define_insn "*ashrhi3_cmp"
12638   [(set (reg FLAGS_REG)
12639         (compare
12640           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12641                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12642           (const_int 0)))
12643    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12644         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12645   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12646    && ix86_match_ccmode (insn, CCGOCmode)
12647    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12648   "sar{w}\t{%2, %0|%0, %2}"
12649   [(set_attr "type" "ishift")
12650    (set_attr "mode" "HI")])
12652 (define_insn "*ashrhi3_cconly"
12653   [(set (reg FLAGS_REG)
12654         (compare
12655           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12656                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12657           (const_int 0)))
12658    (clobber (match_scratch:HI 0 "=r"))]
12659   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12660    && ix86_match_ccmode (insn, CCGOCmode)
12661    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12662   "sar{w}\t{%2, %0|%0, %2}"
12663   [(set_attr "type" "ishift")
12664    (set_attr "mode" "HI")])
12666 (define_expand "ashrqi3"
12667   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12668         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12669                      (match_operand:QI 2 "nonmemory_operand" "")))]
12670   "TARGET_QIMODE_MATH"
12671   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12673 (define_insn "*ashrqi3_1_one_bit"
12674   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12675         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12676                      (match_operand:QI 2 "const1_operand" "")))
12677    (clobber (reg:CC FLAGS_REG))]
12678   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12679    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12680   "sar{b}\t%0"
12681   [(set_attr "type" "ishift")
12682    (set (attr "length")
12683      (if_then_else (match_operand 0 "register_operand" "")
12684         (const_string "2")
12685         (const_string "*")))])
12687 (define_insn "*ashrqi3_1_one_bit_slp"
12688   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12689         (ashiftrt:QI (match_dup 0)
12690                      (match_operand:QI 1 "const1_operand" "")))
12691    (clobber (reg:CC FLAGS_REG))]
12692   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12693    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12694    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12695   "sar{b}\t%0"
12696   [(set_attr "type" "ishift1")
12697    (set (attr "length")
12698      (if_then_else (match_operand 0 "register_operand" "")
12699         (const_string "2")
12700         (const_string "*")))])
12702 (define_insn "*ashrqi3_1"
12703   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12704         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12705                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12706    (clobber (reg:CC FLAGS_REG))]
12707   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12708   "@
12709    sar{b}\t{%2, %0|%0, %2}
12710    sar{b}\t{%b2, %0|%0, %b2}"
12711   [(set_attr "type" "ishift")
12712    (set_attr "mode" "QI")])
12714 (define_insn "*ashrqi3_1_slp"
12715   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12716         (ashiftrt:QI (match_dup 0)
12717                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12718    (clobber (reg:CC FLAGS_REG))]
12719   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12720    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12721   "@
12722    sar{b}\t{%1, %0|%0, %1}
12723    sar{b}\t{%b1, %0|%0, %b1}"
12724   [(set_attr "type" "ishift1")
12725    (set_attr "mode" "QI")])
12727 ;; This pattern can't accept a variable shift count, since shifts by
12728 ;; zero don't affect the flags.  We assume that shifts by constant
12729 ;; zero are optimized away.
12730 (define_insn "*ashrqi3_one_bit_cmp"
12731   [(set (reg FLAGS_REG)
12732         (compare
12733           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12734                        (match_operand:QI 2 "const1_operand" "I"))
12735           (const_int 0)))
12736    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12737         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12738   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12739    && ix86_match_ccmode (insn, CCGOCmode)
12740    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12741   "sar{b}\t%0"
12742   [(set_attr "type" "ishift")
12743    (set (attr "length")
12744      (if_then_else (match_operand 0 "register_operand" "")
12745         (const_string "2")
12746         (const_string "*")))])
12748 (define_insn "*ashrqi3_one_bit_cconly"
12749   [(set (reg FLAGS_REG)
12750         (compare
12751           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12752                        (match_operand:QI 2 "const1_operand" ""))
12753           (const_int 0)))
12754    (clobber (match_scratch:QI 0 "=q"))]
12755   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12756    && ix86_match_ccmode (insn, CCGOCmode)
12757    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12758   "sar{b}\t%0"
12759   [(set_attr "type" "ishift")
12760    (set_attr "length" "2")])
12762 ;; This pattern can't accept a variable shift count, since shifts by
12763 ;; zero don't affect the flags.  We assume that shifts by constant
12764 ;; zero are optimized away.
12765 (define_insn "*ashrqi3_cmp"
12766   [(set (reg FLAGS_REG)
12767         (compare
12768           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12769                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12770           (const_int 0)))
12771    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12772         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12773   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12774    && ix86_match_ccmode (insn, CCGOCmode)
12775    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12776   "sar{b}\t{%2, %0|%0, %2}"
12777   [(set_attr "type" "ishift")
12778    (set_attr "mode" "QI")])
12780 (define_insn "*ashrqi3_cconly"
12781   [(set (reg FLAGS_REG)
12782         (compare
12783           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12784                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12785           (const_int 0)))
12786    (clobber (match_scratch:QI 0 "=q"))]
12787   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12788    && ix86_match_ccmode (insn, CCGOCmode)
12789    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12790   "sar{b}\t{%2, %0|%0, %2}"
12791   [(set_attr "type" "ishift")
12792    (set_attr "mode" "QI")])
12795 ;; Logical shift instructions
12797 ;; See comment above `ashldi3' about how this works.
12799 (define_expand "lshrti3"
12800   [(set (match_operand:TI 0 "register_operand" "")
12801         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12802                      (match_operand:QI 2 "nonmemory_operand" "")))]
12803   "TARGET_64BIT"
12804   "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12806 ;; This pattern must be defined before *lshrti3_1 to prevent
12807 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12809 (define_insn "*avx_lshrti3"
12810   [(set (match_operand:TI 0 "register_operand" "=x")
12811         (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
12812                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12813   "TARGET_AVX"
12815   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12816   return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
12818   [(set_attr "type" "sseishft")
12819    (set_attr "prefix" "vex")
12820    (set_attr "mode" "TI")])
12822 (define_insn "sse2_lshrti3"
12823   [(set (match_operand:TI 0 "register_operand" "=x")
12824         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12825                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12826   "TARGET_SSE2"
12828   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12829   return "psrldq\t{%2, %0|%0, %2}";
12831   [(set_attr "type" "sseishft")
12832    (set_attr "prefix_data16" "1")
12833    (set_attr "mode" "TI")])
12835 (define_insn "*lshrti3_1"
12836   [(set (match_operand:TI 0 "register_operand" "=r")
12837         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12838                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
12839    (clobber (reg:CC FLAGS_REG))]
12840   "TARGET_64BIT"
12841   "#"
12842   [(set_attr "type" "multi")])
12844 (define_peephole2
12845   [(match_scratch:DI 3 "r")
12846    (parallel [(set (match_operand:TI 0 "register_operand" "")
12847                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12848                                 (match_operand:QI 2 "nonmemory_operand" "")))
12849               (clobber (reg:CC FLAGS_REG))])
12850    (match_dup 3)]
12851   "TARGET_64BIT"
12852   [(const_int 0)]
12853   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12855 (define_split
12856   [(set (match_operand:TI 0 "register_operand" "")
12857         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12858                      (match_operand:QI 2 "nonmemory_operand" "")))
12859    (clobber (reg:CC FLAGS_REG))]
12860   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12861                     ? epilogue_completed : reload_completed)"
12862   [(const_int 0)]
12863   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12865 (define_expand "lshrdi3"
12866   [(set (match_operand:DI 0 "shiftdi_operand" "")
12867         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12868                      (match_operand:QI 2 "nonmemory_operand" "")))]
12869   ""
12870   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12872 (define_insn "*lshrdi3_1_one_bit_rex64"
12873   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12874         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12875                      (match_operand:QI 2 "const1_operand" "")))
12876    (clobber (reg:CC FLAGS_REG))]
12877   "TARGET_64BIT
12878    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12879    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12880   "shr{q}\t%0"
12881   [(set_attr "type" "ishift")
12882    (set (attr "length")
12883      (if_then_else (match_operand:DI 0 "register_operand" "")
12884         (const_string "2")
12885         (const_string "*")))])
12887 (define_insn "*lshrdi3_1_rex64"
12888   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12889         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12890                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12891    (clobber (reg:CC FLAGS_REG))]
12892   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12893   "@
12894    shr{q}\t{%2, %0|%0, %2}
12895    shr{q}\t{%b2, %0|%0, %b2}"
12896   [(set_attr "type" "ishift")
12897    (set_attr "mode" "DI")])
12899 ;; This pattern can't accept a variable shift count, since shifts by
12900 ;; zero don't affect the flags.  We assume that shifts by constant
12901 ;; zero are optimized away.
12902 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12903   [(set (reg FLAGS_REG)
12904         (compare
12905           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12906                        (match_operand:QI 2 "const1_operand" ""))
12907           (const_int 0)))
12908    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12909         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12910   "TARGET_64BIT
12911    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12912    && ix86_match_ccmode (insn, CCGOCmode)
12913    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12914   "shr{q}\t%0"
12915   [(set_attr "type" "ishift")
12916    (set (attr "length")
12917      (if_then_else (match_operand:DI 0 "register_operand" "")
12918         (const_string "2")
12919         (const_string "*")))])
12921 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12922   [(set (reg FLAGS_REG)
12923         (compare
12924           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12925                        (match_operand:QI 2 "const1_operand" ""))
12926           (const_int 0)))
12927    (clobber (match_scratch:DI 0 "=r"))]
12928   "TARGET_64BIT
12929    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12930    && ix86_match_ccmode (insn, CCGOCmode)
12931    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12932   "shr{q}\t%0"
12933   [(set_attr "type" "ishift")
12934    (set_attr "length" "2")])
12936 ;; This pattern can't accept a variable shift count, since shifts by
12937 ;; zero don't affect the flags.  We assume that shifts by constant
12938 ;; zero are optimized away.
12939 (define_insn "*lshrdi3_cmp_rex64"
12940   [(set (reg FLAGS_REG)
12941         (compare
12942           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12943                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12944           (const_int 0)))
12945    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12946         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12947   "TARGET_64BIT
12948    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12949    && ix86_match_ccmode (insn, CCGOCmode)
12950    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12951   "shr{q}\t{%2, %0|%0, %2}"
12952   [(set_attr "type" "ishift")
12953    (set_attr "mode" "DI")])
12955 (define_insn "*lshrdi3_cconly_rex64"
12956   [(set (reg FLAGS_REG)
12957         (compare
12958           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12959                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12960           (const_int 0)))
12961    (clobber (match_scratch:DI 0 "=r"))]
12962   "TARGET_64BIT
12963    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12964    && ix86_match_ccmode (insn, CCGOCmode)
12965    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12966   "shr{q}\t{%2, %0|%0, %2}"
12967   [(set_attr "type" "ishift")
12968    (set_attr "mode" "DI")])
12970 (define_insn "*lshrdi3_1"
12971   [(set (match_operand:DI 0 "register_operand" "=r")
12972         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12973                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12974    (clobber (reg:CC FLAGS_REG))]
12975   "!TARGET_64BIT"
12976   "#"
12977   [(set_attr "type" "multi")])
12979 ;; By default we don't ask for a scratch register, because when DImode
12980 ;; values are manipulated, registers are already at a premium.  But if
12981 ;; we have one handy, we won't turn it away.
12982 (define_peephole2
12983   [(match_scratch:SI 3 "r")
12984    (parallel [(set (match_operand:DI 0 "register_operand" "")
12985                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12986                                 (match_operand:QI 2 "nonmemory_operand" "")))
12987               (clobber (reg:CC FLAGS_REG))])
12988    (match_dup 3)]
12989   "!TARGET_64BIT && TARGET_CMOVE"
12990   [(const_int 0)]
12991   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12993 (define_split
12994   [(set (match_operand:DI 0 "register_operand" "")
12995         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12996                      (match_operand:QI 2 "nonmemory_operand" "")))
12997    (clobber (reg:CC FLAGS_REG))]
12998   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12999                      ? epilogue_completed : reload_completed)"
13000   [(const_int 0)]
13001   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
13003 (define_expand "lshrsi3"
13004   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13005         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
13006                      (match_operand:QI 2 "nonmemory_operand" "")))]
13007   ""
13008   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
13010 (define_insn "*lshrsi3_1_one_bit"
13011   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13012         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13013                      (match_operand:QI 2 "const1_operand" "")))
13014    (clobber (reg:CC FLAGS_REG))]
13015   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13016    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13017   "shr{l}\t%0"
13018   [(set_attr "type" "ishift")
13019    (set (attr "length")
13020      (if_then_else (match_operand:SI 0 "register_operand" "")
13021         (const_string "2")
13022         (const_string "*")))])
13024 (define_insn "*lshrsi3_1_one_bit_zext"
13025   [(set (match_operand:DI 0 "register_operand" "=r")
13026         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
13027                      (match_operand:QI 2 "const1_operand" "")))
13028    (clobber (reg:CC FLAGS_REG))]
13029   "TARGET_64BIT
13030    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13031    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13032   "shr{l}\t%k0"
13033   [(set_attr "type" "ishift")
13034    (set_attr "length" "2")])
13036 (define_insn "*lshrsi3_1"
13037   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13038         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13039                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13040    (clobber (reg:CC FLAGS_REG))]
13041   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13042   "@
13043    shr{l}\t{%2, %0|%0, %2}
13044    shr{l}\t{%b2, %0|%0, %b2}"
13045   [(set_attr "type" "ishift")
13046    (set_attr "mode" "SI")])
13048 (define_insn "*lshrsi3_1_zext"
13049   [(set (match_operand:DI 0 "register_operand" "=r,r")
13050         (zero_extend:DI
13051           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13052                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13053    (clobber (reg:CC FLAGS_REG))]
13054   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13055   "@
13056    shr{l}\t{%2, %k0|%k0, %2}
13057    shr{l}\t{%b2, %k0|%k0, %b2}"
13058   [(set_attr "type" "ishift")
13059    (set_attr "mode" "SI")])
13061 ;; This pattern can't accept a variable shift count, since shifts by
13062 ;; zero don't affect the flags.  We assume that shifts by constant
13063 ;; zero are optimized away.
13064 (define_insn "*lshrsi3_one_bit_cmp"
13065   [(set (reg FLAGS_REG)
13066         (compare
13067           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13068                        (match_operand:QI 2 "const1_operand" ""))
13069           (const_int 0)))
13070    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13071         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13072   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13073    && ix86_match_ccmode (insn, CCGOCmode)
13074    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13075   "shr{l}\t%0"
13076   [(set_attr "type" "ishift")
13077    (set (attr "length")
13078      (if_then_else (match_operand:SI 0 "register_operand" "")
13079         (const_string "2")
13080         (const_string "*")))])
13082 (define_insn "*lshrsi3_one_bit_cconly"
13083   [(set (reg FLAGS_REG)
13084         (compare
13085           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13086                        (match_operand:QI 2 "const1_operand" ""))
13087           (const_int 0)))
13088    (clobber (match_scratch:SI 0 "=r"))]
13089   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13090    && ix86_match_ccmode (insn, CCGOCmode)
13091    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13092   "shr{l}\t%0"
13093   [(set_attr "type" "ishift")
13094    (set_attr "length" "2")])
13096 (define_insn "*lshrsi3_cmp_one_bit_zext"
13097   [(set (reg FLAGS_REG)
13098         (compare
13099           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13100                        (match_operand:QI 2 "const1_operand" ""))
13101           (const_int 0)))
13102    (set (match_operand:DI 0 "register_operand" "=r")
13103         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13104   "TARGET_64BIT
13105    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13106    && ix86_match_ccmode (insn, CCGOCmode)
13107    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13108   "shr{l}\t%k0"
13109   [(set_attr "type" "ishift")
13110    (set_attr "length" "2")])
13112 ;; This pattern can't accept a variable shift count, since shifts by
13113 ;; zero don't affect the flags.  We assume that shifts by constant
13114 ;; zero are optimized away.
13115 (define_insn "*lshrsi3_cmp"
13116   [(set (reg FLAGS_REG)
13117         (compare
13118           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13119                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13120           (const_int 0)))
13121    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13122         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13123   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13124    && ix86_match_ccmode (insn, CCGOCmode)
13125    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13126   "shr{l}\t{%2, %0|%0, %2}"
13127   [(set_attr "type" "ishift")
13128    (set_attr "mode" "SI")])
13130 (define_insn "*lshrsi3_cconly"
13131   [(set (reg FLAGS_REG)
13132       (compare
13133         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13134                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
13135         (const_int 0)))
13136    (clobber (match_scratch:SI 0 "=r"))]
13137   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13138    && ix86_match_ccmode (insn, CCGOCmode)
13139    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13140   "shr{l}\t{%2, %0|%0, %2}"
13141   [(set_attr "type" "ishift")
13142    (set_attr "mode" "SI")])
13144 (define_insn "*lshrsi3_cmp_zext"
13145   [(set (reg FLAGS_REG)
13146         (compare
13147           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13148                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13149           (const_int 0)))
13150    (set (match_operand:DI 0 "register_operand" "=r")
13151         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13152   "TARGET_64BIT
13153    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13154    && ix86_match_ccmode (insn, CCGOCmode)
13155    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13156   "shr{l}\t{%2, %k0|%k0, %2}"
13157   [(set_attr "type" "ishift")
13158    (set_attr "mode" "SI")])
13160 (define_expand "lshrhi3"
13161   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13162         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13163                      (match_operand:QI 2 "nonmemory_operand" "")))]
13164   "TARGET_HIMODE_MATH"
13165   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
13167 (define_insn "*lshrhi3_1_one_bit"
13168   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13169         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13170                      (match_operand:QI 2 "const1_operand" "")))
13171    (clobber (reg:CC FLAGS_REG))]
13172   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13173    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13174   "shr{w}\t%0"
13175   [(set_attr "type" "ishift")
13176    (set (attr "length")
13177      (if_then_else (match_operand 0 "register_operand" "")
13178         (const_string "2")
13179         (const_string "*")))])
13181 (define_insn "*lshrhi3_1"
13182   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13183         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13184                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13185    (clobber (reg:CC FLAGS_REG))]
13186   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13187   "@
13188    shr{w}\t{%2, %0|%0, %2}
13189    shr{w}\t{%b2, %0|%0, %b2}"
13190   [(set_attr "type" "ishift")
13191    (set_attr "mode" "HI")])
13193 ;; This pattern can't accept a variable shift count, since shifts by
13194 ;; zero don't affect the flags.  We assume that shifts by constant
13195 ;; zero are optimized away.
13196 (define_insn "*lshrhi3_one_bit_cmp"
13197   [(set (reg FLAGS_REG)
13198         (compare
13199           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13200                        (match_operand:QI 2 "const1_operand" ""))
13201           (const_int 0)))
13202    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13203         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13204   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13205    && ix86_match_ccmode (insn, CCGOCmode)
13206    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13207   "shr{w}\t%0"
13208   [(set_attr "type" "ishift")
13209    (set (attr "length")
13210      (if_then_else (match_operand:SI 0 "register_operand" "")
13211         (const_string "2")
13212         (const_string "*")))])
13214 (define_insn "*lshrhi3_one_bit_cconly"
13215   [(set (reg FLAGS_REG)
13216         (compare
13217           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13218                        (match_operand:QI 2 "const1_operand" ""))
13219           (const_int 0)))
13220    (clobber (match_scratch:HI 0 "=r"))]
13221   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13222    && ix86_match_ccmode (insn, CCGOCmode)
13223    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13224   "shr{w}\t%0"
13225   [(set_attr "type" "ishift")
13226    (set_attr "length" "2")])
13228 ;; This pattern can't accept a variable shift count, since shifts by
13229 ;; zero don't affect the flags.  We assume that shifts by constant
13230 ;; zero are optimized away.
13231 (define_insn "*lshrhi3_cmp"
13232   [(set (reg FLAGS_REG)
13233         (compare
13234           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13235                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13236           (const_int 0)))
13237    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13238         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13239   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13240    && ix86_match_ccmode (insn, CCGOCmode)
13241    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13242   "shr{w}\t{%2, %0|%0, %2}"
13243   [(set_attr "type" "ishift")
13244    (set_attr "mode" "HI")])
13246 (define_insn "*lshrhi3_cconly"
13247   [(set (reg FLAGS_REG)
13248         (compare
13249           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13250                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13251           (const_int 0)))
13252    (clobber (match_scratch:HI 0 "=r"))]
13253   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13254    && ix86_match_ccmode (insn, CCGOCmode)
13255    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13256   "shr{w}\t{%2, %0|%0, %2}"
13257   [(set_attr "type" "ishift")
13258    (set_attr "mode" "HI")])
13260 (define_expand "lshrqi3"
13261   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13262         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13263                      (match_operand:QI 2 "nonmemory_operand" "")))]
13264   "TARGET_QIMODE_MATH"
13265   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13267 (define_insn "*lshrqi3_1_one_bit"
13268   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13269         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13270                      (match_operand:QI 2 "const1_operand" "")))
13271    (clobber (reg:CC FLAGS_REG))]
13272   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13273    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13274   "shr{b}\t%0"
13275   [(set_attr "type" "ishift")
13276    (set (attr "length")
13277      (if_then_else (match_operand 0 "register_operand" "")
13278         (const_string "2")
13279         (const_string "*")))])
13281 (define_insn "*lshrqi3_1_one_bit_slp"
13282   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13283         (lshiftrt:QI (match_dup 0)
13284                      (match_operand:QI 1 "const1_operand" "")))
13285    (clobber (reg:CC FLAGS_REG))]
13286   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13287    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13288   "shr{b}\t%0"
13289   [(set_attr "type" "ishift1")
13290    (set (attr "length")
13291      (if_then_else (match_operand 0 "register_operand" "")
13292         (const_string "2")
13293         (const_string "*")))])
13295 (define_insn "*lshrqi3_1"
13296   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13297         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13298                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13299    (clobber (reg:CC FLAGS_REG))]
13300   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13301   "@
13302    shr{b}\t{%2, %0|%0, %2}
13303    shr{b}\t{%b2, %0|%0, %b2}"
13304   [(set_attr "type" "ishift")
13305    (set_attr "mode" "QI")])
13307 (define_insn "*lshrqi3_1_slp"
13308   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13309         (lshiftrt:QI (match_dup 0)
13310                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13311    (clobber (reg:CC FLAGS_REG))]
13312   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13313    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13314   "@
13315    shr{b}\t{%1, %0|%0, %1}
13316    shr{b}\t{%b1, %0|%0, %b1}"
13317   [(set_attr "type" "ishift1")
13318    (set_attr "mode" "QI")])
13320 ;; This pattern can't accept a variable shift count, since shifts by
13321 ;; zero don't affect the flags.  We assume that shifts by constant
13322 ;; zero are optimized away.
13323 (define_insn "*lshrqi2_one_bit_cmp"
13324   [(set (reg FLAGS_REG)
13325         (compare
13326           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13327                        (match_operand:QI 2 "const1_operand" ""))
13328           (const_int 0)))
13329    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13330         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13331   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13332    && ix86_match_ccmode (insn, CCGOCmode)
13333    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13334   "shr{b}\t%0"
13335   [(set_attr "type" "ishift")
13336    (set (attr "length")
13337      (if_then_else (match_operand:SI 0 "register_operand" "")
13338         (const_string "2")
13339         (const_string "*")))])
13341 (define_insn "*lshrqi2_one_bit_cconly"
13342   [(set (reg FLAGS_REG)
13343         (compare
13344           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13345                        (match_operand:QI 2 "const1_operand" ""))
13346           (const_int 0)))
13347    (clobber (match_scratch:QI 0 "=q"))]
13348   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13349    && ix86_match_ccmode (insn, CCGOCmode)
13350    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13351   "shr{b}\t%0"
13352   [(set_attr "type" "ishift")
13353    (set_attr "length" "2")])
13355 ;; This pattern can't accept a variable shift count, since shifts by
13356 ;; zero don't affect the flags.  We assume that shifts by constant
13357 ;; zero are optimized away.
13358 (define_insn "*lshrqi2_cmp"
13359   [(set (reg FLAGS_REG)
13360         (compare
13361           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13362                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13363           (const_int 0)))
13364    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13365         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13366   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13367    && ix86_match_ccmode (insn, CCGOCmode)
13368    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13369   "shr{b}\t{%2, %0|%0, %2}"
13370   [(set_attr "type" "ishift")
13371    (set_attr "mode" "QI")])
13373 (define_insn "*lshrqi2_cconly"
13374   [(set (reg FLAGS_REG)
13375         (compare
13376           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13377                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13378           (const_int 0)))
13379    (clobber (match_scratch:QI 0 "=q"))]
13380   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13381    && ix86_match_ccmode (insn, CCGOCmode)
13382    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13383   "shr{b}\t{%2, %0|%0, %2}"
13384   [(set_attr "type" "ishift")
13385    (set_attr "mode" "QI")])
13387 ;; Rotate instructions
13389 (define_expand "rotldi3"
13390   [(set (match_operand:DI 0 "shiftdi_operand" "")
13391         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13392                    (match_operand:QI 2 "nonmemory_operand" "")))]
13393  ""
13395   if (TARGET_64BIT)
13396     {
13397       ix86_expand_binary_operator (ROTATE, DImode, operands);
13398       DONE;
13399     }
13400   if (!const_1_to_31_operand (operands[2], VOIDmode))
13401     FAIL;
13402   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13403   DONE;
13406 ;; Implement rotation using two double-precision shift instructions
13407 ;; and a scratch register.
13408 (define_insn_and_split "ix86_rotldi3"
13409  [(set (match_operand:DI 0 "register_operand" "=r")
13410        (rotate:DI (match_operand:DI 1 "register_operand" "0")
13411                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
13412   (clobber (reg:CC FLAGS_REG))
13413   (clobber (match_scratch:SI 3 "=&r"))]
13414  "!TARGET_64BIT"
13415  ""
13416  "&& reload_completed"
13417  [(set (match_dup 3) (match_dup 4))
13418   (parallel
13419    [(set (match_dup 4)
13420          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13421                  (lshiftrt:SI (match_dup 5)
13422                               (minus:QI (const_int 32) (match_dup 2)))))
13423     (clobber (reg:CC FLAGS_REG))])
13424   (parallel
13425    [(set (match_dup 5)
13426          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13427                  (lshiftrt:SI (match_dup 3)
13428                               (minus:QI (const_int 32) (match_dup 2)))))
13429     (clobber (reg:CC FLAGS_REG))])]
13430  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13432 (define_insn "*rotlsi3_1_one_bit_rex64"
13433   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13434         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13435                    (match_operand:QI 2 "const1_operand" "")))
13436    (clobber (reg:CC FLAGS_REG))]
13437   "TARGET_64BIT
13438    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13439    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13440   "rol{q}\t%0"
13441   [(set_attr "type" "rotate")
13442    (set (attr "length")
13443      (if_then_else (match_operand:DI 0 "register_operand" "")
13444         (const_string "2")
13445         (const_string "*")))])
13447 (define_insn "*rotldi3_1_rex64"
13448   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13449         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13450                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
13451    (clobber (reg:CC FLAGS_REG))]
13452   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13453   "@
13454    rol{q}\t{%2, %0|%0, %2}
13455    rol{q}\t{%b2, %0|%0, %b2}"
13456   [(set_attr "type" "rotate")
13457    (set_attr "mode" "DI")])
13459 (define_expand "rotlsi3"
13460   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13461         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13462                    (match_operand:QI 2 "nonmemory_operand" "")))]
13463   ""
13464   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13466 (define_insn "*rotlsi3_1_one_bit"
13467   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13468         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13469                    (match_operand:QI 2 "const1_operand" "")))
13470    (clobber (reg:CC FLAGS_REG))]
13471   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13472    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13473   "rol{l}\t%0"
13474   [(set_attr "type" "rotate")
13475    (set (attr "length")
13476      (if_then_else (match_operand:SI 0 "register_operand" "")
13477         (const_string "2")
13478         (const_string "*")))])
13480 (define_insn "*rotlsi3_1_one_bit_zext"
13481   [(set (match_operand:DI 0 "register_operand" "=r")
13482         (zero_extend:DI
13483           (rotate:SI (match_operand:SI 1 "register_operand" "0")
13484                      (match_operand:QI 2 "const1_operand" ""))))
13485    (clobber (reg:CC FLAGS_REG))]
13486   "TARGET_64BIT
13487    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13488    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13489   "rol{l}\t%k0"
13490   [(set_attr "type" "rotate")
13491    (set_attr "length" "2")])
13493 (define_insn "*rotlsi3_1"
13494   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13495         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13496                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13497    (clobber (reg:CC FLAGS_REG))]
13498   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13499   "@
13500    rol{l}\t{%2, %0|%0, %2}
13501    rol{l}\t{%b2, %0|%0, %b2}"
13502   [(set_attr "type" "rotate")
13503    (set_attr "mode" "SI")])
13505 (define_insn "*rotlsi3_1_zext"
13506   [(set (match_operand:DI 0 "register_operand" "=r,r")
13507         (zero_extend:DI
13508           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13509                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13510    (clobber (reg:CC FLAGS_REG))]
13511   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13512   "@
13513    rol{l}\t{%2, %k0|%k0, %2}
13514    rol{l}\t{%b2, %k0|%k0, %b2}"
13515   [(set_attr "type" "rotate")
13516    (set_attr "mode" "SI")])
13518 (define_expand "rotlhi3"
13519   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13520         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13521                    (match_operand:QI 2 "nonmemory_operand" "")))]
13522   "TARGET_HIMODE_MATH"
13523   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13525 (define_insn "*rotlhi3_1_one_bit"
13526   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13527         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13528                    (match_operand:QI 2 "const1_operand" "")))
13529    (clobber (reg:CC FLAGS_REG))]
13530   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13531    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13532   "rol{w}\t%0"
13533   [(set_attr "type" "rotate")
13534    (set (attr "length")
13535      (if_then_else (match_operand 0 "register_operand" "")
13536         (const_string "2")
13537         (const_string "*")))])
13539 (define_insn "*rotlhi3_1"
13540   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13541         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13542                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13543    (clobber (reg:CC FLAGS_REG))]
13544   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13545   "@
13546    rol{w}\t{%2, %0|%0, %2}
13547    rol{w}\t{%b2, %0|%0, %b2}"
13548   [(set_attr "type" "rotate")
13549    (set_attr "mode" "HI")])
13551 (define_split
13552  [(set (match_operand:HI 0 "register_operand" "")
13553        (rotate:HI (match_dup 0) (const_int 8)))
13554   (clobber (reg:CC FLAGS_REG))]
13555  "reload_completed"
13556  [(parallel [(set (strict_low_part (match_dup 0))
13557                   (bswap:HI (match_dup 0)))
13558              (clobber (reg:CC FLAGS_REG))])]
13559  "")
13561 (define_expand "rotlqi3"
13562   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13563         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13564                    (match_operand:QI 2 "nonmemory_operand" "")))]
13565   "TARGET_QIMODE_MATH"
13566   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13568 (define_insn "*rotlqi3_1_one_bit_slp"
13569   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13570         (rotate:QI (match_dup 0)
13571                    (match_operand:QI 1 "const1_operand" "")))
13572    (clobber (reg:CC FLAGS_REG))]
13573   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13574    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13575   "rol{b}\t%0"
13576   [(set_attr "type" "rotate1")
13577    (set (attr "length")
13578      (if_then_else (match_operand 0 "register_operand" "")
13579         (const_string "2")
13580         (const_string "*")))])
13582 (define_insn "*rotlqi3_1_one_bit"
13583   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13584         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13585                    (match_operand:QI 2 "const1_operand" "")))
13586    (clobber (reg:CC FLAGS_REG))]
13587   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13588    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13589   "rol{b}\t%0"
13590   [(set_attr "type" "rotate")
13591    (set (attr "length")
13592      (if_then_else (match_operand 0 "register_operand" "")
13593         (const_string "2")
13594         (const_string "*")))])
13596 (define_insn "*rotlqi3_1_slp"
13597   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13598         (rotate:QI (match_dup 0)
13599                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13600    (clobber (reg:CC FLAGS_REG))]
13601   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13602    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13603   "@
13604    rol{b}\t{%1, %0|%0, %1}
13605    rol{b}\t{%b1, %0|%0, %b1}"
13606   [(set_attr "type" "rotate1")
13607    (set_attr "mode" "QI")])
13609 (define_insn "*rotlqi3_1"
13610   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13611         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13612                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13613    (clobber (reg:CC FLAGS_REG))]
13614   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13615   "@
13616    rol{b}\t{%2, %0|%0, %2}
13617    rol{b}\t{%b2, %0|%0, %b2}"
13618   [(set_attr "type" "rotate")
13619    (set_attr "mode" "QI")])
13621 (define_expand "rotrdi3"
13622   [(set (match_operand:DI 0 "shiftdi_operand" "")
13623         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13624                    (match_operand:QI 2 "nonmemory_operand" "")))]
13625  ""
13627   if (TARGET_64BIT)
13628     {
13629       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13630       DONE;
13631     }
13632   if (!const_1_to_31_operand (operands[2], VOIDmode))
13633     FAIL;
13634   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13635   DONE;
13638 ;; Implement rotation using two double-precision shift instructions
13639 ;; and a scratch register.
13640 (define_insn_and_split "ix86_rotrdi3"
13641  [(set (match_operand:DI 0 "register_operand" "=r")
13642        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13643                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13644   (clobber (reg:CC FLAGS_REG))
13645   (clobber (match_scratch:SI 3 "=&r"))]
13646  "!TARGET_64BIT"
13647  ""
13648  "&& reload_completed"
13649  [(set (match_dup 3) (match_dup 4))
13650   (parallel
13651    [(set (match_dup 4)
13652          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13653                  (ashift:SI (match_dup 5)
13654                             (minus:QI (const_int 32) (match_dup 2)))))
13655     (clobber (reg:CC FLAGS_REG))])
13656   (parallel
13657    [(set (match_dup 5)
13658          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13659                  (ashift:SI (match_dup 3)
13660                             (minus:QI (const_int 32) (match_dup 2)))))
13661     (clobber (reg:CC FLAGS_REG))])]
13662  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13664 (define_insn "*rotrdi3_1_one_bit_rex64"
13665   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13666         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13667                      (match_operand:QI 2 "const1_operand" "")))
13668    (clobber (reg:CC FLAGS_REG))]
13669   "TARGET_64BIT
13670    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13671    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13672   "ror{q}\t%0"
13673   [(set_attr "type" "rotate")
13674    (set (attr "length")
13675      (if_then_else (match_operand:DI 0 "register_operand" "")
13676         (const_string "2")
13677         (const_string "*")))])
13679 (define_insn "*rotrdi3_1_rex64"
13680   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13681         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13682                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13683    (clobber (reg:CC FLAGS_REG))]
13684   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13685   "@
13686    ror{q}\t{%2, %0|%0, %2}
13687    ror{q}\t{%b2, %0|%0, %b2}"
13688   [(set_attr "type" "rotate")
13689    (set_attr "mode" "DI")])
13691 (define_expand "rotrsi3"
13692   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13693         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13694                      (match_operand:QI 2 "nonmemory_operand" "")))]
13695   ""
13696   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13698 (define_insn "*rotrsi3_1_one_bit"
13699   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13700         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13701                      (match_operand:QI 2 "const1_operand" "")))
13702    (clobber (reg:CC FLAGS_REG))]
13703   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13704    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13705   "ror{l}\t%0"
13706   [(set_attr "type" "rotate")
13707    (set (attr "length")
13708      (if_then_else (match_operand:SI 0 "register_operand" "")
13709         (const_string "2")
13710         (const_string "*")))])
13712 (define_insn "*rotrsi3_1_one_bit_zext"
13713   [(set (match_operand:DI 0 "register_operand" "=r")
13714         (zero_extend:DI
13715           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13716                        (match_operand:QI 2 "const1_operand" ""))))
13717    (clobber (reg:CC FLAGS_REG))]
13718   "TARGET_64BIT
13719    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13720    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13721   "ror{l}\t%k0"
13722   [(set_attr "type" "rotate")
13723    (set (attr "length")
13724      (if_then_else (match_operand:SI 0 "register_operand" "")
13725         (const_string "2")
13726         (const_string "*")))])
13728 (define_insn "*rotrsi3_1"
13729   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13730         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13731                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13732    (clobber (reg:CC FLAGS_REG))]
13733   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13734   "@
13735    ror{l}\t{%2, %0|%0, %2}
13736    ror{l}\t{%b2, %0|%0, %b2}"
13737   [(set_attr "type" "rotate")
13738    (set_attr "mode" "SI")])
13740 (define_insn "*rotrsi3_1_zext"
13741   [(set (match_operand:DI 0 "register_operand" "=r,r")
13742         (zero_extend:DI
13743           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13744                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13745    (clobber (reg:CC FLAGS_REG))]
13746   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13747   "@
13748    ror{l}\t{%2, %k0|%k0, %2}
13749    ror{l}\t{%b2, %k0|%k0, %b2}"
13750   [(set_attr "type" "rotate")
13751    (set_attr "mode" "SI")])
13753 (define_expand "rotrhi3"
13754   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13755         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13756                      (match_operand:QI 2 "nonmemory_operand" "")))]
13757   "TARGET_HIMODE_MATH"
13758   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13760 (define_insn "*rotrhi3_one_bit"
13761   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13762         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13763                      (match_operand:QI 2 "const1_operand" "")))
13764    (clobber (reg:CC FLAGS_REG))]
13765   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13766    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13767   "ror{w}\t%0"
13768   [(set_attr "type" "rotate")
13769    (set (attr "length")
13770      (if_then_else (match_operand 0 "register_operand" "")
13771         (const_string "2")
13772         (const_string "*")))])
13774 (define_insn "*rotrhi3_1"
13775   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13776         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13777                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13778    (clobber (reg:CC FLAGS_REG))]
13779   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13780   "@
13781    ror{w}\t{%2, %0|%0, %2}
13782    ror{w}\t{%b2, %0|%0, %b2}"
13783   [(set_attr "type" "rotate")
13784    (set_attr "mode" "HI")])
13786 (define_split
13787  [(set (match_operand:HI 0 "register_operand" "")
13788        (rotatert:HI (match_dup 0) (const_int 8)))
13789   (clobber (reg:CC FLAGS_REG))]
13790  "reload_completed"
13791  [(parallel [(set (strict_low_part (match_dup 0))
13792                   (bswap:HI (match_dup 0)))
13793              (clobber (reg:CC FLAGS_REG))])]
13794  "")
13796 (define_expand "rotrqi3"
13797   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13798         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13799                      (match_operand:QI 2 "nonmemory_operand" "")))]
13800   "TARGET_QIMODE_MATH"
13801   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13803 (define_insn "*rotrqi3_1_one_bit"
13804   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13805         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13806                      (match_operand:QI 2 "const1_operand" "")))
13807    (clobber (reg:CC FLAGS_REG))]
13808   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13809    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13810   "ror{b}\t%0"
13811   [(set_attr "type" "rotate")
13812    (set (attr "length")
13813      (if_then_else (match_operand 0 "register_operand" "")
13814         (const_string "2")
13815         (const_string "*")))])
13817 (define_insn "*rotrqi3_1_one_bit_slp"
13818   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13819         (rotatert:QI (match_dup 0)
13820                      (match_operand:QI 1 "const1_operand" "")))
13821    (clobber (reg:CC FLAGS_REG))]
13822   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13823    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13824   "ror{b}\t%0"
13825   [(set_attr "type" "rotate1")
13826    (set (attr "length")
13827      (if_then_else (match_operand 0 "register_operand" "")
13828         (const_string "2")
13829         (const_string "*")))])
13831 (define_insn "*rotrqi3_1"
13832   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13833         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13834                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13835    (clobber (reg:CC FLAGS_REG))]
13836   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13837   "@
13838    ror{b}\t{%2, %0|%0, %2}
13839    ror{b}\t{%b2, %0|%0, %b2}"
13840   [(set_attr "type" "rotate")
13841    (set_attr "mode" "QI")])
13843 (define_insn "*rotrqi3_1_slp"
13844   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13845         (rotatert:QI (match_dup 0)
13846                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13847    (clobber (reg:CC FLAGS_REG))]
13848   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13849    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13850   "@
13851    ror{b}\t{%1, %0|%0, %1}
13852    ror{b}\t{%b1, %0|%0, %b1}"
13853   [(set_attr "type" "rotate1")
13854    (set_attr "mode" "QI")])
13856 ;; Bit set / bit test instructions
13858 (define_expand "extv"
13859   [(set (match_operand:SI 0 "register_operand" "")
13860         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13861                          (match_operand:SI 2 "const8_operand" "")
13862                          (match_operand:SI 3 "const8_operand" "")))]
13863   ""
13865   /* Handle extractions from %ah et al.  */
13866   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13867     FAIL;
13869   /* From mips.md: extract_bit_field doesn't verify that our source
13870      matches the predicate, so check it again here.  */
13871   if (! ext_register_operand (operands[1], VOIDmode))
13872     FAIL;
13875 (define_expand "extzv"
13876   [(set (match_operand:SI 0 "register_operand" "")
13877         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13878                          (match_operand:SI 2 "const8_operand" "")
13879                          (match_operand:SI 3 "const8_operand" "")))]
13880   ""
13882   /* Handle extractions from %ah et al.  */
13883   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13884     FAIL;
13886   /* From mips.md: extract_bit_field doesn't verify that our source
13887      matches the predicate, so check it again here.  */
13888   if (! ext_register_operand (operands[1], VOIDmode))
13889     FAIL;
13892 (define_expand "insv"
13893   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13894                       (match_operand 1 "const8_operand" "")
13895                       (match_operand 2 "const8_operand" ""))
13896         (match_operand 3 "register_operand" ""))]
13897   ""
13899   /* Handle insertions to %ah et al.  */
13900   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13901     FAIL;
13903   /* From mips.md: insert_bit_field doesn't verify that our source
13904      matches the predicate, so check it again here.  */
13905   if (! ext_register_operand (operands[0], VOIDmode))
13906     FAIL;
13908   if (TARGET_64BIT)
13909     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13910   else
13911     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13913   DONE;
13916 ;; %%% bts, btr, btc, bt.
13917 ;; In general these instructions are *slow* when applied to memory,
13918 ;; since they enforce atomic operation.  When applied to registers,
13919 ;; it depends on the cpu implementation.  They're never faster than
13920 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13921 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13922 ;; within the instruction itself, so operating on bits in the high
13923 ;; 32-bits of a register becomes easier.
13925 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13926 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13927 ;; negdf respectively, so they can never be disabled entirely.
13929 (define_insn "*btsq"
13930   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13931                          (const_int 1)
13932                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13933         (const_int 1))
13934    (clobber (reg:CC FLAGS_REG))]
13935   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13936   "bts{q}\t{%1, %0|%0, %1}"
13937   [(set_attr "type" "alu1")])
13939 (define_insn "*btrq"
13940   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13941                          (const_int 1)
13942                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13943         (const_int 0))
13944    (clobber (reg:CC FLAGS_REG))]
13945   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13946   "btr{q}\t{%1, %0|%0, %1}"
13947   [(set_attr "type" "alu1")])
13949 (define_insn "*btcq"
13950   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13951                          (const_int 1)
13952                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13953         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13954    (clobber (reg:CC FLAGS_REG))]
13955   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13956   "btc{q}\t{%1, %0|%0, %1}"
13957   [(set_attr "type" "alu1")])
13959 ;; Allow Nocona to avoid these instructions if a register is available.
13961 (define_peephole2
13962   [(match_scratch:DI 2 "r")
13963    (parallel [(set (zero_extract:DI
13964                      (match_operand:DI 0 "register_operand" "")
13965                      (const_int 1)
13966                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13967                    (const_int 1))
13968               (clobber (reg:CC FLAGS_REG))])]
13969   "TARGET_64BIT && !TARGET_USE_BT"
13970   [(const_int 0)]
13972   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13973   rtx op1;
13975   if (HOST_BITS_PER_WIDE_INT >= 64)
13976     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13977   else if (i < HOST_BITS_PER_WIDE_INT)
13978     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13979   else
13980     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13982   op1 = immed_double_const (lo, hi, DImode);
13983   if (i >= 31)
13984     {
13985       emit_move_insn (operands[2], op1);
13986       op1 = operands[2];
13987     }
13989   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13990   DONE;
13993 (define_peephole2
13994   [(match_scratch:DI 2 "r")
13995    (parallel [(set (zero_extract:DI
13996                      (match_operand:DI 0 "register_operand" "")
13997                      (const_int 1)
13998                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13999                    (const_int 0))
14000               (clobber (reg:CC FLAGS_REG))])]
14001   "TARGET_64BIT && !TARGET_USE_BT"
14002   [(const_int 0)]
14004   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14005   rtx op1;
14007   if (HOST_BITS_PER_WIDE_INT >= 64)
14008     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14009   else if (i < HOST_BITS_PER_WIDE_INT)
14010     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14011   else
14012     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14014   op1 = immed_double_const (~lo, ~hi, DImode);
14015   if (i >= 32)
14016     {
14017       emit_move_insn (operands[2], op1);
14018       op1 = operands[2];
14019     }
14021   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
14022   DONE;
14025 (define_peephole2
14026   [(match_scratch:DI 2 "r")
14027    (parallel [(set (zero_extract:DI
14028                      (match_operand:DI 0 "register_operand" "")
14029                      (const_int 1)
14030                      (match_operand:DI 1 "const_0_to_63_operand" ""))
14031               (not:DI (zero_extract:DI
14032                         (match_dup 0) (const_int 1) (match_dup 1))))
14033               (clobber (reg:CC FLAGS_REG))])]
14034   "TARGET_64BIT && !TARGET_USE_BT"
14035   [(const_int 0)]
14037   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14038   rtx op1;
14040   if (HOST_BITS_PER_WIDE_INT >= 64)
14041     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14042   else if (i < HOST_BITS_PER_WIDE_INT)
14043     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14044   else
14045     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14047   op1 = immed_double_const (lo, hi, DImode);
14048   if (i >= 31)
14049     {
14050       emit_move_insn (operands[2], op1);
14051       op1 = operands[2];
14052     }
14054   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
14055   DONE;
14058 (define_insn "*btdi_rex64"
14059   [(set (reg:CCC FLAGS_REG)
14060         (compare:CCC
14061           (zero_extract:DI
14062             (match_operand:DI 0 "register_operand" "r")
14063             (const_int 1)
14064             (match_operand:DI 1 "nonmemory_operand" "rN"))
14065           (const_int 0)))]
14066   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14067   "bt{q}\t{%1, %0|%0, %1}"
14068   [(set_attr "type" "alu1")])
14070 (define_insn "*btsi"
14071   [(set (reg:CCC FLAGS_REG)
14072         (compare:CCC
14073           (zero_extract:SI
14074             (match_operand:SI 0 "register_operand" "r")
14075             (const_int 1)
14076             (match_operand:SI 1 "nonmemory_operand" "rN"))
14077           (const_int 0)))]
14078   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14079   "bt{l}\t{%1, %0|%0, %1}"
14080   [(set_attr "type" "alu1")])
14082 ;; Store-flag instructions.
14084 ;; For all sCOND expanders, also expand the compare or test insn that
14085 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
14087 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
14088 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
14089 ;; way, which can later delete the movzx if only QImode is needed.
14091 (define_expand "s<code>"
14092   [(set (match_operand:QI 0 "register_operand" "")
14093         (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14094   ""
14095   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14097 (define_expand "s<code>"
14098   [(set (match_operand:QI 0 "register_operand" "")
14099         (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14100   "TARGET_80387 || TARGET_SSE"
14101   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14103 (define_insn "*setcc_1"
14104   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14105         (match_operator:QI 1 "ix86_comparison_operator"
14106           [(reg FLAGS_REG) (const_int 0)]))]
14107   ""
14108   "set%C1\t%0"
14109   [(set_attr "type" "setcc")
14110    (set_attr "mode" "QI")])
14112 (define_insn "*setcc_2"
14113   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14114         (match_operator:QI 1 "ix86_comparison_operator"
14115           [(reg FLAGS_REG) (const_int 0)]))]
14116   ""
14117   "set%C1\t%0"
14118   [(set_attr "type" "setcc")
14119    (set_attr "mode" "QI")])
14121 ;; In general it is not safe to assume too much about CCmode registers,
14122 ;; so simplify-rtx stops when it sees a second one.  Under certain
14123 ;; conditions this is safe on x86, so help combine not create
14125 ;;      seta    %al
14126 ;;      testb   %al, %al
14127 ;;      sete    %al
14129 (define_split
14130   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14131         (ne:QI (match_operator 1 "ix86_comparison_operator"
14132                  [(reg FLAGS_REG) (const_int 0)])
14133             (const_int 0)))]
14134   ""
14135   [(set (match_dup 0) (match_dup 1))]
14137   PUT_MODE (operands[1], QImode);
14140 (define_split
14141   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14142         (ne:QI (match_operator 1 "ix86_comparison_operator"
14143                  [(reg FLAGS_REG) (const_int 0)])
14144             (const_int 0)))]
14145   ""
14146   [(set (match_dup 0) (match_dup 1))]
14148   PUT_MODE (operands[1], QImode);
14151 (define_split
14152   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14153         (eq:QI (match_operator 1 "ix86_comparison_operator"
14154                  [(reg FLAGS_REG) (const_int 0)])
14155             (const_int 0)))]
14156   ""
14157   [(set (match_dup 0) (match_dup 1))]
14159   rtx new_op1 = copy_rtx (operands[1]);
14160   operands[1] = new_op1;
14161   PUT_MODE (new_op1, QImode);
14162   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14163                                              GET_MODE (XEXP (new_op1, 0))));
14165   /* Make sure that (a) the CCmode we have for the flags is strong
14166      enough for the reversed compare or (b) we have a valid FP compare.  */
14167   if (! ix86_comparison_operator (new_op1, VOIDmode))
14168     FAIL;
14171 (define_split
14172   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14173         (eq:QI (match_operator 1 "ix86_comparison_operator"
14174                  [(reg FLAGS_REG) (const_int 0)])
14175             (const_int 0)))]
14176   ""
14177   [(set (match_dup 0) (match_dup 1))]
14179   rtx new_op1 = copy_rtx (operands[1]);
14180   operands[1] = new_op1;
14181   PUT_MODE (new_op1, QImode);
14182   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14183                                              GET_MODE (XEXP (new_op1, 0))));
14185   /* Make sure that (a) the CCmode we have for the flags is strong
14186      enough for the reversed compare or (b) we have a valid FP compare.  */
14187   if (! ix86_comparison_operator (new_op1, VOIDmode))
14188     FAIL;
14191 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14192 ;; subsequent logical operations are used to imitate conditional moves.
14193 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14194 ;; it directly.
14196 (define_insn "*avx_setcc<mode>"
14197   [(set (match_operand:MODEF 0 "register_operand" "=x")
14198         (match_operator:MODEF 1 "avx_comparison_float_operator"
14199           [(match_operand:MODEF 2 "register_operand" "x")
14200            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14201   "TARGET_AVX"
14202   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14203   [(set_attr "type" "ssecmp")
14204    (set_attr "prefix" "vex")
14205    (set_attr "mode" "<MODE>")])
14207 (define_insn "*sse_setcc<mode>"
14208   [(set (match_operand:MODEF 0 "register_operand" "=x")
14209         (match_operator:MODEF 1 "sse_comparison_operator"
14210           [(match_operand:MODEF 2 "register_operand" "0")
14211            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14212   "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
14213   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
14214   [(set_attr "type" "ssecmp")
14215    (set_attr "mode" "<MODE>")])
14217 (define_insn "*sse5_setcc<mode>"
14218   [(set (match_operand:MODEF 0 "register_operand" "=x")
14219         (match_operator:MODEF 1 "sse5_comparison_float_operator"
14220           [(match_operand:MODEF 2 "register_operand" "x")
14221            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14222   "TARGET_SSE5"
14223   "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14224   [(set_attr "type" "sse4arg")
14225    (set_attr "mode" "<MODE>")])
14228 ;; Basic conditional jump instructions.
14229 ;; We ignore the overflow flag for signed branch instructions.
14231 ;; For all bCOND expanders, also expand the compare or test insn that
14232 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
14234 (define_expand "b<code>"
14235   [(set (pc)
14236         (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
14237                                    (const_int 0))
14238                       (label_ref (match_operand 0 ""))
14239                       (pc)))]
14240   ""
14241   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14243 (define_expand "b<code>"
14244   [(set (pc)
14245         (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
14246                                   (const_int 0))
14247                       (label_ref (match_operand 0 ""))
14248                       (pc)))]
14249   "TARGET_80387 || TARGET_SSE_MATH"
14250   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14252 (define_insn "*jcc_1"
14253   [(set (pc)
14254         (if_then_else (match_operator 1 "ix86_comparison_operator"
14255                                       [(reg FLAGS_REG) (const_int 0)])
14256                       (label_ref (match_operand 0 "" ""))
14257                       (pc)))]
14258   ""
14259   "%+j%C1\t%l0"
14260   [(set_attr "type" "ibr")
14261    (set_attr "modrm" "0")
14262    (set (attr "length")
14263            (if_then_else (and (ge (minus (match_dup 0) (pc))
14264                                   (const_int -126))
14265                               (lt (minus (match_dup 0) (pc))
14266                                   (const_int 128)))
14267              (const_int 2)
14268              (const_int 6)))])
14270 (define_insn "*jcc_2"
14271   [(set (pc)
14272         (if_then_else (match_operator 1 "ix86_comparison_operator"
14273                                       [(reg FLAGS_REG) (const_int 0)])
14274                       (pc)
14275                       (label_ref (match_operand 0 "" ""))))]
14276   ""
14277   "%+j%c1\t%l0"
14278   [(set_attr "type" "ibr")
14279    (set_attr "modrm" "0")
14280    (set (attr "length")
14281            (if_then_else (and (ge (minus (match_dup 0) (pc))
14282                                   (const_int -126))
14283                               (lt (minus (match_dup 0) (pc))
14284                                   (const_int 128)))
14285              (const_int 2)
14286              (const_int 6)))])
14288 ;; In general it is not safe to assume too much about CCmode registers,
14289 ;; so simplify-rtx stops when it sees a second one.  Under certain
14290 ;; conditions this is safe on x86, so help combine not create
14292 ;;      seta    %al
14293 ;;      testb   %al, %al
14294 ;;      je      Lfoo
14296 (define_split
14297   [(set (pc)
14298         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14299                                       [(reg FLAGS_REG) (const_int 0)])
14300                           (const_int 0))
14301                       (label_ref (match_operand 1 "" ""))
14302                       (pc)))]
14303   ""
14304   [(set (pc)
14305         (if_then_else (match_dup 0)
14306                       (label_ref (match_dup 1))
14307                       (pc)))]
14309   PUT_MODE (operands[0], VOIDmode);
14312 (define_split
14313   [(set (pc)
14314         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14315                                       [(reg FLAGS_REG) (const_int 0)])
14316                           (const_int 0))
14317                       (label_ref (match_operand 1 "" ""))
14318                       (pc)))]
14319   ""
14320   [(set (pc)
14321         (if_then_else (match_dup 0)
14322                       (label_ref (match_dup 1))
14323                       (pc)))]
14325   rtx new_op0 = copy_rtx (operands[0]);
14326   operands[0] = new_op0;
14327   PUT_MODE (new_op0, VOIDmode);
14328   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14329                                              GET_MODE (XEXP (new_op0, 0))));
14331   /* Make sure that (a) the CCmode we have for the flags is strong
14332      enough for the reversed compare or (b) we have a valid FP compare.  */
14333   if (! ix86_comparison_operator (new_op0, VOIDmode))
14334     FAIL;
14337 ;; zero_extend in SImode is correct, since this is what combine pass
14338 ;; generates from shift insn with QImode operand.  Actually, the mode of
14339 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14340 ;; appropriate modulo of the bit offset value.
14342 (define_insn_and_split "*jcc_btdi_rex64"
14343   [(set (pc)
14344         (if_then_else (match_operator 0 "bt_comparison_operator"
14345                         [(zero_extract:DI
14346                            (match_operand:DI 1 "register_operand" "r")
14347                            (const_int 1)
14348                            (zero_extend:SI
14349                              (match_operand:QI 2 "register_operand" "r")))
14350                          (const_int 0)])
14351                       (label_ref (match_operand 3 "" ""))
14352                       (pc)))
14353    (clobber (reg:CC FLAGS_REG))]
14354   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14355   "#"
14356   "&& 1"
14357   [(set (reg:CCC FLAGS_REG)
14358         (compare:CCC
14359           (zero_extract:DI
14360             (match_dup 1)
14361             (const_int 1)
14362             (match_dup 2))
14363           (const_int 0)))
14364    (set (pc)
14365         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14366                       (label_ref (match_dup 3))
14367                       (pc)))]
14369   operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14371   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14374 ;; avoid useless masking of bit offset operand
14375 (define_insn_and_split "*jcc_btdi_mask_rex64"
14376   [(set (pc)
14377         (if_then_else (match_operator 0 "bt_comparison_operator"
14378                         [(zero_extract:DI
14379                            (match_operand:DI 1 "register_operand" "r")
14380                            (const_int 1)
14381                            (and:SI
14382                              (match_operand:SI 2 "register_operand" "r")
14383                              (match_operand:SI 3 "const_int_operand" "n")))])
14384                       (label_ref (match_operand 4 "" ""))
14385                       (pc)))
14386    (clobber (reg:CC FLAGS_REG))]
14387   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
14388    && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14389   "#"
14390   "&& 1"
14391   [(set (reg:CCC FLAGS_REG)
14392         (compare:CCC
14393           (zero_extract:DI
14394             (match_dup 1)
14395             (const_int 1)
14396             (match_dup 2))
14397           (const_int 0)))
14398    (set (pc)
14399         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14400                       (label_ref (match_dup 4))
14401                       (pc)))]
14403   operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14405   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14408 (define_insn_and_split "*jcc_btsi"
14409   [(set (pc)
14410         (if_then_else (match_operator 0 "bt_comparison_operator"
14411                         [(zero_extract:SI
14412                            (match_operand:SI 1 "register_operand" "r")
14413                            (const_int 1)
14414                            (zero_extend:SI
14415                              (match_operand:QI 2 "register_operand" "r")))
14416                          (const_int 0)])
14417                       (label_ref (match_operand 3 "" ""))
14418                       (pc)))
14419    (clobber (reg:CC FLAGS_REG))]
14420   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14421   "#"
14422   "&& 1"
14423   [(set (reg:CCC FLAGS_REG)
14424         (compare:CCC
14425           (zero_extract:SI
14426             (match_dup 1)
14427             (const_int 1)
14428             (match_dup 2))
14429           (const_int 0)))
14430    (set (pc)
14431         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14432                       (label_ref (match_dup 3))
14433                       (pc)))]
14435   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14437   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14440 ;; avoid useless masking of bit offset operand
14441 (define_insn_and_split "*jcc_btsi_mask"
14442   [(set (pc)
14443         (if_then_else (match_operator 0 "bt_comparison_operator"
14444                         [(zero_extract:SI
14445                            (match_operand:SI 1 "register_operand" "r")
14446                            (const_int 1)
14447                            (and:SI
14448                              (match_operand:SI 2 "register_operand" "r")
14449                              (match_operand:SI 3 "const_int_operand" "n")))])
14450                       (label_ref (match_operand 4 "" ""))
14451                       (pc)))
14452    (clobber (reg:CC FLAGS_REG))]
14453   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14454    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14455   "#"
14456   "&& 1"
14457   [(set (reg:CCC FLAGS_REG)
14458         (compare:CCC
14459           (zero_extract:SI
14460             (match_dup 1)
14461             (const_int 1)
14462             (match_dup 2))
14463           (const_int 0)))
14464    (set (pc)
14465         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14466                       (label_ref (match_dup 4))
14467                       (pc)))]
14468   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14470 (define_insn_and_split "*jcc_btsi_1"
14471   [(set (pc)
14472         (if_then_else (match_operator 0 "bt_comparison_operator"
14473                         [(and:SI
14474                            (lshiftrt:SI
14475                              (match_operand:SI 1 "register_operand" "r")
14476                              (match_operand:QI 2 "register_operand" "r"))
14477                            (const_int 1))
14478                          (const_int 0)])
14479                       (label_ref (match_operand 3 "" ""))
14480                       (pc)))
14481    (clobber (reg:CC FLAGS_REG))]
14482   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14483   "#"
14484   "&& 1"
14485   [(set (reg:CCC FLAGS_REG)
14486         (compare:CCC
14487           (zero_extract:SI
14488             (match_dup 1)
14489             (const_int 1)
14490             (match_dup 2))
14491           (const_int 0)))
14492    (set (pc)
14493         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14494                       (label_ref (match_dup 3))
14495                       (pc)))]
14497   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14499   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14502 ;; avoid useless masking of bit offset operand
14503 (define_insn_and_split "*jcc_btsi_mask_1"
14504   [(set (pc)
14505         (if_then_else
14506           (match_operator 0 "bt_comparison_operator"
14507             [(and:SI
14508                (lshiftrt:SI
14509                  (match_operand:SI 1 "register_operand" "r")
14510                  (subreg:QI
14511                    (and:SI
14512                      (match_operand:SI 2 "register_operand" "r")
14513                      (match_operand:SI 3 "const_int_operand" "n")) 0))
14514                (const_int 1))
14515              (const_int 0)])
14516           (label_ref (match_operand 4 "" ""))
14517           (pc)))
14518    (clobber (reg:CC FLAGS_REG))]
14519   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14520    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14521   "#"
14522   "&& 1"
14523   [(set (reg:CCC FLAGS_REG)
14524         (compare:CCC
14525           (zero_extract:SI
14526             (match_dup 1)
14527             (const_int 1)
14528             (match_dup 2))
14529           (const_int 0)))
14530    (set (pc)
14531         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14532                       (label_ref (match_dup 4))
14533                       (pc)))]
14534   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14536 ;; Define combination compare-and-branch fp compare instructions to use
14537 ;; during early optimization.  Splitting the operation apart early makes
14538 ;; for bad code when we want to reverse the operation.
14540 (define_insn "*fp_jcc_1_mixed"
14541   [(set (pc)
14542         (if_then_else (match_operator 0 "comparison_operator"
14543                         [(match_operand 1 "register_operand" "f,x")
14544                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14545           (label_ref (match_operand 3 "" ""))
14546           (pc)))
14547    (clobber (reg:CCFP FPSR_REG))
14548    (clobber (reg:CCFP FLAGS_REG))]
14549   "TARGET_MIX_SSE_I387
14550    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14551    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14552    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14553   "#")
14555 (define_insn "*fp_jcc_1_sse"
14556   [(set (pc)
14557         (if_then_else (match_operator 0 "comparison_operator"
14558                         [(match_operand 1 "register_operand" "x")
14559                          (match_operand 2 "nonimmediate_operand" "xm")])
14560           (label_ref (match_operand 3 "" ""))
14561           (pc)))
14562    (clobber (reg:CCFP FPSR_REG))
14563    (clobber (reg:CCFP FLAGS_REG))]
14564   "TARGET_SSE_MATH
14565    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14566    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14567    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14568   "#")
14570 (define_insn "*fp_jcc_1_387"
14571   [(set (pc)
14572         (if_then_else (match_operator 0 "comparison_operator"
14573                         [(match_operand 1 "register_operand" "f")
14574                          (match_operand 2 "register_operand" "f")])
14575           (label_ref (match_operand 3 "" ""))
14576           (pc)))
14577    (clobber (reg:CCFP FPSR_REG))
14578    (clobber (reg:CCFP FLAGS_REG))]
14579   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14580    && TARGET_CMOVE
14581    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14582    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14583   "#")
14585 (define_insn "*fp_jcc_2_mixed"
14586   [(set (pc)
14587         (if_then_else (match_operator 0 "comparison_operator"
14588                         [(match_operand 1 "register_operand" "f,x")
14589                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14590           (pc)
14591           (label_ref (match_operand 3 "" ""))))
14592    (clobber (reg:CCFP FPSR_REG))
14593    (clobber (reg:CCFP FLAGS_REG))]
14594   "TARGET_MIX_SSE_I387
14595    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14596    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14597    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14598   "#")
14600 (define_insn "*fp_jcc_2_sse"
14601   [(set (pc)
14602         (if_then_else (match_operator 0 "comparison_operator"
14603                         [(match_operand 1 "register_operand" "x")
14604                          (match_operand 2 "nonimmediate_operand" "xm")])
14605           (pc)
14606           (label_ref (match_operand 3 "" ""))))
14607    (clobber (reg:CCFP FPSR_REG))
14608    (clobber (reg:CCFP FLAGS_REG))]
14609   "TARGET_SSE_MATH
14610    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14611    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14612    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14613   "#")
14615 (define_insn "*fp_jcc_2_387"
14616   [(set (pc)
14617         (if_then_else (match_operator 0 "comparison_operator"
14618                         [(match_operand 1 "register_operand" "f")
14619                          (match_operand 2 "register_operand" "f")])
14620           (pc)
14621           (label_ref (match_operand 3 "" ""))))
14622    (clobber (reg:CCFP FPSR_REG))
14623    (clobber (reg:CCFP FLAGS_REG))]
14624   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14625    && TARGET_CMOVE
14626    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14627    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14628   "#")
14630 (define_insn "*fp_jcc_3_387"
14631   [(set (pc)
14632         (if_then_else (match_operator 0 "comparison_operator"
14633                         [(match_operand 1 "register_operand" "f")
14634                          (match_operand 2 "nonimmediate_operand" "fm")])
14635           (label_ref (match_operand 3 "" ""))
14636           (pc)))
14637    (clobber (reg:CCFP FPSR_REG))
14638    (clobber (reg:CCFP FLAGS_REG))
14639    (clobber (match_scratch:HI 4 "=a"))]
14640   "TARGET_80387
14641    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14642    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14643    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14644    && SELECT_CC_MODE (GET_CODE (operands[0]),
14645                       operands[1], operands[2]) == CCFPmode
14646    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14647   "#")
14649 (define_insn "*fp_jcc_4_387"
14650   [(set (pc)
14651         (if_then_else (match_operator 0 "comparison_operator"
14652                         [(match_operand 1 "register_operand" "f")
14653                          (match_operand 2 "nonimmediate_operand" "fm")])
14654           (pc)
14655           (label_ref (match_operand 3 "" ""))))
14656    (clobber (reg:CCFP FPSR_REG))
14657    (clobber (reg:CCFP FLAGS_REG))
14658    (clobber (match_scratch:HI 4 "=a"))]
14659   "TARGET_80387
14660    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14661    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14662    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14663    && SELECT_CC_MODE (GET_CODE (operands[0]),
14664                       operands[1], operands[2]) == CCFPmode
14665    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14666   "#")
14668 (define_insn "*fp_jcc_5_387"
14669   [(set (pc)
14670         (if_then_else (match_operator 0 "comparison_operator"
14671                         [(match_operand 1 "register_operand" "f")
14672                          (match_operand 2 "register_operand" "f")])
14673           (label_ref (match_operand 3 "" ""))
14674           (pc)))
14675    (clobber (reg:CCFP FPSR_REG))
14676    (clobber (reg:CCFP FLAGS_REG))
14677    (clobber (match_scratch:HI 4 "=a"))]
14678   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14679    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14680    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14681   "#")
14683 (define_insn "*fp_jcc_6_387"
14684   [(set (pc)
14685         (if_then_else (match_operator 0 "comparison_operator"
14686                         [(match_operand 1 "register_operand" "f")
14687                          (match_operand 2 "register_operand" "f")])
14688           (pc)
14689           (label_ref (match_operand 3 "" ""))))
14690    (clobber (reg:CCFP FPSR_REG))
14691    (clobber (reg:CCFP FLAGS_REG))
14692    (clobber (match_scratch:HI 4 "=a"))]
14693   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14694    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14695    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14696   "#")
14698 (define_insn "*fp_jcc_7_387"
14699   [(set (pc)
14700         (if_then_else (match_operator 0 "comparison_operator"
14701                         [(match_operand 1 "register_operand" "f")
14702                          (match_operand 2 "const0_operand" "")])
14703           (label_ref (match_operand 3 "" ""))
14704           (pc)))
14705    (clobber (reg:CCFP FPSR_REG))
14706    (clobber (reg:CCFP FLAGS_REG))
14707    (clobber (match_scratch:HI 4 "=a"))]
14708   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14709    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14710    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14711    && SELECT_CC_MODE (GET_CODE (operands[0]),
14712                       operands[1], operands[2]) == CCFPmode
14713    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14714   "#")
14716 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14717 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14718 ;; with a precedence over other operators and is always put in the first
14719 ;; place. Swap condition and operands to match ficom instruction.
14721 (define_insn "*fp_jcc_8<mode>_387"
14722   [(set (pc)
14723         (if_then_else (match_operator 0 "comparison_operator"
14724                         [(match_operator 1 "float_operator"
14725                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14726                            (match_operand 3 "register_operand" "f,f")])
14727           (label_ref (match_operand 4 "" ""))
14728           (pc)))
14729    (clobber (reg:CCFP FPSR_REG))
14730    (clobber (reg:CCFP FLAGS_REG))
14731    (clobber (match_scratch:HI 5 "=a,a"))]
14732   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14733    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
14734    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14735    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14736    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14737    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14738   "#")
14740 (define_split
14741   [(set (pc)
14742         (if_then_else (match_operator 0 "comparison_operator"
14743                         [(match_operand 1 "register_operand" "")
14744                          (match_operand 2 "nonimmediate_operand" "")])
14745           (match_operand 3 "" "")
14746           (match_operand 4 "" "")))
14747    (clobber (reg:CCFP FPSR_REG))
14748    (clobber (reg:CCFP FLAGS_REG))]
14749   "reload_completed"
14750   [(const_int 0)]
14752   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14753                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14754   DONE;
14757 (define_split
14758   [(set (pc)
14759         (if_then_else (match_operator 0 "comparison_operator"
14760                         [(match_operand 1 "register_operand" "")
14761                          (match_operand 2 "general_operand" "")])
14762           (match_operand 3 "" "")
14763           (match_operand 4 "" "")))
14764    (clobber (reg:CCFP FPSR_REG))
14765    (clobber (reg:CCFP FLAGS_REG))
14766    (clobber (match_scratch:HI 5 "=a"))]
14767   "reload_completed"
14768   [(const_int 0)]
14770   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14771                         operands[3], operands[4], operands[5], NULL_RTX);
14772   DONE;
14775 (define_split
14776   [(set (pc)
14777         (if_then_else (match_operator 0 "comparison_operator"
14778                         [(match_operator 1 "float_operator"
14779                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14780                            (match_operand 3 "register_operand" "")])
14781           (match_operand 4 "" "")
14782           (match_operand 5 "" "")))
14783    (clobber (reg:CCFP FPSR_REG))
14784    (clobber (reg:CCFP FLAGS_REG))
14785    (clobber (match_scratch:HI 6 "=a"))]
14786   "reload_completed"
14787   [(const_int 0)]
14789   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14790   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14791                         operands[3], operands[7],
14792                         operands[4], operands[5], operands[6], NULL_RTX);
14793   DONE;
14796 ;; %%% Kill this when reload knows how to do it.
14797 (define_split
14798   [(set (pc)
14799         (if_then_else (match_operator 0 "comparison_operator"
14800                         [(match_operator 1 "float_operator"
14801                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14802                            (match_operand 3 "register_operand" "")])
14803           (match_operand 4 "" "")
14804           (match_operand 5 "" "")))
14805    (clobber (reg:CCFP FPSR_REG))
14806    (clobber (reg:CCFP FLAGS_REG))
14807    (clobber (match_scratch:HI 6 "=a"))]
14808   "reload_completed"
14809   [(const_int 0)]
14811   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14812   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14813   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14814                         operands[3], operands[7],
14815                         operands[4], operands[5], operands[6], operands[2]);
14816   DONE;
14819 ;; Unconditional and other jump instructions
14821 (define_insn "jump"
14822   [(set (pc)
14823         (label_ref (match_operand 0 "" "")))]
14824   ""
14825   "jmp\t%l0"
14826   [(set_attr "type" "ibr")
14827    (set (attr "length")
14828            (if_then_else (and (ge (minus (match_dup 0) (pc))
14829                                   (const_int -126))
14830                               (lt (minus (match_dup 0) (pc))
14831                                   (const_int 128)))
14832              (const_int 2)
14833              (const_int 5)))
14834    (set_attr "modrm" "0")])
14836 (define_expand "indirect_jump"
14837   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14838   ""
14839   "")
14841 (define_insn "*indirect_jump"
14842   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14843   ""
14844   "jmp\t%A0"
14845   [(set_attr "type" "ibr")
14846    (set_attr "length_immediate" "0")])
14848 (define_expand "tablejump"
14849   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14850               (use (label_ref (match_operand 1 "" "")))])]
14851   ""
14853   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14854      relative.  Convert the relative address to an absolute address.  */
14855   if (flag_pic)
14856     {
14857       rtx op0, op1;
14858       enum rtx_code code;
14860       /* We can't use @GOTOFF for text labels on VxWorks;
14861          see gotoff_operand.  */
14862       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14863         {
14864           code = PLUS;
14865           op0 = operands[0];
14866           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14867         }
14868       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14869         {
14870           code = PLUS;
14871           op0 = operands[0];
14872           op1 = pic_offset_table_rtx;
14873         }
14874       else
14875         {
14876           code = MINUS;
14877           op0 = pic_offset_table_rtx;
14878           op1 = operands[0];
14879         }
14881       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14882                                          OPTAB_DIRECT);
14883     }
14886 (define_insn "*tablejump_1"
14887   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14888    (use (label_ref (match_operand 1 "" "")))]
14889   ""
14890   "jmp\t%A0"
14891   [(set_attr "type" "ibr")
14892    (set_attr "length_immediate" "0")])
14894 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14896 (define_peephole2
14897   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14898    (set (match_operand:QI 1 "register_operand" "")
14899         (match_operator:QI 2 "ix86_comparison_operator"
14900           [(reg FLAGS_REG) (const_int 0)]))
14901    (set (match_operand 3 "q_regs_operand" "")
14902         (zero_extend (match_dup 1)))]
14903   "(peep2_reg_dead_p (3, operands[1])
14904     || operands_match_p (operands[1], operands[3]))
14905    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14906   [(set (match_dup 4) (match_dup 0))
14907    (set (strict_low_part (match_dup 5))
14908         (match_dup 2))]
14910   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14911   operands[5] = gen_lowpart (QImode, operands[3]);
14912   ix86_expand_clear (operands[3]);
14915 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14917 (define_peephole2
14918   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14919    (set (match_operand:QI 1 "register_operand" "")
14920         (match_operator:QI 2 "ix86_comparison_operator"
14921           [(reg FLAGS_REG) (const_int 0)]))
14922    (parallel [(set (match_operand 3 "q_regs_operand" "")
14923                    (zero_extend (match_dup 1)))
14924               (clobber (reg:CC FLAGS_REG))])]
14925   "(peep2_reg_dead_p (3, operands[1])
14926     || operands_match_p (operands[1], operands[3]))
14927    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14928   [(set (match_dup 4) (match_dup 0))
14929    (set (strict_low_part (match_dup 5))
14930         (match_dup 2))]
14932   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14933   operands[5] = gen_lowpart (QImode, operands[3]);
14934   ix86_expand_clear (operands[3]);
14937 ;; Call instructions.
14939 ;; The predicates normally associated with named expanders are not properly
14940 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14941 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14943 ;; Call subroutine returning no value.
14945 (define_expand "call_pop"
14946   [(parallel [(call (match_operand:QI 0 "" "")
14947                     (match_operand:SI 1 "" ""))
14948               (set (reg:SI SP_REG)
14949                    (plus:SI (reg:SI SP_REG)
14950                             (match_operand:SI 3 "" "")))])]
14951   "!TARGET_64BIT"
14953   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14954   DONE;
14957 (define_insn "*call_pop_0"
14958   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14959          (match_operand:SI 1 "" ""))
14960    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14961                             (match_operand:SI 2 "immediate_operand" "")))]
14962   "!TARGET_64BIT"
14964   if (SIBLING_CALL_P (insn))
14965     return "jmp\t%P0";
14966   else
14967     return "call\t%P0";
14969   [(set_attr "type" "call")])
14971 (define_insn "*call_pop_1"
14972   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14973          (match_operand:SI 1 "" ""))
14974    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14975                             (match_operand:SI 2 "immediate_operand" "i")))]
14976   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14978   if (constant_call_address_operand (operands[0], Pmode))
14979     return "call\t%P0";
14980   return "call\t%A0";
14982   [(set_attr "type" "call")])
14984 (define_insn "*sibcall_pop_1"
14985   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
14986          (match_operand:SI 1 "" ""))
14987    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14988                             (match_operand:SI 2 "immediate_operand" "i,i")))]
14989   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14990   "@
14991    jmp\t%P0
14992    jmp\t%A0"
14993   [(set_attr "type" "call")])
14995 (define_expand "call"
14996   [(call (match_operand:QI 0 "" "")
14997          (match_operand 1 "" ""))
14998    (use (match_operand 2 "" ""))]
14999   ""
15001   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
15002   DONE;
15005 (define_expand "sibcall"
15006   [(call (match_operand:QI 0 "" "")
15007          (match_operand 1 "" ""))
15008    (use (match_operand 2 "" ""))]
15009   ""
15011   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
15012   DONE;
15015 (define_insn "*call_0"
15016   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
15017          (match_operand 1 "" ""))]
15018   ""
15020   if (SIBLING_CALL_P (insn))
15021     return "jmp\t%P0";
15022   else
15023     return "call\t%P0";
15025   [(set_attr "type" "call")])
15027 (define_insn "*call_1"
15028   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15029          (match_operand 1 "" ""))]
15030   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
15032   if (constant_call_address_operand (operands[0], Pmode))
15033     return "call\t%P0";
15034   return "call\t%A0";
15036   [(set_attr "type" "call")])
15038 (define_insn "*sibcall_1"
15039   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
15040          (match_operand 1 "" ""))]
15041   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
15042   "@
15043    jmp\t%P0
15044    jmp\t%A0"
15045   [(set_attr "type" "call")])
15047 (define_insn "*call_1_rex64"
15048   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15049          (match_operand 1 "" ""))]
15050   "!SIBLING_CALL_P (insn) && TARGET_64BIT
15051    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
15053   if (constant_call_address_operand (operands[0], Pmode))
15054     return "call\t%P0";
15055   return "call\t%A0";
15057   [(set_attr "type" "call")])
15059 (define_insn "*call_1_rex64_ms_sysv"
15060   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15061          (match_operand 1 "" ""))
15062    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
15063    (clobber (reg:TI XMM6_REG))
15064    (clobber (reg:TI XMM7_REG))
15065    (clobber (reg:TI XMM8_REG))
15066    (clobber (reg:TI XMM9_REG))
15067    (clobber (reg:TI XMM10_REG))
15068    (clobber (reg:TI XMM11_REG))
15069    (clobber (reg:TI XMM12_REG))
15070    (clobber (reg:TI XMM13_REG))
15071    (clobber (reg:TI XMM14_REG))
15072    (clobber (reg:TI XMM15_REG))
15073    (clobber (reg:DI SI_REG))
15074    (clobber (reg:DI DI_REG))]
15075   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15077   if (constant_call_address_operand (operands[0], Pmode))
15078     return "call\t%P0";
15079   return "call\t%A0";
15081   [(set_attr "type" "call")])
15083 (define_insn "*call_1_rex64_large"
15084   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15085          (match_operand 1 "" ""))]
15086   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15087   "call\t%A0"
15088   [(set_attr "type" "call")])
15090 (define_insn "*sibcall_1_rex64"
15091   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
15092          (match_operand 1 "" ""))]
15093   "SIBLING_CALL_P (insn) && TARGET_64BIT"
15094   "@
15095    jmp\t%P0
15096    jmp\t%A0"
15097   [(set_attr "type" "call")])
15099 ;; Call subroutine, returning value in operand 0
15100 (define_expand "call_value_pop"
15101   [(parallel [(set (match_operand 0 "" "")
15102                    (call (match_operand:QI 1 "" "")
15103                          (match_operand:SI 2 "" "")))
15104               (set (reg:SI SP_REG)
15105                    (plus:SI (reg:SI SP_REG)
15106                             (match_operand:SI 4 "" "")))])]
15107   "!TARGET_64BIT"
15109   ix86_expand_call (operands[0], operands[1], operands[2],
15110                     operands[3], operands[4], 0);
15111   DONE;
15114 (define_expand "call_value"
15115   [(set (match_operand 0 "" "")
15116         (call (match_operand:QI 1 "" "")
15117               (match_operand:SI 2 "" "")))
15118    (use (match_operand:SI 3 "" ""))]
15119   ;; Operand 2 not used on the i386.
15120   ""
15122   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15123   DONE;
15126 (define_expand "sibcall_value"
15127   [(set (match_operand 0 "" "")
15128         (call (match_operand:QI 1 "" "")
15129               (match_operand:SI 2 "" "")))
15130    (use (match_operand:SI 3 "" ""))]
15131   ;; Operand 2 not used on the i386.
15132   ""
15134   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15135   DONE;
15138 ;; Call subroutine returning any type.
15140 (define_expand "untyped_call"
15141   [(parallel [(call (match_operand 0 "" "")
15142                     (const_int 0))
15143               (match_operand 1 "" "")
15144               (match_operand 2 "" "")])]
15145   ""
15147   int i;
15149   /* In order to give reg-stack an easier job in validating two
15150      coprocessor registers as containing a possible return value,
15151      simply pretend the untyped call returns a complex long double
15152      value. 
15154      We can't use SSE_REGPARM_MAX here since callee is unprototyped
15155      and should have the default ABI.  */
15157   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15158                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15159                     operands[0], const0_rtx,
15160                     GEN_INT ((TARGET_64BIT
15161                               ? (DEFAULT_ABI == SYSV_ABI
15162                                  ? X86_64_SSE_REGPARM_MAX
15163                                  : X64_SSE_REGPARM_MAX)
15164                               : X86_32_SSE_REGPARM_MAX)
15165                              - 1),
15166                     NULL, 0);
15168   for (i = 0; i < XVECLEN (operands[2], 0); i++)
15169     {
15170       rtx set = XVECEXP (operands[2], 0, i);
15171       emit_move_insn (SET_DEST (set), SET_SRC (set));
15172     }
15174   /* The optimizer does not know that the call sets the function value
15175      registers we stored in the result block.  We avoid problems by
15176      claiming that all hard registers are used and clobbered at this
15177      point.  */
15178   emit_insn (gen_blockage ());
15180   DONE;
15183 ;; Prologue and epilogue instructions
15185 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15186 ;; all of memory.  This blocks insns from being moved across this point.
15188 (define_insn "blockage"
15189   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15190   ""
15191   ""
15192   [(set_attr "length" "0")])
15194 ;; Do not schedule instructions accessing memory across this point.
15196 (define_expand "memory_blockage"
15197   [(set (match_dup 0)
15198         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15199   ""
15201   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
15202   MEM_VOLATILE_P (operands[0]) = 1;
15205 (define_insn "*memory_blockage"
15206   [(set (match_operand:BLK 0 "" "")
15207         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15208   ""
15209   ""
15210   [(set_attr "length" "0")])
15212 ;; As USE insns aren't meaningful after reload, this is used instead
15213 ;; to prevent deleting instructions setting registers for PIC code
15214 (define_insn "prologue_use"
15215   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15216   ""
15217   ""
15218   [(set_attr "length" "0")])
15220 ;; Insn emitted into the body of a function to return from a function.
15221 ;; This is only done if the function's epilogue is known to be simple.
15222 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15224 (define_expand "return"
15225   [(return)]
15226   "ix86_can_use_return_insn_p ()"
15228   if (crtl->args.pops_args)
15229     {
15230       rtx popc = GEN_INT (crtl->args.pops_args);
15231       emit_jump_insn (gen_return_pop_internal (popc));
15232       DONE;
15233     }
15236 (define_insn "return_internal"
15237   [(return)]
15238   "reload_completed"
15239   "ret"
15240   [(set_attr "length" "1")
15241    (set_attr "length_immediate" "0")
15242    (set_attr "modrm" "0")])
15244 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15245 ;; instruction Athlon and K8 have.
15247 (define_insn "return_internal_long"
15248   [(return)
15249    (unspec [(const_int 0)] UNSPEC_REP)]
15250   "reload_completed"
15251   "rep\;ret"
15252   [(set_attr "length" "1")
15253    (set_attr "length_immediate" "0")
15254    (set_attr "prefix_rep" "1")
15255    (set_attr "modrm" "0")])
15257 (define_insn "return_pop_internal"
15258   [(return)
15259    (use (match_operand:SI 0 "const_int_operand" ""))]
15260   "reload_completed"
15261   "ret\t%0"
15262   [(set_attr "length" "3")
15263    (set_attr "length_immediate" "2")
15264    (set_attr "modrm" "0")])
15266 (define_insn "return_indirect_internal"
15267   [(return)
15268    (use (match_operand:SI 0 "register_operand" "r"))]
15269   "reload_completed"
15270   "jmp\t%A0"
15271   [(set_attr "type" "ibr")
15272    (set_attr "length_immediate" "0")])
15274 (define_insn "nop"
15275   [(const_int 0)]
15276   ""
15277   "nop"
15278   [(set_attr "length" "1")
15279    (set_attr "length_immediate" "0")
15280    (set_attr "modrm" "0")])
15282 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
15283 ;; branch prediction penalty for the third jump in a 16-byte
15284 ;; block on K8.
15286 (define_insn "align"
15287   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15288   ""
15290 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15291   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15292 #else
15293   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15294      The align insn is used to avoid 3 jump instructions in the row to improve
15295      branch prediction and the benefits hardly outweigh the cost of extra 8
15296      nops on the average inserted by full alignment pseudo operation.  */
15297 #endif
15298   return "";
15300   [(set_attr "length" "16")])
15302 (define_expand "prologue"
15303   [(const_int 0)]
15304   ""
15305   "ix86_expand_prologue (); DONE;")
15307 (define_insn "set_got"
15308   [(set (match_operand:SI 0 "register_operand" "=r")
15309         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15310    (clobber (reg:CC FLAGS_REG))]
15311   "!TARGET_64BIT"
15312   { return output_set_got (operands[0], NULL_RTX); }
15313   [(set_attr "type" "multi")
15314    (set_attr "length" "12")])
15316 (define_insn "set_got_labelled"
15317   [(set (match_operand:SI 0 "register_operand" "=r")
15318         (unspec:SI [(label_ref (match_operand 1 "" ""))]
15319          UNSPEC_SET_GOT))
15320    (clobber (reg:CC FLAGS_REG))]
15321   "!TARGET_64BIT"
15322   { return output_set_got (operands[0], operands[1]); }
15323   [(set_attr "type" "multi")
15324    (set_attr "length" "12")])
15326 (define_insn "set_got_rex64"
15327   [(set (match_operand:DI 0 "register_operand" "=r")
15328         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15329   "TARGET_64BIT"
15330   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15331   [(set_attr "type" "lea")
15332    (set_attr "length" "6")])
15334 (define_insn "set_rip_rex64"
15335   [(set (match_operand:DI 0 "register_operand" "=r")
15336         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
15337   "TARGET_64BIT"
15338   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15339   [(set_attr "type" "lea")
15340    (set_attr "length" "6")])
15342 (define_insn "set_got_offset_rex64"
15343   [(set (match_operand:DI 0 "register_operand" "=r")
15344         (unspec:DI
15345           [(label_ref (match_operand 1 "" ""))]
15346           UNSPEC_SET_GOT_OFFSET))]
15347   "TARGET_64BIT"
15348   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15349   [(set_attr "type" "imov")
15350    (set_attr "length" "11")])
15352 (define_expand "epilogue"
15353   [(const_int 0)]
15354   ""
15355   "ix86_expand_epilogue (1); DONE;")
15357 (define_expand "sibcall_epilogue"
15358   [(const_int 0)]
15359   ""
15360   "ix86_expand_epilogue (0); DONE;")
15362 (define_expand "eh_return"
15363   [(use (match_operand 0 "register_operand" ""))]
15364   ""
15366   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15368   /* Tricky bit: we write the address of the handler to which we will
15369      be returning into someone else's stack frame, one word below the
15370      stack address we wish to restore.  */
15371   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15372   tmp = plus_constant (tmp, -UNITS_PER_WORD);
15373   tmp = gen_rtx_MEM (Pmode, tmp);
15374   emit_move_insn (tmp, ra);
15376   if (Pmode == SImode)
15377     emit_jump_insn (gen_eh_return_si (sa));
15378   else
15379     emit_jump_insn (gen_eh_return_di (sa));
15380   emit_barrier ();
15381   DONE;
15384 (define_insn_and_split "eh_return_<mode>"
15385   [(set (pc)
15386         (unspec [(match_operand:P 0 "register_operand" "c")]
15387                  UNSPEC_EH_RETURN))]
15388   ""
15389   "#"
15390   "reload_completed"
15391   [(const_int 0)]
15392   "ix86_expand_epilogue (2); DONE;")
15394 (define_insn "leave"
15395   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15396    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15397    (clobber (mem:BLK (scratch)))]
15398   "!TARGET_64BIT"
15399   "leave"
15400   [(set_attr "type" "leave")])
15402 (define_insn "leave_rex64"
15403   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15404    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15405    (clobber (mem:BLK (scratch)))]
15406   "TARGET_64BIT"
15407   "leave"
15408   [(set_attr "type" "leave")])
15410 (define_expand "ffssi2"
15411   [(parallel
15412      [(set (match_operand:SI 0 "register_operand" "")
15413            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15414       (clobber (match_scratch:SI 2 ""))
15415       (clobber (reg:CC FLAGS_REG))])]
15416   ""
15418   if (TARGET_CMOVE)
15419     {
15420       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15421       DONE;
15422     }
15425 (define_expand "ffs_cmove"
15426   [(set (match_dup 2) (const_int -1))
15427    (parallel [(set (reg:CCZ FLAGS_REG)
15428                    (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15429                                 (const_int 0)))
15430               (set (match_operand:SI 0 "register_operand" "")
15431                    (ctz:SI (match_dup 1)))])
15432    (set (match_dup 0) (if_then_else:SI
15433                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15434                         (match_dup 2)
15435                         (match_dup 0)))
15436    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15437               (clobber (reg:CC FLAGS_REG))])]
15438   "TARGET_CMOVE"
15439   "operands[2] = gen_reg_rtx (SImode);")
15441 (define_insn_and_split "*ffs_no_cmove"
15442   [(set (match_operand:SI 0 "register_operand" "=r")
15443         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15444    (clobber (match_scratch:SI 2 "=&q"))
15445    (clobber (reg:CC FLAGS_REG))]
15446   "!TARGET_CMOVE"
15447   "#"
15448   "&& reload_completed"
15449   [(parallel [(set (reg:CCZ FLAGS_REG)
15450                    (compare:CCZ (match_dup 1) (const_int 0)))
15451               (set (match_dup 0) (ctz:SI (match_dup 1)))])
15452    (set (strict_low_part (match_dup 3))
15453         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15454    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15455               (clobber (reg:CC FLAGS_REG))])
15456    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15457               (clobber (reg:CC FLAGS_REG))])
15458    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15459               (clobber (reg:CC FLAGS_REG))])]
15461   operands[3] = gen_lowpart (QImode, operands[2]);
15462   ix86_expand_clear (operands[2]);
15465 (define_insn "*ffssi_1"
15466   [(set (reg:CCZ FLAGS_REG)
15467         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15468                      (const_int 0)))
15469    (set (match_operand:SI 0 "register_operand" "=r")
15470         (ctz:SI (match_dup 1)))]
15471   ""
15472   "bsf{l}\t{%1, %0|%0, %1}"
15473   [(set_attr "prefix_0f" "1")])
15475 (define_expand "ffsdi2"
15476   [(set (match_dup 2) (const_int -1))
15477    (parallel [(set (reg:CCZ FLAGS_REG)
15478                    (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15479                                 (const_int 0)))
15480               (set (match_operand:DI 0 "register_operand" "")
15481                    (ctz:DI (match_dup 1)))])
15482    (set (match_dup 0) (if_then_else:DI
15483                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15484                         (match_dup 2)
15485                         (match_dup 0)))
15486    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15487               (clobber (reg:CC FLAGS_REG))])]
15488   "TARGET_64BIT"
15489   "operands[2] = gen_reg_rtx (DImode);")
15491 (define_insn "*ffsdi_1"
15492   [(set (reg:CCZ FLAGS_REG)
15493         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15494                      (const_int 0)))
15495    (set (match_operand:DI 0 "register_operand" "=r")
15496         (ctz:DI (match_dup 1)))]
15497   "TARGET_64BIT"
15498   "bsf{q}\t{%1, %0|%0, %1}"
15499   [(set_attr "prefix_0f" "1")])
15501 (define_insn "ctzsi2"
15502   [(set (match_operand:SI 0 "register_operand" "=r")
15503         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15504    (clobber (reg:CC FLAGS_REG))]
15505   ""
15506   "bsf{l}\t{%1, %0|%0, %1}"
15507   [(set_attr "prefix_0f" "1")])
15509 (define_insn "ctzdi2"
15510   [(set (match_operand:DI 0 "register_operand" "=r")
15511         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15512    (clobber (reg:CC FLAGS_REG))]
15513   "TARGET_64BIT"
15514   "bsf{q}\t{%1, %0|%0, %1}"
15515   [(set_attr "prefix_0f" "1")])
15517 (define_expand "clzsi2"
15518   [(parallel
15519      [(set (match_operand:SI 0 "register_operand" "")
15520            (minus:SI (const_int 31)
15521                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15522       (clobber (reg:CC FLAGS_REG))])
15523    (parallel
15524      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15525       (clobber (reg:CC FLAGS_REG))])]
15526   ""
15528   if (TARGET_ABM)
15529     {
15530       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15531       DONE;
15532     }
15535 (define_insn "clzsi2_abm"
15536   [(set (match_operand:SI 0 "register_operand" "=r")
15537         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15538    (clobber (reg:CC FLAGS_REG))]
15539   "TARGET_ABM"
15540   "lzcnt{l}\t{%1, %0|%0, %1}"
15541   [(set_attr "prefix_rep" "1")
15542    (set_attr "type" "bitmanip")
15543    (set_attr "mode" "SI")])
15545 (define_insn "*bsr"
15546   [(set (match_operand:SI 0 "register_operand" "=r")
15547         (minus:SI (const_int 31)
15548                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15549    (clobber (reg:CC FLAGS_REG))]
15550   ""
15551   "bsr{l}\t{%1, %0|%0, %1}"
15552   [(set_attr "prefix_0f" "1")
15553    (set_attr "mode" "SI")])
15555 (define_insn "popcount<mode>2"
15556   [(set (match_operand:SWI248 0 "register_operand" "=r")
15557         (popcount:SWI248
15558           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
15559    (clobber (reg:CC FLAGS_REG))]
15560   "TARGET_POPCNT"
15562 #if TARGET_MACHO
15563   return "popcnt\t{%1, %0|%0, %1}";
15564 #else
15565   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15566 #endif
15568   [(set_attr "prefix_rep" "1")
15569    (set_attr "type" "bitmanip")
15570    (set_attr "mode" "<MODE>")])
15572 (define_insn "*popcount<mode>2_cmp"
15573   [(set (reg FLAGS_REG)
15574         (compare
15575           (popcount:SWI248
15576             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
15577           (const_int 0)))
15578    (set (match_operand:SWI248 0 "register_operand" "=r")
15579         (popcount:SWI248 (match_dup 1)))]
15580   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15582 #if TARGET_MACHO
15583   return "popcnt\t{%1, %0|%0, %1}";
15584 #else
15585   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15586 #endif
15588   [(set_attr "prefix_rep" "1")
15589    (set_attr "type" "bitmanip")
15590    (set_attr "mode" "<MODE>")])
15592 (define_insn "*popcountsi2_cmp_zext"
15593   [(set (reg FLAGS_REG)
15594         (compare
15595           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15596           (const_int 0)))
15597    (set (match_operand:DI 0 "register_operand" "=r")
15598         (zero_extend:DI(popcount:SI (match_dup 1))))]
15599   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15601 #if TARGET_MACHO
15602   return "popcnt\t{%1, %0|%0, %1}";
15603 #else
15604   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15605 #endif
15607   [(set_attr "prefix_rep" "1")
15608    (set_attr "type" "bitmanip")
15609    (set_attr "mode" "SI")])
15611 (define_expand "bswapsi2"
15612   [(set (match_operand:SI 0 "register_operand" "")
15613         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15614   ""
15616   if (!TARGET_BSWAP)
15617     {
15618       rtx x = operands[0];
15620       emit_move_insn (x, operands[1]);
15621       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15622       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15623       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15624       DONE;
15625     }
15628 (define_insn "*bswapsi_1"
15629   [(set (match_operand:SI 0 "register_operand" "=r")
15630         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15631   "TARGET_BSWAP"
15632   "bswap\t%0"
15633   [(set_attr "prefix_0f" "1")
15634    (set_attr "length" "2")])
15636 (define_insn "*bswaphi_lowpart_1"
15637   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15638         (bswap:HI (match_dup 0)))
15639    (clobber (reg:CC FLAGS_REG))]
15640   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
15641   "@
15642     xchg{b}\t{%h0, %b0|%b0, %h0}
15643     rol{w}\t{$8, %0|%0, 8}"
15644   [(set_attr "length" "2,4")
15645    (set_attr "mode" "QI,HI")])
15647 (define_insn "bswaphi_lowpart"
15648   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15649         (bswap:HI (match_dup 0)))
15650    (clobber (reg:CC FLAGS_REG))]
15651   ""
15652   "rol{w}\t{$8, %0|%0, 8}"
15653   [(set_attr "length" "4")
15654    (set_attr "mode" "HI")])
15656 (define_insn "bswapdi2"
15657   [(set (match_operand:DI 0 "register_operand" "=r")
15658         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15659   "TARGET_64BIT"
15660   "bswap\t%0"
15661   [(set_attr "prefix_0f" "1")
15662    (set_attr "length" "3")])
15664 (define_expand "clzdi2"
15665   [(parallel
15666      [(set (match_operand:DI 0 "register_operand" "")
15667            (minus:DI (const_int 63)
15668                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15669       (clobber (reg:CC FLAGS_REG))])
15670    (parallel
15671      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15672       (clobber (reg:CC FLAGS_REG))])]
15673   "TARGET_64BIT"
15675   if (TARGET_ABM)
15676     {
15677       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15678       DONE;
15679     }
15682 (define_insn "clzdi2_abm"
15683   [(set (match_operand:DI 0 "register_operand" "=r")
15684         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15685    (clobber (reg:CC FLAGS_REG))]
15686   "TARGET_64BIT && TARGET_ABM"
15687   "lzcnt{q}\t{%1, %0|%0, %1}"
15688   [(set_attr "prefix_rep" "1")
15689    (set_attr "type" "bitmanip")
15690    (set_attr "mode" "DI")])
15692 (define_insn "*bsr_rex64"
15693   [(set (match_operand:DI 0 "register_operand" "=r")
15694         (minus:DI (const_int 63)
15695                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15696    (clobber (reg:CC FLAGS_REG))]
15697   "TARGET_64BIT"
15698   "bsr{q}\t{%1, %0|%0, %1}"
15699   [(set_attr "prefix_0f" "1")
15700    (set_attr "mode" "DI")])
15702 (define_expand "clzhi2"
15703   [(parallel
15704      [(set (match_operand:HI 0 "register_operand" "")
15705            (minus:HI (const_int 15)
15706                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15707       (clobber (reg:CC FLAGS_REG))])
15708    (parallel
15709      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15710       (clobber (reg:CC FLAGS_REG))])]
15711   ""
15713   if (TARGET_ABM)
15714     {
15715       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15716       DONE;
15717     }
15720 (define_insn "clzhi2_abm"
15721   [(set (match_operand:HI 0 "register_operand" "=r")
15722         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15723    (clobber (reg:CC FLAGS_REG))]
15724   "TARGET_ABM"
15725   "lzcnt{w}\t{%1, %0|%0, %1}"
15726   [(set_attr "prefix_rep" "1")
15727    (set_attr "type" "bitmanip")
15728    (set_attr "mode" "HI")])
15730 (define_insn "*bsrhi"
15731   [(set (match_operand:HI 0 "register_operand" "=r")
15732         (minus:HI (const_int 15)
15733                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15734    (clobber (reg:CC FLAGS_REG))]
15735   ""
15736   "bsr{w}\t{%1, %0|%0, %1}"
15737   [(set_attr "prefix_0f" "1")
15738    (set_attr "mode" "HI")])
15740 (define_expand "paritydi2"
15741   [(set (match_operand:DI 0 "register_operand" "")
15742         (parity:DI (match_operand:DI 1 "register_operand" "")))]
15743   "! TARGET_POPCNT"
15745   rtx scratch = gen_reg_rtx (QImode);
15746   rtx cond;
15748   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15749                                 NULL_RTX, operands[1]));
15751   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15752                          gen_rtx_REG (CCmode, FLAGS_REG),
15753                          const0_rtx);
15754   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15756   if (TARGET_64BIT)
15757     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15758   else
15759     {
15760       rtx tmp = gen_reg_rtx (SImode);
15762       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15763       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15764     }
15765   DONE;
15768 (define_insn_and_split "paritydi2_cmp"
15769   [(set (reg:CC FLAGS_REG)
15770         (parity:CC (match_operand:DI 3 "register_operand" "0")))
15771    (clobber (match_scratch:DI 0 "=r"))
15772    (clobber (match_scratch:SI 1 "=&r"))
15773    (clobber (match_scratch:HI 2 "=Q"))]
15774   "! TARGET_POPCNT"
15775   "#"
15776   "&& reload_completed"
15777   [(parallel
15778      [(set (match_dup 1)
15779            (xor:SI (match_dup 1) (match_dup 4)))
15780       (clobber (reg:CC FLAGS_REG))])
15781    (parallel
15782      [(set (reg:CC FLAGS_REG)
15783            (parity:CC (match_dup 1)))
15784       (clobber (match_dup 1))
15785       (clobber (match_dup 2))])]
15787   operands[4] = gen_lowpart (SImode, operands[3]);
15789   if (TARGET_64BIT)
15790     {
15791       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15792       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15793     }
15794   else
15795     operands[1] = gen_highpart (SImode, operands[3]);
15798 (define_expand "paritysi2"
15799   [(set (match_operand:SI 0 "register_operand" "")
15800         (parity:SI (match_operand:SI 1 "register_operand" "")))]
15801   "! TARGET_POPCNT"
15803   rtx scratch = gen_reg_rtx (QImode);
15804   rtx cond;
15806   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15808   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15809                          gen_rtx_REG (CCmode, FLAGS_REG),
15810                          const0_rtx);
15811   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15813   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15814   DONE;
15817 (define_insn_and_split "paritysi2_cmp"
15818   [(set (reg:CC FLAGS_REG)
15819         (parity:CC (match_operand:SI 2 "register_operand" "0")))
15820    (clobber (match_scratch:SI 0 "=r"))
15821    (clobber (match_scratch:HI 1 "=&Q"))]
15822   "! TARGET_POPCNT"
15823   "#"
15824   "&& reload_completed"
15825   [(parallel
15826      [(set (match_dup 1)
15827            (xor:HI (match_dup 1) (match_dup 3)))
15828       (clobber (reg:CC FLAGS_REG))])
15829    (parallel
15830      [(set (reg:CC FLAGS_REG)
15831            (parity:CC (match_dup 1)))
15832       (clobber (match_dup 1))])]
15834   operands[3] = gen_lowpart (HImode, operands[2]);
15836   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15837   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15840 (define_insn "*parityhi2_cmp"
15841   [(set (reg:CC FLAGS_REG)
15842         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15843    (clobber (match_scratch:HI 0 "=Q"))]
15844   "! TARGET_POPCNT"
15845   "xor{b}\t{%h0, %b0|%b0, %h0}"
15846   [(set_attr "length" "2")
15847    (set_attr "mode" "HI")])
15849 (define_insn "*parityqi2_cmp"
15850   [(set (reg:CC FLAGS_REG)
15851         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15852   "! TARGET_POPCNT"
15853   "test{b}\t%0, %0"
15854   [(set_attr "length" "2")
15855    (set_attr "mode" "QI")])
15857 ;; Thread-local storage patterns for ELF.
15859 ;; Note that these code sequences must appear exactly as shown
15860 ;; in order to allow linker relaxation.
15862 (define_insn "*tls_global_dynamic_32_gnu"
15863   [(set (match_operand:SI 0 "register_operand" "=a")
15864         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15865                     (match_operand:SI 2 "tls_symbolic_operand" "")
15866                     (match_operand:SI 3 "call_insn_operand" "")]
15867                     UNSPEC_TLS_GD))
15868    (clobber (match_scratch:SI 4 "=d"))
15869    (clobber (match_scratch:SI 5 "=c"))
15870    (clobber (reg:CC FLAGS_REG))]
15871   "!TARGET_64BIT && TARGET_GNU_TLS"
15872   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15873   [(set_attr "type" "multi")
15874    (set_attr "length" "12")])
15876 (define_insn "*tls_global_dynamic_32_sun"
15877   [(set (match_operand:SI 0 "register_operand" "=a")
15878         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15879                     (match_operand:SI 2 "tls_symbolic_operand" "")
15880                     (match_operand:SI 3 "call_insn_operand" "")]
15881                     UNSPEC_TLS_GD))
15882    (clobber (match_scratch:SI 4 "=d"))
15883    (clobber (match_scratch:SI 5 "=c"))
15884    (clobber (reg:CC FLAGS_REG))]
15885   "!TARGET_64BIT && TARGET_SUN_TLS"
15886   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15887         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15888   [(set_attr "type" "multi")
15889    (set_attr "length" "14")])
15891 (define_expand "tls_global_dynamic_32"
15892   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15893                    (unspec:SI
15894                     [(match_dup 2)
15895                      (match_operand:SI 1 "tls_symbolic_operand" "")
15896                      (match_dup 3)]
15897                     UNSPEC_TLS_GD))
15898               (clobber (match_scratch:SI 4 ""))
15899               (clobber (match_scratch:SI 5 ""))
15900               (clobber (reg:CC FLAGS_REG))])]
15901   ""
15903   if (flag_pic)
15904     operands[2] = pic_offset_table_rtx;
15905   else
15906     {
15907       operands[2] = gen_reg_rtx (Pmode);
15908       emit_insn (gen_set_got (operands[2]));
15909     }
15910   if (TARGET_GNU2_TLS)
15911     {
15912        emit_insn (gen_tls_dynamic_gnu2_32
15913                   (operands[0], operands[1], operands[2]));
15914        DONE;
15915     }
15916   operands[3] = ix86_tls_get_addr ();
15919 (define_insn "*tls_global_dynamic_64"
15920   [(set (match_operand:DI 0 "register_operand" "=a")
15921         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15922                  (match_operand:DI 3 "" "")))
15923    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15924               UNSPEC_TLS_GD)]
15925   "TARGET_64BIT"
15926   { return ".byte\t0x66\n\tlea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; }
15927   [(set_attr "type" "multi")
15928    (set_attr "length" "16")])
15930 (define_expand "tls_global_dynamic_64"
15931   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15932                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15933               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15934                          UNSPEC_TLS_GD)])]
15935   ""
15937   if (TARGET_GNU2_TLS)
15938     {
15939        emit_insn (gen_tls_dynamic_gnu2_64
15940                   (operands[0], operands[1]));
15941        DONE;
15942     }
15943   operands[2] = ix86_tls_get_addr ();
15946 (define_insn "*tls_local_dynamic_base_32_gnu"
15947   [(set (match_operand:SI 0 "register_operand" "=a")
15948         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15949                     (match_operand:SI 2 "call_insn_operand" "")]
15950                    UNSPEC_TLS_LD_BASE))
15951    (clobber (match_scratch:SI 3 "=d"))
15952    (clobber (match_scratch:SI 4 "=c"))
15953    (clobber (reg:CC FLAGS_REG))]
15954   "!TARGET_64BIT && TARGET_GNU_TLS"
15955   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15956   [(set_attr "type" "multi")
15957    (set_attr "length" "11")])
15959 (define_insn "*tls_local_dynamic_base_32_sun"
15960   [(set (match_operand:SI 0 "register_operand" "=a")
15961         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15962                     (match_operand:SI 2 "call_insn_operand" "")]
15963                    UNSPEC_TLS_LD_BASE))
15964    (clobber (match_scratch:SI 3 "=d"))
15965    (clobber (match_scratch:SI 4 "=c"))
15966    (clobber (reg:CC FLAGS_REG))]
15967   "!TARGET_64BIT && TARGET_SUN_TLS"
15968   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15969         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15970   [(set_attr "type" "multi")
15971    (set_attr "length" "13")])
15973 (define_expand "tls_local_dynamic_base_32"
15974   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15975                    (unspec:SI [(match_dup 1) (match_dup 2)]
15976                               UNSPEC_TLS_LD_BASE))
15977               (clobber (match_scratch:SI 3 ""))
15978               (clobber (match_scratch:SI 4 ""))
15979               (clobber (reg:CC FLAGS_REG))])]
15980   ""
15982   if (flag_pic)
15983     operands[1] = pic_offset_table_rtx;
15984   else
15985     {
15986       operands[1] = gen_reg_rtx (Pmode);
15987       emit_insn (gen_set_got (operands[1]));
15988     }
15989   if (TARGET_GNU2_TLS)
15990     {
15991        emit_insn (gen_tls_dynamic_gnu2_32
15992                   (operands[0], ix86_tls_module_base (), operands[1]));
15993        DONE;
15994     }
15995   operands[2] = ix86_tls_get_addr ();
15998 (define_insn "*tls_local_dynamic_base_64"
15999   [(set (match_operand:DI 0 "register_operand" "=a")
16000         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
16001                  (match_operand:DI 2 "" "")))
16002    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
16003   "TARGET_64BIT"
16004   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
16005   [(set_attr "type" "multi")
16006    (set_attr "length" "12")])
16008 (define_expand "tls_local_dynamic_base_64"
16009   [(parallel [(set (match_operand:DI 0 "register_operand" "")
16010                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
16011               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
16012   ""
16014   if (TARGET_GNU2_TLS)
16015     {
16016        emit_insn (gen_tls_dynamic_gnu2_64
16017                   (operands[0], ix86_tls_module_base ()));
16018        DONE;
16019     }
16020   operands[1] = ix86_tls_get_addr ();
16023 ;; Local dynamic of a single variable is a lose.  Show combine how
16024 ;; to convert that back to global dynamic.
16026 (define_insn_and_split "*tls_local_dynamic_32_once"
16027   [(set (match_operand:SI 0 "register_operand" "=a")
16028         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16029                              (match_operand:SI 2 "call_insn_operand" "")]
16030                             UNSPEC_TLS_LD_BASE)
16031                  (const:SI (unspec:SI
16032                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
16033                             UNSPEC_DTPOFF))))
16034    (clobber (match_scratch:SI 4 "=d"))
16035    (clobber (match_scratch:SI 5 "=c"))
16036    (clobber (reg:CC FLAGS_REG))]
16037   ""
16038   "#"
16039   ""
16040   [(parallel [(set (match_dup 0)
16041                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
16042                               UNSPEC_TLS_GD))
16043               (clobber (match_dup 4))
16044               (clobber (match_dup 5))
16045               (clobber (reg:CC FLAGS_REG))])]
16046   "")
16048 ;; Load and add the thread base pointer from %gs:0.
16050 (define_insn "*load_tp_si"
16051   [(set (match_operand:SI 0 "register_operand" "=r")
16052         (unspec:SI [(const_int 0)] UNSPEC_TP))]
16053   "!TARGET_64BIT"
16054   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16055   [(set_attr "type" "imov")
16056    (set_attr "modrm" "0")
16057    (set_attr "length" "7")
16058    (set_attr "memory" "load")
16059    (set_attr "imm_disp" "false")])
16061 (define_insn "*add_tp_si"
16062   [(set (match_operand:SI 0 "register_operand" "=r")
16063         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16064                  (match_operand:SI 1 "register_operand" "0")))
16065    (clobber (reg:CC FLAGS_REG))]
16066   "!TARGET_64BIT"
16067   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16068   [(set_attr "type" "alu")
16069    (set_attr "modrm" "0")
16070    (set_attr "length" "7")
16071    (set_attr "memory" "load")
16072    (set_attr "imm_disp" "false")])
16074 (define_insn "*load_tp_di"
16075   [(set (match_operand:DI 0 "register_operand" "=r")
16076         (unspec:DI [(const_int 0)] UNSPEC_TP))]
16077   "TARGET_64BIT"
16078   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16079   [(set_attr "type" "imov")
16080    (set_attr "modrm" "0")
16081    (set_attr "length" "7")
16082    (set_attr "memory" "load")
16083    (set_attr "imm_disp" "false")])
16085 (define_insn "*add_tp_di"
16086   [(set (match_operand:DI 0 "register_operand" "=r")
16087         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16088                  (match_operand:DI 1 "register_operand" "0")))
16089    (clobber (reg:CC FLAGS_REG))]
16090   "TARGET_64BIT"
16091   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16092   [(set_attr "type" "alu")
16093    (set_attr "modrm" "0")
16094    (set_attr "length" "7")
16095    (set_attr "memory" "load")
16096    (set_attr "imm_disp" "false")])
16098 ;; GNU2 TLS patterns can be split.
16100 (define_expand "tls_dynamic_gnu2_32"
16101   [(set (match_dup 3)
16102         (plus:SI (match_operand:SI 2 "register_operand" "")
16103                  (const:SI
16104                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16105                              UNSPEC_TLSDESC))))
16106    (parallel
16107     [(set (match_operand:SI 0 "register_operand" "")
16108           (unspec:SI [(match_dup 1) (match_dup 3)
16109                       (match_dup 2) (reg:SI SP_REG)]
16110                       UNSPEC_TLSDESC))
16111      (clobber (reg:CC FLAGS_REG))])]
16112   "!TARGET_64BIT && TARGET_GNU2_TLS"
16114   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16115   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16118 (define_insn "*tls_dynamic_lea_32"
16119   [(set (match_operand:SI 0 "register_operand" "=r")
16120         (plus:SI (match_operand:SI 1 "register_operand" "b")
16121                  (const:SI
16122                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16123                               UNSPEC_TLSDESC))))]
16124   "!TARGET_64BIT && TARGET_GNU2_TLS"
16125   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16126   [(set_attr "type" "lea")
16127    (set_attr "mode" "SI")
16128    (set_attr "length" "6")
16129    (set_attr "length_address" "4")])
16131 (define_insn "*tls_dynamic_call_32"
16132   [(set (match_operand:SI 0 "register_operand" "=a")
16133         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16134                     (match_operand:SI 2 "register_operand" "0")
16135                     ;; we have to make sure %ebx still points to the GOT
16136                     (match_operand:SI 3 "register_operand" "b")
16137                     (reg:SI SP_REG)]
16138                    UNSPEC_TLSDESC))
16139    (clobber (reg:CC FLAGS_REG))]
16140   "!TARGET_64BIT && TARGET_GNU2_TLS"
16141   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16142   [(set_attr "type" "call")
16143    (set_attr "length" "2")
16144    (set_attr "length_address" "0")])
16146 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16147   [(set (match_operand:SI 0 "register_operand" "=&a")
16148         (plus:SI
16149          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16150                      (match_operand:SI 4 "" "")
16151                      (match_operand:SI 2 "register_operand" "b")
16152                      (reg:SI SP_REG)]
16153                     UNSPEC_TLSDESC)
16154          (const:SI (unspec:SI
16155                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
16156                     UNSPEC_DTPOFF))))
16157    (clobber (reg:CC FLAGS_REG))]
16158   "!TARGET_64BIT && TARGET_GNU2_TLS"
16159   "#"
16160   ""
16161   [(set (match_dup 0) (match_dup 5))]
16163   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16164   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16167 (define_expand "tls_dynamic_gnu2_64"
16168   [(set (match_dup 2)
16169         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16170                    UNSPEC_TLSDESC))
16171    (parallel
16172     [(set (match_operand:DI 0 "register_operand" "")
16173           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16174                      UNSPEC_TLSDESC))
16175      (clobber (reg:CC FLAGS_REG))])]
16176   "TARGET_64BIT && TARGET_GNU2_TLS"
16178   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16179   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16182 (define_insn "*tls_dynamic_lea_64"
16183   [(set (match_operand:DI 0 "register_operand" "=r")
16184         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16185                    UNSPEC_TLSDESC))]
16186   "TARGET_64BIT && TARGET_GNU2_TLS"
16187   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16188   [(set_attr "type" "lea")
16189    (set_attr "mode" "DI")
16190    (set_attr "length" "7")
16191    (set_attr "length_address" "4")])
16193 (define_insn "*tls_dynamic_call_64"
16194   [(set (match_operand:DI 0 "register_operand" "=a")
16195         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16196                     (match_operand:DI 2 "register_operand" "0")
16197                     (reg:DI SP_REG)]
16198                    UNSPEC_TLSDESC))
16199    (clobber (reg:CC FLAGS_REG))]
16200   "TARGET_64BIT && TARGET_GNU2_TLS"
16201   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16202   [(set_attr "type" "call")
16203    (set_attr "length" "2")
16204    (set_attr "length_address" "0")])
16206 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16207   [(set (match_operand:DI 0 "register_operand" "=&a")
16208         (plus:DI
16209          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16210                      (match_operand:DI 3 "" "")
16211                      (reg:DI SP_REG)]
16212                     UNSPEC_TLSDESC)
16213          (const:DI (unspec:DI
16214                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
16215                     UNSPEC_DTPOFF))))
16216    (clobber (reg:CC FLAGS_REG))]
16217   "TARGET_64BIT && TARGET_GNU2_TLS"
16218   "#"
16219   ""
16220   [(set (match_dup 0) (match_dup 4))]
16222   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16223   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16228 ;; These patterns match the binary 387 instructions for addM3, subM3,
16229 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
16230 ;; SFmode.  The first is the normal insn, the second the same insn but
16231 ;; with one operand a conversion, and the third the same insn but with
16232 ;; the other operand a conversion.  The conversion may be SFmode or
16233 ;; SImode if the target mode DFmode, but only SImode if the target mode
16234 ;; is SFmode.
16236 ;; Gcc is slightly more smart about handling normal two address instructions
16237 ;; so use special patterns for add and mull.
16239 (define_insn "*fop_<mode>_comm_mixed_avx"
16240   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16241         (match_operator:MODEF 3 "binary_fp_operator"
16242           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16243            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16244   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16245    && COMMUTATIVE_ARITH_P (operands[3])
16246    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16247   "* return output_387_binary_op (insn, operands);"
16248   [(set (attr "type")
16249         (if_then_else (eq_attr "alternative" "1")
16250            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16251               (const_string "ssemul")
16252               (const_string "sseadd"))
16253            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16254               (const_string "fmul")
16255               (const_string "fop"))))
16256    (set_attr "prefix" "orig,maybe_vex")
16257    (set_attr "mode" "<MODE>")])
16259 (define_insn "*fop_<mode>_comm_mixed"
16260   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16261         (match_operator:MODEF 3 "binary_fp_operator"
16262           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16263            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16264   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16265    && COMMUTATIVE_ARITH_P (operands[3])
16266    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16267   "* return output_387_binary_op (insn, operands);"
16268   [(set (attr "type")
16269         (if_then_else (eq_attr "alternative" "1")
16270            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16271               (const_string "ssemul")
16272               (const_string "sseadd"))
16273            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16274               (const_string "fmul")
16275               (const_string "fop"))))
16276    (set_attr "mode" "<MODE>")])
16278 (define_insn "*fop_<mode>_comm_avx"
16279   [(set (match_operand:MODEF 0 "register_operand" "=x")
16280         (match_operator:MODEF 3 "binary_fp_operator"
16281           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16282            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16283   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16284    && COMMUTATIVE_ARITH_P (operands[3])
16285    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16286   "* return output_387_binary_op (insn, operands);"
16287   [(set (attr "type")
16288         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16289            (const_string "ssemul")
16290            (const_string "sseadd")))
16291    (set_attr "prefix" "vex")
16292    (set_attr "mode" "<MODE>")])
16294 (define_insn "*fop_<mode>_comm_sse"
16295   [(set (match_operand:MODEF 0 "register_operand" "=x")
16296         (match_operator:MODEF 3 "binary_fp_operator"
16297           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16298            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16299   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16300    && COMMUTATIVE_ARITH_P (operands[3])
16301    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16302   "* return output_387_binary_op (insn, operands);"
16303   [(set (attr "type")
16304         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16305            (const_string "ssemul")
16306            (const_string "sseadd")))
16307    (set_attr "mode" "<MODE>")])
16309 (define_insn "*fop_<mode>_comm_i387"
16310   [(set (match_operand:MODEF 0 "register_operand" "=f")
16311         (match_operator:MODEF 3 "binary_fp_operator"
16312           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16313            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16314   "TARGET_80387
16315    && COMMUTATIVE_ARITH_P (operands[3])
16316    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16317   "* return output_387_binary_op (insn, operands);"
16318   [(set (attr "type")
16319         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16320            (const_string "fmul")
16321            (const_string "fop")))
16322    (set_attr "mode" "<MODE>")])
16324 (define_insn "*fop_<mode>_1_mixed_avx"
16325   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16326         (match_operator:MODEF 3 "binary_fp_operator"
16327           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16328            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16329   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16330    && !COMMUTATIVE_ARITH_P (operands[3])
16331    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16332   "* return output_387_binary_op (insn, operands);"
16333   [(set (attr "type")
16334         (cond [(and (eq_attr "alternative" "2")
16335                     (match_operand:MODEF 3 "mult_operator" ""))
16336                  (const_string "ssemul")
16337                (and (eq_attr "alternative" "2")
16338                     (match_operand:MODEF 3 "div_operator" ""))
16339                  (const_string "ssediv")
16340                (eq_attr "alternative" "2")
16341                  (const_string "sseadd")
16342                (match_operand:MODEF 3 "mult_operator" "")
16343                  (const_string "fmul")
16344                (match_operand:MODEF 3 "div_operator" "")
16345                  (const_string "fdiv")
16346               ]
16347               (const_string "fop")))
16348    (set_attr "prefix" "orig,orig,maybe_vex")
16349    (set_attr "mode" "<MODE>")])
16351 (define_insn "*fop_<mode>_1_mixed"
16352   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16353         (match_operator:MODEF 3 "binary_fp_operator"
16354           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16355            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16356   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16357    && !COMMUTATIVE_ARITH_P (operands[3])
16358    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16359   "* return output_387_binary_op (insn, operands);"
16360   [(set (attr "type")
16361         (cond [(and (eq_attr "alternative" "2")
16362                     (match_operand:MODEF 3 "mult_operator" ""))
16363                  (const_string "ssemul")
16364                (and (eq_attr "alternative" "2")
16365                     (match_operand:MODEF 3 "div_operator" ""))
16366                  (const_string "ssediv")
16367                (eq_attr "alternative" "2")
16368                  (const_string "sseadd")
16369                (match_operand:MODEF 3 "mult_operator" "")
16370                  (const_string "fmul")
16371                (match_operand:MODEF 3 "div_operator" "")
16372                  (const_string "fdiv")
16373               ]
16374               (const_string "fop")))
16375    (set_attr "mode" "<MODE>")])
16377 (define_insn "*rcpsf2_sse"
16378   [(set (match_operand:SF 0 "register_operand" "=x")
16379         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16380                    UNSPEC_RCP))]
16381   "TARGET_SSE_MATH"
16382   "%vrcpss\t{%1, %d0|%d0, %1}"
16383   [(set_attr "type" "sse")
16384    (set_attr "prefix" "maybe_vex")
16385    (set_attr "mode" "SF")])
16387 (define_insn "*fop_<mode>_1_avx"
16388   [(set (match_operand:MODEF 0 "register_operand" "=x")
16389         (match_operator:MODEF 3 "binary_fp_operator"
16390           [(match_operand:MODEF 1 "register_operand" "x")
16391            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16392   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16393    && !COMMUTATIVE_ARITH_P (operands[3])"
16394   "* return output_387_binary_op (insn, operands);"
16395   [(set (attr "type")
16396         (cond [(match_operand:MODEF 3 "mult_operator" "")
16397                  (const_string "ssemul")
16398                (match_operand:MODEF 3 "div_operator" "")
16399                  (const_string "ssediv")
16400               ]
16401               (const_string "sseadd")))
16402    (set_attr "prefix" "vex")
16403    (set_attr "mode" "<MODE>")])
16405 (define_insn "*fop_<mode>_1_sse"
16406   [(set (match_operand:MODEF 0 "register_operand" "=x")
16407         (match_operator:MODEF 3 "binary_fp_operator"
16408           [(match_operand:MODEF 1 "register_operand" "0")
16409            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16410   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16411    && !COMMUTATIVE_ARITH_P (operands[3])"
16412   "* return output_387_binary_op (insn, operands);"
16413   [(set (attr "type")
16414         (cond [(match_operand:MODEF 3 "mult_operator" "")
16415                  (const_string "ssemul")
16416                (match_operand:MODEF 3 "div_operator" "")
16417                  (const_string "ssediv")
16418               ]
16419               (const_string "sseadd")))
16420    (set_attr "mode" "<MODE>")])
16422 ;; This pattern is not fully shadowed by the pattern above.
16423 (define_insn "*fop_<mode>_1_i387"
16424   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16425         (match_operator:MODEF 3 "binary_fp_operator"
16426           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16427            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16428   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16429    && !COMMUTATIVE_ARITH_P (operands[3])
16430    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16431   "* return output_387_binary_op (insn, operands);"
16432   [(set (attr "type")
16433         (cond [(match_operand:MODEF 3 "mult_operator" "")
16434                  (const_string "fmul")
16435                (match_operand:MODEF 3 "div_operator" "")
16436                  (const_string "fdiv")
16437               ]
16438               (const_string "fop")))
16439    (set_attr "mode" "<MODE>")])
16441 ;; ??? Add SSE splitters for these!
16442 (define_insn "*fop_<MODEF:mode>_2_i387"
16443   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16444         (match_operator:MODEF 3 "binary_fp_operator"
16445           [(float:MODEF
16446              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16447            (match_operand:MODEF 2 "register_operand" "0,0")]))]
16448   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16449    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16450   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16451   [(set (attr "type")
16452         (cond [(match_operand:MODEF 3 "mult_operator" "")
16453                  (const_string "fmul")
16454                (match_operand:MODEF 3 "div_operator" "")
16455                  (const_string "fdiv")
16456               ]
16457               (const_string "fop")))
16458    (set_attr "fp_int_src" "true")
16459    (set_attr "mode" "<X87MODEI12:MODE>")])
16461 (define_insn "*fop_<MODEF:mode>_3_i387"
16462   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16463         (match_operator:MODEF 3 "binary_fp_operator"
16464           [(match_operand:MODEF 1 "register_operand" "0,0")
16465            (float:MODEF
16466              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16467   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16468    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16469   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16470   [(set (attr "type")
16471         (cond [(match_operand:MODEF 3 "mult_operator" "")
16472                  (const_string "fmul")
16473                (match_operand:MODEF 3 "div_operator" "")
16474                  (const_string "fdiv")
16475               ]
16476               (const_string "fop")))
16477    (set_attr "fp_int_src" "true")
16478    (set_attr "mode" "<MODE>")])
16480 (define_insn "*fop_df_4_i387"
16481   [(set (match_operand:DF 0 "register_operand" "=f,f")
16482         (match_operator:DF 3 "binary_fp_operator"
16483            [(float_extend:DF
16484              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16485             (match_operand:DF 2 "register_operand" "0,f")]))]
16486   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16487    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16488   "* return output_387_binary_op (insn, operands);"
16489   [(set (attr "type")
16490         (cond [(match_operand:DF 3 "mult_operator" "")
16491                  (const_string "fmul")
16492                (match_operand:DF 3 "div_operator" "")
16493                  (const_string "fdiv")
16494               ]
16495               (const_string "fop")))
16496    (set_attr "mode" "SF")])
16498 (define_insn "*fop_df_5_i387"
16499   [(set (match_operand:DF 0 "register_operand" "=f,f")
16500         (match_operator:DF 3 "binary_fp_operator"
16501           [(match_operand:DF 1 "register_operand" "0,f")
16502            (float_extend:DF
16503             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16504   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16505   "* return output_387_binary_op (insn, operands);"
16506   [(set (attr "type")
16507         (cond [(match_operand:DF 3 "mult_operator" "")
16508                  (const_string "fmul")
16509                (match_operand:DF 3 "div_operator" "")
16510                  (const_string "fdiv")
16511               ]
16512               (const_string "fop")))
16513    (set_attr "mode" "SF")])
16515 (define_insn "*fop_df_6_i387"
16516   [(set (match_operand:DF 0 "register_operand" "=f,f")
16517         (match_operator:DF 3 "binary_fp_operator"
16518           [(float_extend:DF
16519             (match_operand:SF 1 "register_operand" "0,f"))
16520            (float_extend:DF
16521             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16522   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16523   "* return output_387_binary_op (insn, operands);"
16524   [(set (attr "type")
16525         (cond [(match_operand:DF 3 "mult_operator" "")
16526                  (const_string "fmul")
16527                (match_operand:DF 3 "div_operator" "")
16528                  (const_string "fdiv")
16529               ]
16530               (const_string "fop")))
16531    (set_attr "mode" "SF")])
16533 (define_insn "*fop_xf_comm_i387"
16534   [(set (match_operand:XF 0 "register_operand" "=f")
16535         (match_operator:XF 3 "binary_fp_operator"
16536                         [(match_operand:XF 1 "register_operand" "%0")
16537                          (match_operand:XF 2 "register_operand" "f")]))]
16538   "TARGET_80387
16539    && COMMUTATIVE_ARITH_P (operands[3])"
16540   "* return output_387_binary_op (insn, operands);"
16541   [(set (attr "type")
16542         (if_then_else (match_operand:XF 3 "mult_operator" "")
16543            (const_string "fmul")
16544            (const_string "fop")))
16545    (set_attr "mode" "XF")])
16547 (define_insn "*fop_xf_1_i387"
16548   [(set (match_operand:XF 0 "register_operand" "=f,f")
16549         (match_operator:XF 3 "binary_fp_operator"
16550                         [(match_operand:XF 1 "register_operand" "0,f")
16551                          (match_operand:XF 2 "register_operand" "f,0")]))]
16552   "TARGET_80387
16553    && !COMMUTATIVE_ARITH_P (operands[3])"
16554   "* return output_387_binary_op (insn, operands);"
16555   [(set (attr "type")
16556         (cond [(match_operand:XF 3 "mult_operator" "")
16557                  (const_string "fmul")
16558                (match_operand:XF 3 "div_operator" "")
16559                  (const_string "fdiv")
16560               ]
16561               (const_string "fop")))
16562    (set_attr "mode" "XF")])
16564 (define_insn "*fop_xf_2_i387"
16565   [(set (match_operand:XF 0 "register_operand" "=f,f")
16566         (match_operator:XF 3 "binary_fp_operator"
16567           [(float:XF
16568              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16569            (match_operand:XF 2 "register_operand" "0,0")]))]
16570   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16571   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16572   [(set (attr "type")
16573         (cond [(match_operand:XF 3 "mult_operator" "")
16574                  (const_string "fmul")
16575                (match_operand:XF 3 "div_operator" "")
16576                  (const_string "fdiv")
16577               ]
16578               (const_string "fop")))
16579    (set_attr "fp_int_src" "true")
16580    (set_attr "mode" "<MODE>")])
16582 (define_insn "*fop_xf_3_i387"
16583   [(set (match_operand:XF 0 "register_operand" "=f,f")
16584         (match_operator:XF 3 "binary_fp_operator"
16585           [(match_operand:XF 1 "register_operand" "0,0")
16586            (float:XF
16587              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16588   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16589   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16590   [(set (attr "type")
16591         (cond [(match_operand:XF 3 "mult_operator" "")
16592                  (const_string "fmul")
16593                (match_operand:XF 3 "div_operator" "")
16594                  (const_string "fdiv")
16595               ]
16596               (const_string "fop")))
16597    (set_attr "fp_int_src" "true")
16598    (set_attr "mode" "<MODE>")])
16600 (define_insn "*fop_xf_4_i387"
16601   [(set (match_operand:XF 0 "register_operand" "=f,f")
16602         (match_operator:XF 3 "binary_fp_operator"
16603            [(float_extend:XF
16604               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16605             (match_operand:XF 2 "register_operand" "0,f")]))]
16606   "TARGET_80387"
16607   "* return output_387_binary_op (insn, operands);"
16608   [(set (attr "type")
16609         (cond [(match_operand:XF 3 "mult_operator" "")
16610                  (const_string "fmul")
16611                (match_operand:XF 3 "div_operator" "")
16612                  (const_string "fdiv")
16613               ]
16614               (const_string "fop")))
16615    (set_attr "mode" "<MODE>")])
16617 (define_insn "*fop_xf_5_i387"
16618   [(set (match_operand:XF 0 "register_operand" "=f,f")
16619         (match_operator:XF 3 "binary_fp_operator"
16620           [(match_operand:XF 1 "register_operand" "0,f")
16621            (float_extend:XF
16622              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16623   "TARGET_80387"
16624   "* return output_387_binary_op (insn, operands);"
16625   [(set (attr "type")
16626         (cond [(match_operand:XF 3 "mult_operator" "")
16627                  (const_string "fmul")
16628                (match_operand:XF 3 "div_operator" "")
16629                  (const_string "fdiv")
16630               ]
16631               (const_string "fop")))
16632    (set_attr "mode" "<MODE>")])
16634 (define_insn "*fop_xf_6_i387"
16635   [(set (match_operand:XF 0 "register_operand" "=f,f")
16636         (match_operator:XF 3 "binary_fp_operator"
16637           [(float_extend:XF
16638              (match_operand:MODEF 1 "register_operand" "0,f"))
16639            (float_extend:XF
16640              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16641   "TARGET_80387"
16642   "* return output_387_binary_op (insn, operands);"
16643   [(set (attr "type")
16644         (cond [(match_operand:XF 3 "mult_operator" "")
16645                  (const_string "fmul")
16646                (match_operand:XF 3 "div_operator" "")
16647                  (const_string "fdiv")
16648               ]
16649               (const_string "fop")))
16650    (set_attr "mode" "<MODE>")])
16652 (define_split
16653   [(set (match_operand 0 "register_operand" "")
16654         (match_operator 3 "binary_fp_operator"
16655            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16656             (match_operand 2 "register_operand" "")]))]
16657   "reload_completed
16658    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16659   [(const_int 0)]
16661   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16662   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16663   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16664                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16665                                           GET_MODE (operands[3]),
16666                                           operands[4],
16667                                           operands[2])));
16668   ix86_free_from_memory (GET_MODE (operands[1]));
16669   DONE;
16672 (define_split
16673   [(set (match_operand 0 "register_operand" "")
16674         (match_operator 3 "binary_fp_operator"
16675            [(match_operand 1 "register_operand" "")
16676             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16677   "reload_completed
16678    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16679   [(const_int 0)]
16681   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16682   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16683   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16684                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16685                                           GET_MODE (operands[3]),
16686                                           operands[1],
16687                                           operands[4])));
16688   ix86_free_from_memory (GET_MODE (operands[2]));
16689   DONE;
16692 ;; FPU special functions.
16694 ;; This pattern implements a no-op XFmode truncation for
16695 ;; all fancy i386 XFmode math functions.
16697 (define_insn "truncxf<mode>2_i387_noop_unspec"
16698   [(set (match_operand:MODEF 0 "register_operand" "=f")
16699         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16700         UNSPEC_TRUNC_NOOP))]
16701   "TARGET_USE_FANCY_MATH_387"
16702   "* return output_387_reg_move (insn, operands);"
16703   [(set_attr "type" "fmov")
16704    (set_attr "mode" "<MODE>")])
16706 (define_insn "sqrtxf2"
16707   [(set (match_operand:XF 0 "register_operand" "=f")
16708         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16709   "TARGET_USE_FANCY_MATH_387"
16710   "fsqrt"
16711   [(set_attr "type" "fpspc")
16712    (set_attr "mode" "XF")
16713    (set_attr "athlon_decode" "direct")
16714    (set_attr "amdfam10_decode" "direct")])
16716 (define_insn "sqrt_extend<mode>xf2_i387"
16717   [(set (match_operand:XF 0 "register_operand" "=f")
16718         (sqrt:XF
16719           (float_extend:XF
16720             (match_operand:MODEF 1 "register_operand" "0"))))]
16721   "TARGET_USE_FANCY_MATH_387"
16722   "fsqrt"
16723   [(set_attr "type" "fpspc")
16724    (set_attr "mode" "XF")
16725    (set_attr "athlon_decode" "direct")
16726    (set_attr "amdfam10_decode" "direct")])
16728 (define_insn "*rsqrtsf2_sse"
16729   [(set (match_operand:SF 0 "register_operand" "=x")
16730         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16731                    UNSPEC_RSQRT))]
16732   "TARGET_SSE_MATH"
16733   "%vrsqrtss\t{%1, %d0|%d0, %1}"
16734   [(set_attr "type" "sse")
16735    (set_attr "prefix" "maybe_vex")
16736    (set_attr "mode" "SF")])
16738 (define_expand "rsqrtsf2"
16739   [(set (match_operand:SF 0 "register_operand" "")
16740         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16741                    UNSPEC_RSQRT))]
16742   "TARGET_SSE_MATH"
16744   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16745   DONE;
16748 (define_insn "*sqrt<mode>2_sse"
16749   [(set (match_operand:MODEF 0 "register_operand" "=x")
16750         (sqrt:MODEF
16751           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16752   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16753   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
16754   [(set_attr "type" "sse")
16755    (set_attr "prefix" "maybe_vex")
16756    (set_attr "mode" "<MODE>")
16757    (set_attr "athlon_decode" "*")
16758    (set_attr "amdfam10_decode" "*")])
16760 (define_expand "sqrt<mode>2"
16761   [(set (match_operand:MODEF 0 "register_operand" "")
16762         (sqrt:MODEF
16763           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16764   "TARGET_USE_FANCY_MATH_387
16765    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16767   if (<MODE>mode == SFmode
16768       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16769       && flag_finite_math_only && !flag_trapping_math
16770       && flag_unsafe_math_optimizations)
16771     {
16772       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16773       DONE;
16774     }
16776   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16777     {
16778       rtx op0 = gen_reg_rtx (XFmode);
16779       rtx op1 = force_reg (<MODE>mode, operands[1]);
16781       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16782       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16783       DONE;
16784    }
16787 (define_insn "fpremxf4_i387"
16788   [(set (match_operand:XF 0 "register_operand" "=f")
16789         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16790                     (match_operand:XF 3 "register_operand" "1")]
16791                    UNSPEC_FPREM_F))
16792    (set (match_operand:XF 1 "register_operand" "=u")
16793         (unspec:XF [(match_dup 2) (match_dup 3)]
16794                    UNSPEC_FPREM_U))
16795    (set (reg:CCFP FPSR_REG)
16796         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16797                      UNSPEC_C2_FLAG))]
16798   "TARGET_USE_FANCY_MATH_387"
16799   "fprem"
16800   [(set_attr "type" "fpspc")
16801    (set_attr "mode" "XF")])
16803 (define_expand "fmodxf3"
16804   [(use (match_operand:XF 0 "register_operand" ""))
16805    (use (match_operand:XF 1 "general_operand" ""))
16806    (use (match_operand:XF 2 "general_operand" ""))]
16807   "TARGET_USE_FANCY_MATH_387"
16809   rtx label = gen_label_rtx ();
16811   rtx op1 = gen_reg_rtx (XFmode);
16812   rtx op2 = gen_reg_rtx (XFmode);
16814   emit_move_insn (op2, operands[2]);
16815   emit_move_insn (op1, operands[1]);
16817   emit_label (label);
16818   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16819   ix86_emit_fp_unordered_jump (label);
16820   LABEL_NUSES (label) = 1;
16822   emit_move_insn (operands[0], op1);
16823   DONE;
16826 (define_expand "fmod<mode>3"
16827   [(use (match_operand:MODEF 0 "register_operand" ""))
16828    (use (match_operand:MODEF 1 "general_operand" ""))
16829    (use (match_operand:MODEF 2 "general_operand" ""))]
16830   "TARGET_USE_FANCY_MATH_387"
16832   rtx label = gen_label_rtx ();
16834   rtx op1 = gen_reg_rtx (XFmode);
16835   rtx op2 = gen_reg_rtx (XFmode);
16837   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16838   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16840   emit_label (label);
16841   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16842   ix86_emit_fp_unordered_jump (label);
16843   LABEL_NUSES (label) = 1;
16845   /* Truncate the result properly for strict SSE math.  */
16846   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16847       && !TARGET_MIX_SSE_I387)
16848     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16849   else
16850     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16852   DONE;
16855 (define_insn "fprem1xf4_i387"
16856   [(set (match_operand:XF 0 "register_operand" "=f")
16857         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16858                     (match_operand:XF 3 "register_operand" "1")]
16859                    UNSPEC_FPREM1_F))
16860    (set (match_operand:XF 1 "register_operand" "=u")
16861         (unspec:XF [(match_dup 2) (match_dup 3)]
16862                    UNSPEC_FPREM1_U))
16863    (set (reg:CCFP FPSR_REG)
16864         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16865                      UNSPEC_C2_FLAG))]
16866   "TARGET_USE_FANCY_MATH_387"
16867   "fprem1"
16868   [(set_attr "type" "fpspc")
16869    (set_attr "mode" "XF")])
16871 (define_expand "remainderxf3"
16872   [(use (match_operand:XF 0 "register_operand" ""))
16873    (use (match_operand:XF 1 "general_operand" ""))
16874    (use (match_operand:XF 2 "general_operand" ""))]
16875   "TARGET_USE_FANCY_MATH_387"
16877   rtx label = gen_label_rtx ();
16879   rtx op1 = gen_reg_rtx (XFmode);
16880   rtx op2 = gen_reg_rtx (XFmode);
16882   emit_move_insn (op2, operands[2]);
16883   emit_move_insn (op1, operands[1]);
16885   emit_label (label);
16886   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16887   ix86_emit_fp_unordered_jump (label);
16888   LABEL_NUSES (label) = 1;
16890   emit_move_insn (operands[0], op1);
16891   DONE;
16894 (define_expand "remainder<mode>3"
16895   [(use (match_operand:MODEF 0 "register_operand" ""))
16896    (use (match_operand:MODEF 1 "general_operand" ""))
16897    (use (match_operand:MODEF 2 "general_operand" ""))]
16898   "TARGET_USE_FANCY_MATH_387"
16900   rtx label = gen_label_rtx ();
16902   rtx op1 = gen_reg_rtx (XFmode);
16903   rtx op2 = gen_reg_rtx (XFmode);
16905   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16906   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16908   emit_label (label);
16910   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16911   ix86_emit_fp_unordered_jump (label);
16912   LABEL_NUSES (label) = 1;
16914   /* Truncate the result properly for strict SSE math.  */
16915   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16916       && !TARGET_MIX_SSE_I387)
16917     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16918   else
16919     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16921   DONE;
16924 (define_insn "*sinxf2_i387"
16925   [(set (match_operand:XF 0 "register_operand" "=f")
16926         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16927   "TARGET_USE_FANCY_MATH_387
16928    && flag_unsafe_math_optimizations"
16929   "fsin"
16930   [(set_attr "type" "fpspc")
16931    (set_attr "mode" "XF")])
16933 (define_insn "*sin_extend<mode>xf2_i387"
16934   [(set (match_operand:XF 0 "register_operand" "=f")
16935         (unspec:XF [(float_extend:XF
16936                       (match_operand:MODEF 1 "register_operand" "0"))]
16937                    UNSPEC_SIN))]
16938   "TARGET_USE_FANCY_MATH_387
16939    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16940        || TARGET_MIX_SSE_I387)
16941    && flag_unsafe_math_optimizations"
16942   "fsin"
16943   [(set_attr "type" "fpspc")
16944    (set_attr "mode" "XF")])
16946 (define_insn "*cosxf2_i387"
16947   [(set (match_operand:XF 0 "register_operand" "=f")
16948         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16949   "TARGET_USE_FANCY_MATH_387
16950    && flag_unsafe_math_optimizations"
16951   "fcos"
16952   [(set_attr "type" "fpspc")
16953    (set_attr "mode" "XF")])
16955 (define_insn "*cos_extend<mode>xf2_i387"
16956   [(set (match_operand:XF 0 "register_operand" "=f")
16957         (unspec:XF [(float_extend:XF
16958                       (match_operand:MODEF 1 "register_operand" "0"))]
16959                    UNSPEC_COS))]
16960   "TARGET_USE_FANCY_MATH_387
16961    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16962        || TARGET_MIX_SSE_I387)
16963    && flag_unsafe_math_optimizations"
16964   "fcos"
16965   [(set_attr "type" "fpspc")
16966    (set_attr "mode" "XF")])
16968 ;; When sincos pattern is defined, sin and cos builtin functions will be
16969 ;; expanded to sincos pattern with one of its outputs left unused.
16970 ;; CSE pass will figure out if two sincos patterns can be combined,
16971 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16972 ;; depending on the unused output.
16974 (define_insn "sincosxf3"
16975   [(set (match_operand:XF 0 "register_operand" "=f")
16976         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16977                    UNSPEC_SINCOS_COS))
16978    (set (match_operand:XF 1 "register_operand" "=u")
16979         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16980   "TARGET_USE_FANCY_MATH_387
16981    && flag_unsafe_math_optimizations"
16982   "fsincos"
16983   [(set_attr "type" "fpspc")
16984    (set_attr "mode" "XF")])
16986 (define_split
16987   [(set (match_operand:XF 0 "register_operand" "")
16988         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16989                    UNSPEC_SINCOS_COS))
16990    (set (match_operand:XF 1 "register_operand" "")
16991         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16992   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16993    && !(reload_completed || reload_in_progress)"
16994   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16995   "")
16997 (define_split
16998   [(set (match_operand:XF 0 "register_operand" "")
16999         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17000                    UNSPEC_SINCOS_COS))
17001    (set (match_operand:XF 1 "register_operand" "")
17002         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17003   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17004    && !(reload_completed || reload_in_progress)"
17005   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
17006   "")
17008 (define_insn "sincos_extend<mode>xf3_i387"
17009   [(set (match_operand:XF 0 "register_operand" "=f")
17010         (unspec:XF [(float_extend:XF
17011                       (match_operand:MODEF 2 "register_operand" "0"))]
17012                    UNSPEC_SINCOS_COS))
17013    (set (match_operand:XF 1 "register_operand" "=u")
17014         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17015   "TARGET_USE_FANCY_MATH_387
17016    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17017        || TARGET_MIX_SSE_I387)
17018    && flag_unsafe_math_optimizations"
17019   "fsincos"
17020   [(set_attr "type" "fpspc")
17021    (set_attr "mode" "XF")])
17023 (define_split
17024   [(set (match_operand:XF 0 "register_operand" "")
17025         (unspec:XF [(float_extend:XF
17026                       (match_operand:MODEF 2 "register_operand" ""))]
17027                    UNSPEC_SINCOS_COS))
17028    (set (match_operand:XF 1 "register_operand" "")
17029         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17030   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17031    && !(reload_completed || reload_in_progress)"
17032   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
17033   "")
17035 (define_split
17036   [(set (match_operand:XF 0 "register_operand" "")
17037         (unspec:XF [(float_extend:XF
17038                       (match_operand:MODEF 2 "register_operand" ""))]
17039                    UNSPEC_SINCOS_COS))
17040    (set (match_operand:XF 1 "register_operand" "")
17041         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17042   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17043    && !(reload_completed || reload_in_progress)"
17044   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
17045   "")
17047 (define_expand "sincos<mode>3"
17048   [(use (match_operand:MODEF 0 "register_operand" ""))
17049    (use (match_operand:MODEF 1 "register_operand" ""))
17050    (use (match_operand:MODEF 2 "register_operand" ""))]
17051   "TARGET_USE_FANCY_MATH_387
17052    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17053        || TARGET_MIX_SSE_I387)
17054    && flag_unsafe_math_optimizations"
17056   rtx op0 = gen_reg_rtx (XFmode);
17057   rtx op1 = gen_reg_rtx (XFmode);
17059   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17060   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17061   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17062   DONE;
17065 (define_insn "fptanxf4_i387"
17066   [(set (match_operand:XF 0 "register_operand" "=f")
17067         (match_operand:XF 3 "const_double_operand" "F"))
17068    (set (match_operand:XF 1 "register_operand" "=u")
17069         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17070                    UNSPEC_TAN))]
17071   "TARGET_USE_FANCY_MATH_387
17072    && flag_unsafe_math_optimizations
17073    && standard_80387_constant_p (operands[3]) == 2"
17074   "fptan"
17075   [(set_attr "type" "fpspc")
17076    (set_attr "mode" "XF")])
17078 (define_insn "fptan_extend<mode>xf4_i387"
17079   [(set (match_operand:MODEF 0 "register_operand" "=f")
17080         (match_operand:MODEF 3 "const_double_operand" "F"))
17081    (set (match_operand:XF 1 "register_operand" "=u")
17082         (unspec:XF [(float_extend:XF
17083                       (match_operand:MODEF 2 "register_operand" "0"))]
17084                    UNSPEC_TAN))]
17085   "TARGET_USE_FANCY_MATH_387
17086    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17087        || TARGET_MIX_SSE_I387)
17088    && flag_unsafe_math_optimizations
17089    && standard_80387_constant_p (operands[3]) == 2"
17090   "fptan"
17091   [(set_attr "type" "fpspc")
17092    (set_attr "mode" "XF")])
17094 (define_expand "tanxf2"
17095   [(use (match_operand:XF 0 "register_operand" ""))
17096    (use (match_operand:XF 1 "register_operand" ""))]
17097   "TARGET_USE_FANCY_MATH_387
17098    && flag_unsafe_math_optimizations"
17100   rtx one = gen_reg_rtx (XFmode);
17101   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17103   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17104   DONE;
17107 (define_expand "tan<mode>2"
17108   [(use (match_operand:MODEF 0 "register_operand" ""))
17109    (use (match_operand:MODEF 1 "register_operand" ""))]
17110   "TARGET_USE_FANCY_MATH_387
17111    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17112        || TARGET_MIX_SSE_I387)
17113    && flag_unsafe_math_optimizations"
17115   rtx op0 = gen_reg_rtx (XFmode);
17117   rtx one = gen_reg_rtx (<MODE>mode);
17118   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17120   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17121                                              operands[1], op2));
17122   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17123   DONE;
17126 (define_insn "*fpatanxf3_i387"
17127   [(set (match_operand:XF 0 "register_operand" "=f")
17128         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17129                     (match_operand:XF 2 "register_operand" "u")]
17130                    UNSPEC_FPATAN))
17131    (clobber (match_scratch:XF 3 "=2"))]
17132   "TARGET_USE_FANCY_MATH_387
17133    && flag_unsafe_math_optimizations"
17134   "fpatan"
17135   [(set_attr "type" "fpspc")
17136    (set_attr "mode" "XF")])
17138 (define_insn "fpatan_extend<mode>xf3_i387"
17139   [(set (match_operand:XF 0 "register_operand" "=f")
17140         (unspec:XF [(float_extend:XF
17141                       (match_operand:MODEF 1 "register_operand" "0"))
17142                     (float_extend:XF
17143                       (match_operand:MODEF 2 "register_operand" "u"))]
17144                    UNSPEC_FPATAN))
17145    (clobber (match_scratch:XF 3 "=2"))]
17146   "TARGET_USE_FANCY_MATH_387
17147    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17148        || TARGET_MIX_SSE_I387)
17149    && flag_unsafe_math_optimizations"
17150   "fpatan"
17151   [(set_attr "type" "fpspc")
17152    (set_attr "mode" "XF")])
17154 (define_expand "atan2xf3"
17155   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17156                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
17157                                (match_operand:XF 1 "register_operand" "")]
17158                               UNSPEC_FPATAN))
17159               (clobber (match_scratch:XF 3 ""))])]
17160   "TARGET_USE_FANCY_MATH_387
17161    && flag_unsafe_math_optimizations"
17162   "")
17164 (define_expand "atan2<mode>3"
17165   [(use (match_operand:MODEF 0 "register_operand" ""))
17166    (use (match_operand:MODEF 1 "register_operand" ""))
17167    (use (match_operand:MODEF 2 "register_operand" ""))]
17168   "TARGET_USE_FANCY_MATH_387
17169    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17170        || TARGET_MIX_SSE_I387)
17171    && flag_unsafe_math_optimizations"
17173   rtx op0 = gen_reg_rtx (XFmode);
17175   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17176   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17177   DONE;
17180 (define_expand "atanxf2"
17181   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17182                    (unspec:XF [(match_dup 2)
17183                                (match_operand:XF 1 "register_operand" "")]
17184                               UNSPEC_FPATAN))
17185               (clobber (match_scratch:XF 3 ""))])]
17186   "TARGET_USE_FANCY_MATH_387
17187    && flag_unsafe_math_optimizations"
17189   operands[2] = gen_reg_rtx (XFmode);
17190   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
17193 (define_expand "atan<mode>2"
17194   [(use (match_operand:MODEF 0 "register_operand" ""))
17195    (use (match_operand:MODEF 1 "register_operand" ""))]
17196   "TARGET_USE_FANCY_MATH_387
17197    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17198        || TARGET_MIX_SSE_I387)
17199    && flag_unsafe_math_optimizations"
17201   rtx op0 = gen_reg_rtx (XFmode);
17203   rtx op2 = gen_reg_rtx (<MODE>mode);
17204   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
17206   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17207   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17208   DONE;
17211 (define_expand "asinxf2"
17212   [(set (match_dup 2)
17213         (mult:XF (match_operand:XF 1 "register_operand" "")
17214                  (match_dup 1)))
17215    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17216    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17217    (parallel [(set (match_operand:XF 0 "register_operand" "")
17218                    (unspec:XF [(match_dup 5) (match_dup 1)]
17219                               UNSPEC_FPATAN))
17220               (clobber (match_scratch:XF 6 ""))])]
17221   "TARGET_USE_FANCY_MATH_387
17222    && flag_unsafe_math_optimizations"
17224   int i;
17226   if (optimize_insn_for_size_p ())
17227     FAIL;
17229   for (i = 2; i < 6; i++)
17230     operands[i] = gen_reg_rtx (XFmode);
17232   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17235 (define_expand "asin<mode>2"
17236   [(use (match_operand:MODEF 0 "register_operand" ""))
17237    (use (match_operand:MODEF 1 "general_operand" ""))]
17238  "TARGET_USE_FANCY_MATH_387
17239    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17240        || TARGET_MIX_SSE_I387)
17241    && flag_unsafe_math_optimizations"
17243   rtx op0 = gen_reg_rtx (XFmode);
17244   rtx op1 = gen_reg_rtx (XFmode);
17246   if (optimize_insn_for_size_p ())
17247     FAIL;
17249   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17250   emit_insn (gen_asinxf2 (op0, op1));
17251   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17252   DONE;
17255 (define_expand "acosxf2"
17256   [(set (match_dup 2)
17257         (mult:XF (match_operand:XF 1 "register_operand" "")
17258                  (match_dup 1)))
17259    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17260    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17261    (parallel [(set (match_operand:XF 0 "register_operand" "")
17262                    (unspec:XF [(match_dup 1) (match_dup 5)]
17263                               UNSPEC_FPATAN))
17264               (clobber (match_scratch:XF 6 ""))])]
17265   "TARGET_USE_FANCY_MATH_387
17266    && flag_unsafe_math_optimizations"
17268   int i;
17270   if (optimize_insn_for_size_p ())
17271     FAIL;
17273   for (i = 2; i < 6; i++)
17274     operands[i] = gen_reg_rtx (XFmode);
17276   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17279 (define_expand "acos<mode>2"
17280   [(use (match_operand:MODEF 0 "register_operand" ""))
17281    (use (match_operand:MODEF 1 "general_operand" ""))]
17282  "TARGET_USE_FANCY_MATH_387
17283    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17284        || TARGET_MIX_SSE_I387)
17285    && flag_unsafe_math_optimizations"
17287   rtx op0 = gen_reg_rtx (XFmode);
17288   rtx op1 = gen_reg_rtx (XFmode);
17290   if (optimize_insn_for_size_p ())
17291     FAIL;
17293   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17294   emit_insn (gen_acosxf2 (op0, op1));
17295   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17296   DONE;
17299 (define_insn "fyl2xxf3_i387"
17300   [(set (match_operand:XF 0 "register_operand" "=f")
17301         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17302                     (match_operand:XF 2 "register_operand" "u")]
17303                    UNSPEC_FYL2X))
17304    (clobber (match_scratch:XF 3 "=2"))]
17305   "TARGET_USE_FANCY_MATH_387
17306    && flag_unsafe_math_optimizations"
17307   "fyl2x"
17308   [(set_attr "type" "fpspc")
17309    (set_attr "mode" "XF")])
17311 (define_insn "fyl2x_extend<mode>xf3_i387"
17312   [(set (match_operand:XF 0 "register_operand" "=f")
17313         (unspec:XF [(float_extend:XF
17314                       (match_operand:MODEF 1 "register_operand" "0"))
17315                     (match_operand:XF 2 "register_operand" "u")]
17316                    UNSPEC_FYL2X))
17317    (clobber (match_scratch:XF 3 "=2"))]
17318   "TARGET_USE_FANCY_MATH_387
17319    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17320        || TARGET_MIX_SSE_I387)
17321    && flag_unsafe_math_optimizations"
17322   "fyl2x"
17323   [(set_attr "type" "fpspc")
17324    (set_attr "mode" "XF")])
17326 (define_expand "logxf2"
17327   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17328                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17329                                (match_dup 2)] UNSPEC_FYL2X))
17330               (clobber (match_scratch:XF 3 ""))])]
17331   "TARGET_USE_FANCY_MATH_387
17332    && flag_unsafe_math_optimizations"
17334   operands[2] = gen_reg_rtx (XFmode);
17335   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17338 (define_expand "log<mode>2"
17339   [(use (match_operand:MODEF 0 "register_operand" ""))
17340    (use (match_operand:MODEF 1 "register_operand" ""))]
17341   "TARGET_USE_FANCY_MATH_387
17342    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17343        || TARGET_MIX_SSE_I387)
17344    && flag_unsafe_math_optimizations"
17346   rtx op0 = gen_reg_rtx (XFmode);
17348   rtx op2 = gen_reg_rtx (XFmode);
17349   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17351   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17352   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17353   DONE;
17356 (define_expand "log10xf2"
17357   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17358                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17359                                (match_dup 2)] UNSPEC_FYL2X))
17360               (clobber (match_scratch:XF 3 ""))])]
17361   "TARGET_USE_FANCY_MATH_387
17362    && flag_unsafe_math_optimizations"
17364   operands[2] = gen_reg_rtx (XFmode);
17365   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17368 (define_expand "log10<mode>2"
17369   [(use (match_operand:MODEF 0 "register_operand" ""))
17370    (use (match_operand:MODEF 1 "register_operand" ""))]
17371   "TARGET_USE_FANCY_MATH_387
17372    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17373        || TARGET_MIX_SSE_I387)
17374    && flag_unsafe_math_optimizations"
17376   rtx op0 = gen_reg_rtx (XFmode);
17378   rtx op2 = gen_reg_rtx (XFmode);
17379   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17381   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17382   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17383   DONE;
17386 (define_expand "log2xf2"
17387   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17388                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17389                                (match_dup 2)] UNSPEC_FYL2X))
17390               (clobber (match_scratch:XF 3 ""))])]
17391   "TARGET_USE_FANCY_MATH_387
17392    && flag_unsafe_math_optimizations"
17394   operands[2] = gen_reg_rtx (XFmode);
17395   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17398 (define_expand "log2<mode>2"
17399   [(use (match_operand:MODEF 0 "register_operand" ""))
17400    (use (match_operand:MODEF 1 "register_operand" ""))]
17401   "TARGET_USE_FANCY_MATH_387
17402    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17403        || TARGET_MIX_SSE_I387)
17404    && flag_unsafe_math_optimizations"
17406   rtx op0 = gen_reg_rtx (XFmode);
17408   rtx op2 = gen_reg_rtx (XFmode);
17409   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17411   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17412   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17413   DONE;
17416 (define_insn "fyl2xp1xf3_i387"
17417   [(set (match_operand:XF 0 "register_operand" "=f")
17418         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17419                     (match_operand:XF 2 "register_operand" "u")]
17420                    UNSPEC_FYL2XP1))
17421    (clobber (match_scratch:XF 3 "=2"))]
17422   "TARGET_USE_FANCY_MATH_387
17423    && flag_unsafe_math_optimizations"
17424   "fyl2xp1"
17425   [(set_attr "type" "fpspc")
17426    (set_attr "mode" "XF")])
17428 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17429   [(set (match_operand:XF 0 "register_operand" "=f")
17430         (unspec:XF [(float_extend:XF
17431                       (match_operand:MODEF 1 "register_operand" "0"))
17432                     (match_operand:XF 2 "register_operand" "u")]
17433                    UNSPEC_FYL2XP1))
17434    (clobber (match_scratch:XF 3 "=2"))]
17435   "TARGET_USE_FANCY_MATH_387
17436    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17437        || TARGET_MIX_SSE_I387)
17438    && flag_unsafe_math_optimizations"
17439   "fyl2xp1"
17440   [(set_attr "type" "fpspc")
17441    (set_attr "mode" "XF")])
17443 (define_expand "log1pxf2"
17444   [(use (match_operand:XF 0 "register_operand" ""))
17445    (use (match_operand:XF 1 "register_operand" ""))]
17446   "TARGET_USE_FANCY_MATH_387
17447    && flag_unsafe_math_optimizations"
17449   if (optimize_insn_for_size_p ())
17450     FAIL;
17452   ix86_emit_i387_log1p (operands[0], operands[1]);
17453   DONE;
17456 (define_expand "log1p<mode>2"
17457   [(use (match_operand:MODEF 0 "register_operand" ""))
17458    (use (match_operand:MODEF 1 "register_operand" ""))]
17459   "TARGET_USE_FANCY_MATH_387
17460    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17461        || TARGET_MIX_SSE_I387)
17462    && flag_unsafe_math_optimizations"
17464   rtx op0;
17466   if (optimize_insn_for_size_p ())
17467     FAIL;
17469   op0 = gen_reg_rtx (XFmode);
17471   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17473   ix86_emit_i387_log1p (op0, operands[1]);
17474   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17475   DONE;
17478 (define_insn "fxtractxf3_i387"
17479   [(set (match_operand:XF 0 "register_operand" "=f")
17480         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17481                    UNSPEC_XTRACT_FRACT))
17482    (set (match_operand:XF 1 "register_operand" "=u")
17483         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17484   "TARGET_USE_FANCY_MATH_387
17485    && flag_unsafe_math_optimizations"
17486   "fxtract"
17487   [(set_attr "type" "fpspc")
17488    (set_attr "mode" "XF")])
17490 (define_insn "fxtract_extend<mode>xf3_i387"
17491   [(set (match_operand:XF 0 "register_operand" "=f")
17492         (unspec:XF [(float_extend:XF
17493                       (match_operand:MODEF 2 "register_operand" "0"))]
17494                    UNSPEC_XTRACT_FRACT))
17495    (set (match_operand:XF 1 "register_operand" "=u")
17496         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17497   "TARGET_USE_FANCY_MATH_387
17498    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17499        || TARGET_MIX_SSE_I387)
17500    && flag_unsafe_math_optimizations"
17501   "fxtract"
17502   [(set_attr "type" "fpspc")
17503    (set_attr "mode" "XF")])
17505 (define_expand "logbxf2"
17506   [(parallel [(set (match_dup 2)
17507                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17508                               UNSPEC_XTRACT_FRACT))
17509               (set (match_operand:XF 0 "register_operand" "")
17510                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17511   "TARGET_USE_FANCY_MATH_387
17512    && flag_unsafe_math_optimizations"
17514   operands[2] = gen_reg_rtx (XFmode);
17517 (define_expand "logb<mode>2"
17518   [(use (match_operand:MODEF 0 "register_operand" ""))
17519    (use (match_operand:MODEF 1 "register_operand" ""))]
17520   "TARGET_USE_FANCY_MATH_387
17521    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17522        || TARGET_MIX_SSE_I387)
17523    && flag_unsafe_math_optimizations"
17525   rtx op0 = gen_reg_rtx (XFmode);
17526   rtx op1 = gen_reg_rtx (XFmode);
17528   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17529   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17530   DONE;
17533 (define_expand "ilogbxf2"
17534   [(use (match_operand:SI 0 "register_operand" ""))
17535    (use (match_operand:XF 1 "register_operand" ""))]
17536   "TARGET_USE_FANCY_MATH_387
17537    && flag_unsafe_math_optimizations"
17539   rtx op0, op1;
17541   if (optimize_insn_for_size_p ())
17542     FAIL;
17544   op0 = gen_reg_rtx (XFmode);
17545   op1 = gen_reg_rtx (XFmode);
17547   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17548   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17549   DONE;
17552 (define_expand "ilogb<mode>2"
17553   [(use (match_operand:SI 0 "register_operand" ""))
17554    (use (match_operand:MODEF 1 "register_operand" ""))]
17555   "TARGET_USE_FANCY_MATH_387
17556    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17557        || TARGET_MIX_SSE_I387)
17558    && flag_unsafe_math_optimizations"
17560   rtx op0, op1;
17562   if (optimize_insn_for_size_p ())
17563     FAIL;
17565   op0 = gen_reg_rtx (XFmode);
17566   op1 = gen_reg_rtx (XFmode);
17568   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17569   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17570   DONE;
17573 (define_insn "*f2xm1xf2_i387"
17574   [(set (match_operand:XF 0 "register_operand" "=f")
17575         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17576                    UNSPEC_F2XM1))]
17577   "TARGET_USE_FANCY_MATH_387
17578    && flag_unsafe_math_optimizations"
17579   "f2xm1"
17580   [(set_attr "type" "fpspc")
17581    (set_attr "mode" "XF")])
17583 (define_insn "*fscalexf4_i387"
17584   [(set (match_operand:XF 0 "register_operand" "=f")
17585         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17586                     (match_operand:XF 3 "register_operand" "1")]
17587                    UNSPEC_FSCALE_FRACT))
17588    (set (match_operand:XF 1 "register_operand" "=u")
17589         (unspec:XF [(match_dup 2) (match_dup 3)]
17590                    UNSPEC_FSCALE_EXP))]
17591   "TARGET_USE_FANCY_MATH_387
17592    && flag_unsafe_math_optimizations"
17593   "fscale"
17594   [(set_attr "type" "fpspc")
17595    (set_attr "mode" "XF")])
17597 (define_expand "expNcorexf3"
17598   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17599                                (match_operand:XF 2 "register_operand" "")))
17600    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17601    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17602    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17603    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17604    (parallel [(set (match_operand:XF 0 "register_operand" "")
17605                    (unspec:XF [(match_dup 8) (match_dup 4)]
17606                               UNSPEC_FSCALE_FRACT))
17607               (set (match_dup 9)
17608                    (unspec:XF [(match_dup 8) (match_dup 4)]
17609                               UNSPEC_FSCALE_EXP))])]
17610   "TARGET_USE_FANCY_MATH_387
17611    && flag_unsafe_math_optimizations"
17613   int i;
17615   if (optimize_insn_for_size_p ())
17616     FAIL;
17618   for (i = 3; i < 10; i++)
17619     operands[i] = gen_reg_rtx (XFmode);
17621   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17624 (define_expand "expxf2"
17625   [(use (match_operand:XF 0 "register_operand" ""))
17626    (use (match_operand:XF 1 "register_operand" ""))]
17627   "TARGET_USE_FANCY_MATH_387
17628    && flag_unsafe_math_optimizations"
17630   rtx op2;
17632   if (optimize_insn_for_size_p ())
17633     FAIL;
17635   op2 = gen_reg_rtx (XFmode);
17636   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17638   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17639   DONE;
17642 (define_expand "exp<mode>2"
17643   [(use (match_operand:MODEF 0 "register_operand" ""))
17644    (use (match_operand:MODEF 1 "general_operand" ""))]
17645  "TARGET_USE_FANCY_MATH_387
17646    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17647        || TARGET_MIX_SSE_I387)
17648    && flag_unsafe_math_optimizations"
17650   rtx op0, op1;
17652   if (optimize_insn_for_size_p ())
17653     FAIL;
17655   op0 = gen_reg_rtx (XFmode);
17656   op1 = gen_reg_rtx (XFmode);
17658   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17659   emit_insn (gen_expxf2 (op0, op1));
17660   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17661   DONE;
17664 (define_expand "exp10xf2"
17665   [(use (match_operand:XF 0 "register_operand" ""))
17666    (use (match_operand:XF 1 "register_operand" ""))]
17667   "TARGET_USE_FANCY_MATH_387
17668    && flag_unsafe_math_optimizations"
17670   rtx op2;
17672   if (optimize_insn_for_size_p ())
17673     FAIL;
17675   op2 = gen_reg_rtx (XFmode);
17676   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17678   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17679   DONE;
17682 (define_expand "exp10<mode>2"
17683   [(use (match_operand:MODEF 0 "register_operand" ""))
17684    (use (match_operand:MODEF 1 "general_operand" ""))]
17685  "TARGET_USE_FANCY_MATH_387
17686    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17687        || TARGET_MIX_SSE_I387)
17688    && flag_unsafe_math_optimizations"
17690   rtx op0, op1;
17692   if (optimize_insn_for_size_p ())
17693     FAIL;
17695   op0 = gen_reg_rtx (XFmode);
17696   op1 = gen_reg_rtx (XFmode);
17698   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17699   emit_insn (gen_exp10xf2 (op0, op1));
17700   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17701   DONE;
17704 (define_expand "exp2xf2"
17705   [(use (match_operand:XF 0 "register_operand" ""))
17706    (use (match_operand:XF 1 "register_operand" ""))]
17707   "TARGET_USE_FANCY_MATH_387
17708    && flag_unsafe_math_optimizations"
17710   rtx op2;
17712   if (optimize_insn_for_size_p ())
17713     FAIL;
17715   op2 = gen_reg_rtx (XFmode);
17716   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17718   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17719   DONE;
17722 (define_expand "exp2<mode>2"
17723   [(use (match_operand:MODEF 0 "register_operand" ""))
17724    (use (match_operand:MODEF 1 "general_operand" ""))]
17725  "TARGET_USE_FANCY_MATH_387
17726    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17727        || TARGET_MIX_SSE_I387)
17728    && flag_unsafe_math_optimizations"
17730   rtx op0, op1;
17732   if (optimize_insn_for_size_p ())
17733     FAIL;
17735   op0 = gen_reg_rtx (XFmode);
17736   op1 = gen_reg_rtx (XFmode);
17738   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17739   emit_insn (gen_exp2xf2 (op0, op1));
17740   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17741   DONE;
17744 (define_expand "expm1xf2"
17745   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17746                                (match_dup 2)))
17747    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17748    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17749    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17750    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17751    (parallel [(set (match_dup 7)
17752                    (unspec:XF [(match_dup 6) (match_dup 4)]
17753                               UNSPEC_FSCALE_FRACT))
17754               (set (match_dup 8)
17755                    (unspec:XF [(match_dup 6) (match_dup 4)]
17756                               UNSPEC_FSCALE_EXP))])
17757    (parallel [(set (match_dup 10)
17758                    (unspec:XF [(match_dup 9) (match_dup 8)]
17759                               UNSPEC_FSCALE_FRACT))
17760               (set (match_dup 11)
17761                    (unspec:XF [(match_dup 9) (match_dup 8)]
17762                               UNSPEC_FSCALE_EXP))])
17763    (set (match_dup 12) (minus:XF (match_dup 10)
17764                                  (float_extend:XF (match_dup 13))))
17765    (set (match_operand:XF 0 "register_operand" "")
17766         (plus:XF (match_dup 12) (match_dup 7)))]
17767   "TARGET_USE_FANCY_MATH_387
17768    && flag_unsafe_math_optimizations"
17770   int i;
17772   if (optimize_insn_for_size_p ())
17773     FAIL;
17775   for (i = 2; i < 13; i++)
17776     operands[i] = gen_reg_rtx (XFmode);
17778   operands[13]
17779     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17781   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17784 (define_expand "expm1<mode>2"
17785   [(use (match_operand:MODEF 0 "register_operand" ""))
17786    (use (match_operand:MODEF 1 "general_operand" ""))]
17787  "TARGET_USE_FANCY_MATH_387
17788    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17789        || TARGET_MIX_SSE_I387)
17790    && flag_unsafe_math_optimizations"
17792   rtx op0, op1;
17794   if (optimize_insn_for_size_p ())
17795     FAIL;
17797   op0 = gen_reg_rtx (XFmode);
17798   op1 = gen_reg_rtx (XFmode);
17800   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17801   emit_insn (gen_expm1xf2 (op0, op1));
17802   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17803   DONE;
17806 (define_expand "ldexpxf3"
17807   [(set (match_dup 3)
17808         (float:XF (match_operand:SI 2 "register_operand" "")))
17809    (parallel [(set (match_operand:XF 0 " register_operand" "")
17810                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17811                                (match_dup 3)]
17812                               UNSPEC_FSCALE_FRACT))
17813               (set (match_dup 4)
17814                    (unspec:XF [(match_dup 1) (match_dup 3)]
17815                               UNSPEC_FSCALE_EXP))])]
17816   "TARGET_USE_FANCY_MATH_387
17817    && flag_unsafe_math_optimizations"
17819   if (optimize_insn_for_size_p ())
17820     FAIL;
17822   operands[3] = gen_reg_rtx (XFmode);
17823   operands[4] = gen_reg_rtx (XFmode);
17826 (define_expand "ldexp<mode>3"
17827   [(use (match_operand:MODEF 0 "register_operand" ""))
17828    (use (match_operand:MODEF 1 "general_operand" ""))
17829    (use (match_operand:SI 2 "register_operand" ""))]
17830  "TARGET_USE_FANCY_MATH_387
17831    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17832        || TARGET_MIX_SSE_I387)
17833    && flag_unsafe_math_optimizations"
17835   rtx op0, op1;
17837   if (optimize_insn_for_size_p ())
17838     FAIL;
17840   op0 = gen_reg_rtx (XFmode);
17841   op1 = gen_reg_rtx (XFmode);
17843   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17844   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17845   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17846   DONE;
17849 (define_expand "scalbxf3"
17850   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17851                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17852                                (match_operand:XF 2 "register_operand" "")]
17853                               UNSPEC_FSCALE_FRACT))
17854               (set (match_dup 3)
17855                    (unspec:XF [(match_dup 1) (match_dup 2)]
17856                               UNSPEC_FSCALE_EXP))])]
17857   "TARGET_USE_FANCY_MATH_387
17858    && flag_unsafe_math_optimizations"
17860   if (optimize_insn_for_size_p ())
17861     FAIL;
17863   operands[3] = gen_reg_rtx (XFmode);
17866 (define_expand "scalb<mode>3"
17867   [(use (match_operand:MODEF 0 "register_operand" ""))
17868    (use (match_operand:MODEF 1 "general_operand" ""))
17869    (use (match_operand:MODEF 2 "register_operand" ""))]
17870  "TARGET_USE_FANCY_MATH_387
17871    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17872        || TARGET_MIX_SSE_I387)
17873    && flag_unsafe_math_optimizations"
17875   rtx op0, op1, op2;
17877   if (optimize_insn_for_size_p ())
17878     FAIL;
17880   op0 = gen_reg_rtx (XFmode);
17881   op1 = gen_reg_rtx (XFmode);
17882   op2 = gen_reg_rtx (XFmode);
17884   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17885   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17886   emit_insn (gen_scalbxf3 (op0, op1, op2));
17887   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17888   DONE;
17892 (define_insn "sse4_1_round<mode>2"
17893   [(set (match_operand:MODEF 0 "register_operand" "=x")
17894         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17895                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
17896                       UNSPEC_ROUND))]
17897   "TARGET_ROUND"
17898   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17899   [(set_attr "type" "ssecvt")
17900    (set_attr "prefix_extra" "1")
17901    (set_attr "prefix" "maybe_vex")
17902    (set_attr "mode" "<MODE>")])
17904 (define_insn "rintxf2"
17905   [(set (match_operand:XF 0 "register_operand" "=f")
17906         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17907                    UNSPEC_FRNDINT))]
17908   "TARGET_USE_FANCY_MATH_387
17909    && flag_unsafe_math_optimizations"
17910   "frndint"
17911   [(set_attr "type" "fpspc")
17912    (set_attr "mode" "XF")])
17914 (define_expand "rint<mode>2"
17915   [(use (match_operand:MODEF 0 "register_operand" ""))
17916    (use (match_operand:MODEF 1 "register_operand" ""))]
17917   "(TARGET_USE_FANCY_MATH_387
17918     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17919         || TARGET_MIX_SSE_I387)
17920     && flag_unsafe_math_optimizations)
17921    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17922        && !flag_trapping_math)"
17924   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17925       && !flag_trapping_math)
17926     {
17927       if (!TARGET_ROUND && optimize_insn_for_size_p ())
17928         FAIL;
17929       if (TARGET_ROUND)
17930         emit_insn (gen_sse4_1_round<mode>2
17931                    (operands[0], operands[1], GEN_INT (0x04)));
17932       else
17933         ix86_expand_rint (operand0, operand1);
17934     }
17935   else
17936     {
17937       rtx op0 = gen_reg_rtx (XFmode);
17938       rtx op1 = gen_reg_rtx (XFmode);
17940       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17941       emit_insn (gen_rintxf2 (op0, op1));
17943       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17944     }
17945   DONE;
17948 (define_expand "round<mode>2"
17949   [(match_operand:MODEF 0 "register_operand" "")
17950    (match_operand:MODEF 1 "nonimmediate_operand" "")]
17951   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17952    && !flag_trapping_math && !flag_rounding_math"
17954   if (optimize_insn_for_size_p ())
17955     FAIL;
17956   if (TARGET_64BIT || (<MODE>mode != DFmode))
17957     ix86_expand_round (operand0, operand1);
17958   else
17959     ix86_expand_rounddf_32 (operand0, operand1);
17960   DONE;
17963 (define_insn_and_split "*fistdi2_1"
17964   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17965         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17966                    UNSPEC_FIST))]
17967   "TARGET_USE_FANCY_MATH_387
17968    && !(reload_completed || reload_in_progress)"
17969   "#"
17970   "&& 1"
17971   [(const_int 0)]
17973   if (memory_operand (operands[0], VOIDmode))
17974     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17975   else
17976     {
17977       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17978       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17979                                          operands[2]));
17980     }
17981   DONE;
17983   [(set_attr "type" "fpspc")
17984    (set_attr "mode" "DI")])
17986 (define_insn "fistdi2"
17987   [(set (match_operand:DI 0 "memory_operand" "=m")
17988         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17989                    UNSPEC_FIST))
17990    (clobber (match_scratch:XF 2 "=&1f"))]
17991   "TARGET_USE_FANCY_MATH_387"
17992   "* return output_fix_trunc (insn, operands, 0);"
17993   [(set_attr "type" "fpspc")
17994    (set_attr "mode" "DI")])
17996 (define_insn "fistdi2_with_temp"
17997   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17998         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17999                    UNSPEC_FIST))
18000    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
18001    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
18002   "TARGET_USE_FANCY_MATH_387"
18003   "#"
18004   [(set_attr "type" "fpspc")
18005    (set_attr "mode" "DI")])
18007 (define_split
18008   [(set (match_operand:DI 0 "register_operand" "")
18009         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18010                    UNSPEC_FIST))
18011    (clobber (match_operand:DI 2 "memory_operand" ""))
18012    (clobber (match_scratch 3 ""))]
18013   "reload_completed"
18014   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18015               (clobber (match_dup 3))])
18016    (set (match_dup 0) (match_dup 2))]
18017   "")
18019 (define_split
18020   [(set (match_operand:DI 0 "memory_operand" "")
18021         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18022                    UNSPEC_FIST))
18023    (clobber (match_operand:DI 2 "memory_operand" ""))
18024    (clobber (match_scratch 3 ""))]
18025   "reload_completed"
18026   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18027               (clobber (match_dup 3))])]
18028   "")
18030 (define_insn_and_split "*fist<mode>2_1"
18031   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18032         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18033                            UNSPEC_FIST))]
18034   "TARGET_USE_FANCY_MATH_387
18035    && !(reload_completed || reload_in_progress)"
18036   "#"
18037   "&& 1"
18038   [(const_int 0)]
18040   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18041   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
18042                                         operands[2]));
18043   DONE;
18045   [(set_attr "type" "fpspc")
18046    (set_attr "mode" "<MODE>")])
18048 (define_insn "fist<mode>2"
18049   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18050         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18051                            UNSPEC_FIST))]
18052   "TARGET_USE_FANCY_MATH_387"
18053   "* return output_fix_trunc (insn, operands, 0);"
18054   [(set_attr "type" "fpspc")
18055    (set_attr "mode" "<MODE>")])
18057 (define_insn "fist<mode>2_with_temp"
18058   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
18059         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18060                            UNSPEC_FIST))
18061    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18062   "TARGET_USE_FANCY_MATH_387"
18063   "#"
18064   [(set_attr "type" "fpspc")
18065    (set_attr "mode" "<MODE>")])
18067 (define_split
18068   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18069         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18070                            UNSPEC_FIST))
18071    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18072   "reload_completed"
18073   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18074    (set (match_dup 0) (match_dup 2))]
18075   "")
18077 (define_split
18078   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18079         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18080                            UNSPEC_FIST))
18081    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18082   "reload_completed"
18083   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18084   "")
18086 (define_expand "lrintxf<mode>2"
18087   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18088      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18089                       UNSPEC_FIST))]
18090   "TARGET_USE_FANCY_MATH_387"
18091   "")
18093 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18094   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18095      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18096                         UNSPEC_FIX_NOTRUNC))]
18097   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18098    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18099   "")
18101 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18102   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18103    (match_operand:MODEF 1 "register_operand" "")]
18104   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18105    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18106    && !flag_trapping_math && !flag_rounding_math"
18108   if (optimize_insn_for_size_p ())
18109     FAIL;
18110   ix86_expand_lround (operand0, operand1);
18111   DONE;
18114 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18115 (define_insn_and_split "frndintxf2_floor"
18116   [(set (match_operand:XF 0 "register_operand" "")
18117         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18118          UNSPEC_FRNDINT_FLOOR))
18119    (clobber (reg:CC FLAGS_REG))]
18120   "TARGET_USE_FANCY_MATH_387
18121    && flag_unsafe_math_optimizations
18122    && !(reload_completed || reload_in_progress)"
18123   "#"
18124   "&& 1"
18125   [(const_int 0)]
18127   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18129   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18130   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18132   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18133                                         operands[2], operands[3]));
18134   DONE;
18136   [(set_attr "type" "frndint")
18137    (set_attr "i387_cw" "floor")
18138    (set_attr "mode" "XF")])
18140 (define_insn "frndintxf2_floor_i387"
18141   [(set (match_operand:XF 0 "register_operand" "=f")
18142         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18143          UNSPEC_FRNDINT_FLOOR))
18144    (use (match_operand:HI 2 "memory_operand" "m"))
18145    (use (match_operand:HI 3 "memory_operand" "m"))]
18146   "TARGET_USE_FANCY_MATH_387
18147    && flag_unsafe_math_optimizations"
18148   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18149   [(set_attr "type" "frndint")
18150    (set_attr "i387_cw" "floor")
18151    (set_attr "mode" "XF")])
18153 (define_expand "floorxf2"
18154   [(use (match_operand:XF 0 "register_operand" ""))
18155    (use (match_operand:XF 1 "register_operand" ""))]
18156   "TARGET_USE_FANCY_MATH_387
18157    && flag_unsafe_math_optimizations"
18159   if (optimize_insn_for_size_p ())
18160     FAIL;
18161   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18162   DONE;
18165 (define_expand "floor<mode>2"
18166   [(use (match_operand:MODEF 0 "register_operand" ""))
18167    (use (match_operand:MODEF 1 "register_operand" ""))]
18168   "(TARGET_USE_FANCY_MATH_387
18169     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18170         || TARGET_MIX_SSE_I387)
18171     && flag_unsafe_math_optimizations)
18172    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18173        && !flag_trapping_math)"
18175   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18176       && !flag_trapping_math
18177       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18178     {
18179       if (!TARGET_ROUND && optimize_insn_for_size_p ())
18180         FAIL;
18181       if (TARGET_ROUND)
18182         emit_insn (gen_sse4_1_round<mode>2
18183                    (operands[0], operands[1], GEN_INT (0x01)));
18184       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18185         ix86_expand_floorceil (operand0, operand1, true);
18186       else
18187         ix86_expand_floorceildf_32 (operand0, operand1, true);
18188     }
18189   else
18190     {
18191       rtx op0, op1;
18193       if (optimize_insn_for_size_p ())
18194         FAIL;
18196       op0 = gen_reg_rtx (XFmode);
18197       op1 = gen_reg_rtx (XFmode);
18198       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18199       emit_insn (gen_frndintxf2_floor (op0, op1));
18201       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18202     }
18203   DONE;
18206 (define_insn_and_split "*fist<mode>2_floor_1"
18207   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18208         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18209          UNSPEC_FIST_FLOOR))
18210    (clobber (reg:CC FLAGS_REG))]
18211   "TARGET_USE_FANCY_MATH_387
18212    && flag_unsafe_math_optimizations
18213    && !(reload_completed || reload_in_progress)"
18214   "#"
18215   "&& 1"
18216   [(const_int 0)]
18218   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18220   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18221   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18222   if (memory_operand (operands[0], VOIDmode))
18223     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18224                                       operands[2], operands[3]));
18225   else
18226     {
18227       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18228       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18229                                                   operands[2], operands[3],
18230                                                   operands[4]));
18231     }
18232   DONE;
18234   [(set_attr "type" "fistp")
18235    (set_attr "i387_cw" "floor")
18236    (set_attr "mode" "<MODE>")])
18238 (define_insn "fistdi2_floor"
18239   [(set (match_operand:DI 0 "memory_operand" "=m")
18240         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18241          UNSPEC_FIST_FLOOR))
18242    (use (match_operand:HI 2 "memory_operand" "m"))
18243    (use (match_operand:HI 3 "memory_operand" "m"))
18244    (clobber (match_scratch:XF 4 "=&1f"))]
18245   "TARGET_USE_FANCY_MATH_387
18246    && flag_unsafe_math_optimizations"
18247   "* return output_fix_trunc (insn, operands, 0);"
18248   [(set_attr "type" "fistp")
18249    (set_attr "i387_cw" "floor")
18250    (set_attr "mode" "DI")])
18252 (define_insn "fistdi2_floor_with_temp"
18253   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18254         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18255          UNSPEC_FIST_FLOOR))
18256    (use (match_operand:HI 2 "memory_operand" "m,m"))
18257    (use (match_operand:HI 3 "memory_operand" "m,m"))
18258    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18259    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18260   "TARGET_USE_FANCY_MATH_387
18261    && flag_unsafe_math_optimizations"
18262   "#"
18263   [(set_attr "type" "fistp")
18264    (set_attr "i387_cw" "floor")
18265    (set_attr "mode" "DI")])
18267 (define_split
18268   [(set (match_operand:DI 0 "register_operand" "")
18269         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18270          UNSPEC_FIST_FLOOR))
18271    (use (match_operand:HI 2 "memory_operand" ""))
18272    (use (match_operand:HI 3 "memory_operand" ""))
18273    (clobber (match_operand:DI 4 "memory_operand" ""))
18274    (clobber (match_scratch 5 ""))]
18275   "reload_completed"
18276   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18277               (use (match_dup 2))
18278               (use (match_dup 3))
18279               (clobber (match_dup 5))])
18280    (set (match_dup 0) (match_dup 4))]
18281   "")
18283 (define_split
18284   [(set (match_operand:DI 0 "memory_operand" "")
18285         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18286          UNSPEC_FIST_FLOOR))
18287    (use (match_operand:HI 2 "memory_operand" ""))
18288    (use (match_operand:HI 3 "memory_operand" ""))
18289    (clobber (match_operand:DI 4 "memory_operand" ""))
18290    (clobber (match_scratch 5 ""))]
18291   "reload_completed"
18292   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18293               (use (match_dup 2))
18294               (use (match_dup 3))
18295               (clobber (match_dup 5))])]
18296   "")
18298 (define_insn "fist<mode>2_floor"
18299   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18300         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18301          UNSPEC_FIST_FLOOR))
18302    (use (match_operand:HI 2 "memory_operand" "m"))
18303    (use (match_operand:HI 3 "memory_operand" "m"))]
18304   "TARGET_USE_FANCY_MATH_387
18305    && flag_unsafe_math_optimizations"
18306   "* return output_fix_trunc (insn, operands, 0);"
18307   [(set_attr "type" "fistp")
18308    (set_attr "i387_cw" "floor")
18309    (set_attr "mode" "<MODE>")])
18311 (define_insn "fist<mode>2_floor_with_temp"
18312   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18313         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18314          UNSPEC_FIST_FLOOR))
18315    (use (match_operand:HI 2 "memory_operand" "m,m"))
18316    (use (match_operand:HI 3 "memory_operand" "m,m"))
18317    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18318   "TARGET_USE_FANCY_MATH_387
18319    && flag_unsafe_math_optimizations"
18320   "#"
18321   [(set_attr "type" "fistp")
18322    (set_attr "i387_cw" "floor")
18323    (set_attr "mode" "<MODE>")])
18325 (define_split
18326   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18327         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18328          UNSPEC_FIST_FLOOR))
18329    (use (match_operand:HI 2 "memory_operand" ""))
18330    (use (match_operand:HI 3 "memory_operand" ""))
18331    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18332   "reload_completed"
18333   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18334                                   UNSPEC_FIST_FLOOR))
18335               (use (match_dup 2))
18336               (use (match_dup 3))])
18337    (set (match_dup 0) (match_dup 4))]
18338   "")
18340 (define_split
18341   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18342         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18343          UNSPEC_FIST_FLOOR))
18344    (use (match_operand:HI 2 "memory_operand" ""))
18345    (use (match_operand:HI 3 "memory_operand" ""))
18346    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18347   "reload_completed"
18348   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18349                                   UNSPEC_FIST_FLOOR))
18350               (use (match_dup 2))
18351               (use (match_dup 3))])]
18352   "")
18354 (define_expand "lfloorxf<mode>2"
18355   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18356                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18357                     UNSPEC_FIST_FLOOR))
18358               (clobber (reg:CC FLAGS_REG))])]
18359   "TARGET_USE_FANCY_MATH_387
18360    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18361    && flag_unsafe_math_optimizations"
18362   "")
18364 (define_expand "lfloor<mode>di2"
18365   [(match_operand:DI 0 "nonimmediate_operand" "")
18366    (match_operand:MODEF 1 "register_operand" "")]
18367   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18368    && !flag_trapping_math"
18370   if (optimize_insn_for_size_p ())
18371     FAIL;
18372   ix86_expand_lfloorceil (operand0, operand1, true);
18373   DONE;
18376 (define_expand "lfloor<mode>si2"
18377   [(match_operand:SI 0 "nonimmediate_operand" "")
18378    (match_operand:MODEF 1 "register_operand" "")]
18379   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18380    && !flag_trapping_math"
18382   if (optimize_insn_for_size_p () && TARGET_64BIT)
18383     FAIL;
18384   ix86_expand_lfloorceil (operand0, operand1, true);
18385   DONE;
18388 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18389 (define_insn_and_split "frndintxf2_ceil"
18390   [(set (match_operand:XF 0 "register_operand" "")
18391         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18392          UNSPEC_FRNDINT_CEIL))
18393    (clobber (reg:CC FLAGS_REG))]
18394   "TARGET_USE_FANCY_MATH_387
18395    && flag_unsafe_math_optimizations
18396    && !(reload_completed || reload_in_progress)"
18397   "#"
18398   "&& 1"
18399   [(const_int 0)]
18401   ix86_optimize_mode_switching[I387_CEIL] = 1;
18403   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18404   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18406   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18407                                        operands[2], operands[3]));
18408   DONE;
18410   [(set_attr "type" "frndint")
18411    (set_attr "i387_cw" "ceil")
18412    (set_attr "mode" "XF")])
18414 (define_insn "frndintxf2_ceil_i387"
18415   [(set (match_operand:XF 0 "register_operand" "=f")
18416         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18417          UNSPEC_FRNDINT_CEIL))
18418    (use (match_operand:HI 2 "memory_operand" "m"))
18419    (use (match_operand:HI 3 "memory_operand" "m"))]
18420   "TARGET_USE_FANCY_MATH_387
18421    && flag_unsafe_math_optimizations"
18422   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18423   [(set_attr "type" "frndint")
18424    (set_attr "i387_cw" "ceil")
18425    (set_attr "mode" "XF")])
18427 (define_expand "ceilxf2"
18428   [(use (match_operand:XF 0 "register_operand" ""))
18429    (use (match_operand:XF 1 "register_operand" ""))]
18430   "TARGET_USE_FANCY_MATH_387
18431    && flag_unsafe_math_optimizations"
18433   if (optimize_insn_for_size_p ())
18434     FAIL;
18435   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18436   DONE;
18439 (define_expand "ceil<mode>2"
18440   [(use (match_operand:MODEF 0 "register_operand" ""))
18441    (use (match_operand:MODEF 1 "register_operand" ""))]
18442   "(TARGET_USE_FANCY_MATH_387
18443     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18444         || TARGET_MIX_SSE_I387)
18445     && flag_unsafe_math_optimizations)
18446    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18447        && !flag_trapping_math)"
18449   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18450       && !flag_trapping_math
18451       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18452     {
18453       if (TARGET_ROUND)
18454         emit_insn (gen_sse4_1_round<mode>2
18455                    (operands[0], operands[1], GEN_INT (0x02)));
18456       else if (optimize_insn_for_size_p ())
18457         FAIL;
18458       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18459         ix86_expand_floorceil (operand0, operand1, false);
18460       else
18461         ix86_expand_floorceildf_32 (operand0, operand1, false);
18462     }
18463   else
18464     {
18465       rtx op0, op1;
18467       if (optimize_insn_for_size_p ())
18468         FAIL;
18470       op0 = gen_reg_rtx (XFmode);
18471       op1 = gen_reg_rtx (XFmode);
18472       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18473       emit_insn (gen_frndintxf2_ceil (op0, op1));
18475       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18476     }
18477   DONE;
18480 (define_insn_and_split "*fist<mode>2_ceil_1"
18481   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18482         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18483          UNSPEC_FIST_CEIL))
18484    (clobber (reg:CC FLAGS_REG))]
18485   "TARGET_USE_FANCY_MATH_387
18486    && flag_unsafe_math_optimizations
18487    && !(reload_completed || reload_in_progress)"
18488   "#"
18489   "&& 1"
18490   [(const_int 0)]
18492   ix86_optimize_mode_switching[I387_CEIL] = 1;
18494   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18495   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18496   if (memory_operand (operands[0], VOIDmode))
18497     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18498                                      operands[2], operands[3]));
18499   else
18500     {
18501       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18502       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18503                                                  operands[2], operands[3],
18504                                                  operands[4]));
18505     }
18506   DONE;
18508   [(set_attr "type" "fistp")
18509    (set_attr "i387_cw" "ceil")
18510    (set_attr "mode" "<MODE>")])
18512 (define_insn "fistdi2_ceil"
18513   [(set (match_operand:DI 0 "memory_operand" "=m")
18514         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18515          UNSPEC_FIST_CEIL))
18516    (use (match_operand:HI 2 "memory_operand" "m"))
18517    (use (match_operand:HI 3 "memory_operand" "m"))
18518    (clobber (match_scratch:XF 4 "=&1f"))]
18519   "TARGET_USE_FANCY_MATH_387
18520    && flag_unsafe_math_optimizations"
18521   "* return output_fix_trunc (insn, operands, 0);"
18522   [(set_attr "type" "fistp")
18523    (set_attr "i387_cw" "ceil")
18524    (set_attr "mode" "DI")])
18526 (define_insn "fistdi2_ceil_with_temp"
18527   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18528         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18529          UNSPEC_FIST_CEIL))
18530    (use (match_operand:HI 2 "memory_operand" "m,m"))
18531    (use (match_operand:HI 3 "memory_operand" "m,m"))
18532    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18533    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18534   "TARGET_USE_FANCY_MATH_387
18535    && flag_unsafe_math_optimizations"
18536   "#"
18537   [(set_attr "type" "fistp")
18538    (set_attr "i387_cw" "ceil")
18539    (set_attr "mode" "DI")])
18541 (define_split
18542   [(set (match_operand:DI 0 "register_operand" "")
18543         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18544          UNSPEC_FIST_CEIL))
18545    (use (match_operand:HI 2 "memory_operand" ""))
18546    (use (match_operand:HI 3 "memory_operand" ""))
18547    (clobber (match_operand:DI 4 "memory_operand" ""))
18548    (clobber (match_scratch 5 ""))]
18549   "reload_completed"
18550   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18551               (use (match_dup 2))
18552               (use (match_dup 3))
18553               (clobber (match_dup 5))])
18554    (set (match_dup 0) (match_dup 4))]
18555   "")
18557 (define_split
18558   [(set (match_operand:DI 0 "memory_operand" "")
18559         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18560          UNSPEC_FIST_CEIL))
18561    (use (match_operand:HI 2 "memory_operand" ""))
18562    (use (match_operand:HI 3 "memory_operand" ""))
18563    (clobber (match_operand:DI 4 "memory_operand" ""))
18564    (clobber (match_scratch 5 ""))]
18565   "reload_completed"
18566   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18567               (use (match_dup 2))
18568               (use (match_dup 3))
18569               (clobber (match_dup 5))])]
18570   "")
18572 (define_insn "fist<mode>2_ceil"
18573   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18574         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18575          UNSPEC_FIST_CEIL))
18576    (use (match_operand:HI 2 "memory_operand" "m"))
18577    (use (match_operand:HI 3 "memory_operand" "m"))]
18578   "TARGET_USE_FANCY_MATH_387
18579    && flag_unsafe_math_optimizations"
18580   "* return output_fix_trunc (insn, operands, 0);"
18581   [(set_attr "type" "fistp")
18582    (set_attr "i387_cw" "ceil")
18583    (set_attr "mode" "<MODE>")])
18585 (define_insn "fist<mode>2_ceil_with_temp"
18586   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18587         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18588          UNSPEC_FIST_CEIL))
18589    (use (match_operand:HI 2 "memory_operand" "m,m"))
18590    (use (match_operand:HI 3 "memory_operand" "m,m"))
18591    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18592   "TARGET_USE_FANCY_MATH_387
18593    && flag_unsafe_math_optimizations"
18594   "#"
18595   [(set_attr "type" "fistp")
18596    (set_attr "i387_cw" "ceil")
18597    (set_attr "mode" "<MODE>")])
18599 (define_split
18600   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18601         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18602          UNSPEC_FIST_CEIL))
18603    (use (match_operand:HI 2 "memory_operand" ""))
18604    (use (match_operand:HI 3 "memory_operand" ""))
18605    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18606   "reload_completed"
18607   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18608                                   UNSPEC_FIST_CEIL))
18609               (use (match_dup 2))
18610               (use (match_dup 3))])
18611    (set (match_dup 0) (match_dup 4))]
18612   "")
18614 (define_split
18615   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18616         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18617          UNSPEC_FIST_CEIL))
18618    (use (match_operand:HI 2 "memory_operand" ""))
18619    (use (match_operand:HI 3 "memory_operand" ""))
18620    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18621   "reload_completed"
18622   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18623                                   UNSPEC_FIST_CEIL))
18624               (use (match_dup 2))
18625               (use (match_dup 3))])]
18626   "")
18628 (define_expand "lceilxf<mode>2"
18629   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18630                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18631                     UNSPEC_FIST_CEIL))
18632               (clobber (reg:CC FLAGS_REG))])]
18633   "TARGET_USE_FANCY_MATH_387
18634    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18635    && flag_unsafe_math_optimizations"
18636   "")
18638 (define_expand "lceil<mode>di2"
18639   [(match_operand:DI 0 "nonimmediate_operand" "")
18640    (match_operand:MODEF 1 "register_operand" "")]
18641   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18642    && !flag_trapping_math"
18644   ix86_expand_lfloorceil (operand0, operand1, false);
18645   DONE;
18648 (define_expand "lceil<mode>si2"
18649   [(match_operand:SI 0 "nonimmediate_operand" "")
18650    (match_operand:MODEF 1 "register_operand" "")]
18651   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18652    && !flag_trapping_math"
18654   ix86_expand_lfloorceil (operand0, operand1, false);
18655   DONE;
18658 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18659 (define_insn_and_split "frndintxf2_trunc"
18660   [(set (match_operand:XF 0 "register_operand" "")
18661         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18662          UNSPEC_FRNDINT_TRUNC))
18663    (clobber (reg:CC FLAGS_REG))]
18664   "TARGET_USE_FANCY_MATH_387
18665    && flag_unsafe_math_optimizations
18666    && !(reload_completed || reload_in_progress)"
18667   "#"
18668   "&& 1"
18669   [(const_int 0)]
18671   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18673   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18674   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18676   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18677                                         operands[2], operands[3]));
18678   DONE;
18680   [(set_attr "type" "frndint")
18681    (set_attr "i387_cw" "trunc")
18682    (set_attr "mode" "XF")])
18684 (define_insn "frndintxf2_trunc_i387"
18685   [(set (match_operand:XF 0 "register_operand" "=f")
18686         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18687          UNSPEC_FRNDINT_TRUNC))
18688    (use (match_operand:HI 2 "memory_operand" "m"))
18689    (use (match_operand:HI 3 "memory_operand" "m"))]
18690   "TARGET_USE_FANCY_MATH_387
18691    && flag_unsafe_math_optimizations"
18692   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18693   [(set_attr "type" "frndint")
18694    (set_attr "i387_cw" "trunc")
18695    (set_attr "mode" "XF")])
18697 (define_expand "btruncxf2"
18698   [(use (match_operand:XF 0 "register_operand" ""))
18699    (use (match_operand:XF 1 "register_operand" ""))]
18700   "TARGET_USE_FANCY_MATH_387
18701    && flag_unsafe_math_optimizations"
18703   if (optimize_insn_for_size_p ())
18704     FAIL;
18705   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18706   DONE;
18709 (define_expand "btrunc<mode>2"
18710   [(use (match_operand:MODEF 0 "register_operand" ""))
18711    (use (match_operand:MODEF 1 "register_operand" ""))]
18712   "(TARGET_USE_FANCY_MATH_387
18713     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18714         || TARGET_MIX_SSE_I387)
18715     && flag_unsafe_math_optimizations)
18716    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18717        && !flag_trapping_math)"
18719   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18720       && !flag_trapping_math
18721       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18722     {
18723       if (TARGET_ROUND)
18724         emit_insn (gen_sse4_1_round<mode>2
18725                    (operands[0], operands[1], GEN_INT (0x03)));
18726       else if (optimize_insn_for_size_p ())
18727         FAIL;
18728       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18729         ix86_expand_trunc (operand0, operand1);
18730       else
18731         ix86_expand_truncdf_32 (operand0, operand1);
18732     }
18733   else
18734     {
18735       rtx op0, op1;
18737       if (optimize_insn_for_size_p ())
18738         FAIL;
18740       op0 = gen_reg_rtx (XFmode);
18741       op1 = gen_reg_rtx (XFmode);
18742       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18743       emit_insn (gen_frndintxf2_trunc (op0, op1));
18745       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18746     }
18747   DONE;
18750 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18751 (define_insn_and_split "frndintxf2_mask_pm"
18752   [(set (match_operand:XF 0 "register_operand" "")
18753         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18754          UNSPEC_FRNDINT_MASK_PM))
18755    (clobber (reg:CC FLAGS_REG))]
18756   "TARGET_USE_FANCY_MATH_387
18757    && flag_unsafe_math_optimizations
18758    && !(reload_completed || reload_in_progress)"
18759   "#"
18760   "&& 1"
18761   [(const_int 0)]
18763   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18765   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18766   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18768   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18769                                           operands[2], operands[3]));
18770   DONE;
18772   [(set_attr "type" "frndint")
18773    (set_attr "i387_cw" "mask_pm")
18774    (set_attr "mode" "XF")])
18776 (define_insn "frndintxf2_mask_pm_i387"
18777   [(set (match_operand:XF 0 "register_operand" "=f")
18778         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18779          UNSPEC_FRNDINT_MASK_PM))
18780    (use (match_operand:HI 2 "memory_operand" "m"))
18781    (use (match_operand:HI 3 "memory_operand" "m"))]
18782   "TARGET_USE_FANCY_MATH_387
18783    && flag_unsafe_math_optimizations"
18784   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18785   [(set_attr "type" "frndint")
18786    (set_attr "i387_cw" "mask_pm")
18787    (set_attr "mode" "XF")])
18789 (define_expand "nearbyintxf2"
18790   [(use (match_operand:XF 0 "register_operand" ""))
18791    (use (match_operand:XF 1 "register_operand" ""))]
18792   "TARGET_USE_FANCY_MATH_387
18793    && flag_unsafe_math_optimizations"
18795   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18797   DONE;
18800 (define_expand "nearbyint<mode>2"
18801   [(use (match_operand:MODEF 0 "register_operand" ""))
18802    (use (match_operand:MODEF 1 "register_operand" ""))]
18803   "TARGET_USE_FANCY_MATH_387
18804    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18805        || TARGET_MIX_SSE_I387)
18806    && flag_unsafe_math_optimizations"
18808   rtx op0 = gen_reg_rtx (XFmode);
18809   rtx op1 = gen_reg_rtx (XFmode);
18811   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18812   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18814   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18815   DONE;
18818 (define_insn "fxam<mode>2_i387"
18819   [(set (match_operand:HI 0 "register_operand" "=a")
18820         (unspec:HI
18821           [(match_operand:X87MODEF 1 "register_operand" "f")]
18822           UNSPEC_FXAM))]
18823   "TARGET_USE_FANCY_MATH_387"
18824   "fxam\n\tfnstsw\t%0"
18825   [(set_attr "type" "multi")
18826    (set_attr "unit" "i387")
18827    (set_attr "mode" "<MODE>")])
18829 (define_insn_and_split "fxam<mode>2_i387_with_temp"
18830   [(set (match_operand:HI 0 "register_operand" "")
18831         (unspec:HI
18832           [(match_operand:MODEF 1 "memory_operand" "")]
18833           UNSPEC_FXAM_MEM))]
18834   "TARGET_USE_FANCY_MATH_387
18835    && !(reload_completed || reload_in_progress)"
18836   "#"
18837   "&& 1"
18838   [(set (match_dup 2)(match_dup 1))
18839    (set (match_dup 0)
18840         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
18842   operands[2] = gen_reg_rtx (<MODE>mode);
18844   MEM_VOLATILE_P (operands[1]) = 1;
18846   [(set_attr "type" "multi")
18847    (set_attr "unit" "i387")
18848    (set_attr "mode" "<MODE>")])
18850 (define_expand "isinfxf2"
18851   [(use (match_operand:SI 0 "register_operand" ""))
18852    (use (match_operand:XF 1 "register_operand" ""))]
18853   "TARGET_USE_FANCY_MATH_387
18854    && TARGET_C99_FUNCTIONS"
18856   rtx mask = GEN_INT (0x45);
18857   rtx val = GEN_INT (0x05);
18859   rtx cond;
18861   rtx scratch = gen_reg_rtx (HImode);
18862   rtx res = gen_reg_rtx (QImode);
18864   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
18866   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18867   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18868   cond = gen_rtx_fmt_ee (EQ, QImode,
18869                          gen_rtx_REG (CCmode, FLAGS_REG),
18870                          const0_rtx);
18871   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18872   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18873   DONE;
18876 (define_expand "isinf<mode>2"
18877   [(use (match_operand:SI 0 "register_operand" ""))
18878    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
18879   "TARGET_USE_FANCY_MATH_387
18880    && TARGET_C99_FUNCTIONS
18881    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18883   rtx mask = GEN_INT (0x45);
18884   rtx val = GEN_INT (0x05);
18886   rtx cond;
18888   rtx scratch = gen_reg_rtx (HImode);
18889   rtx res = gen_reg_rtx (QImode);
18891   /* Remove excess precision by forcing value through memory. */
18892   if (memory_operand (operands[1], VOIDmode))
18893     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
18894   else
18895     {
18896       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
18897       rtx temp = assign_386_stack_local (<MODE>mode, slot);
18899       emit_move_insn (temp, operands[1]);
18900       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
18901     }
18903   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18904   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18905   cond = gen_rtx_fmt_ee (EQ, QImode,
18906                          gen_rtx_REG (CCmode, FLAGS_REG),
18907                          const0_rtx);
18908   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18909   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18910   DONE;
18913 (define_expand "signbit<mode>2"
18914   [(use (match_operand:SI 0 "register_operand" ""))
18915    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18916   "TARGET_USE_FANCY_MATH_387
18917    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18919   rtx mask = GEN_INT (0x0200);
18921   rtx scratch = gen_reg_rtx (HImode);
18923   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18924   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18925   DONE;
18928 ;; Block operation instructions
18930 (define_insn "cld"
18931   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18932   ""
18933   "cld"
18934   [(set_attr "length" "1")
18935    (set_attr "length_immediate" "0")
18936    (set_attr "modrm" "0")])
18938 (define_expand "movmemsi"
18939   [(use (match_operand:BLK 0 "memory_operand" ""))
18940    (use (match_operand:BLK 1 "memory_operand" ""))
18941    (use (match_operand:SI 2 "nonmemory_operand" ""))
18942    (use (match_operand:SI 3 "const_int_operand" ""))
18943    (use (match_operand:SI 4 "const_int_operand" ""))
18944    (use (match_operand:SI 5 "const_int_operand" ""))]
18945   ""
18947  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18948                          operands[4], operands[5]))
18949    DONE;
18950  else
18951    FAIL;
18954 (define_expand "movmemdi"
18955   [(use (match_operand:BLK 0 "memory_operand" ""))
18956    (use (match_operand:BLK 1 "memory_operand" ""))
18957    (use (match_operand:DI 2 "nonmemory_operand" ""))
18958    (use (match_operand:DI 3 "const_int_operand" ""))
18959    (use (match_operand:SI 4 "const_int_operand" ""))
18960    (use (match_operand:SI 5 "const_int_operand" ""))]
18961   "TARGET_64BIT"
18963  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18964                          operands[4], operands[5]))
18965    DONE;
18966  else
18967    FAIL;
18970 ;; Most CPUs don't like single string operations
18971 ;; Handle this case here to simplify previous expander.
18973 (define_expand "strmov"
18974   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18975    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18976    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18977               (clobber (reg:CC FLAGS_REG))])
18978    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18979               (clobber (reg:CC FLAGS_REG))])]
18980   ""
18982   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18984   /* If .md ever supports :P for Pmode, these can be directly
18985      in the pattern above.  */
18986   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18987   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18989   /* Can't use this if the user has appropriated esi or edi.  */
18990   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18991       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18992     {
18993       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18994                                       operands[2], operands[3],
18995                                       operands[5], operands[6]));
18996       DONE;
18997     }
18999   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
19002 (define_expand "strmov_singleop"
19003   [(parallel [(set (match_operand 1 "memory_operand" "")
19004                    (match_operand 3 "memory_operand" ""))
19005               (set (match_operand 0 "register_operand" "")
19006                    (match_operand 4 "" ""))
19007               (set (match_operand 2 "register_operand" "")
19008                    (match_operand 5 "" ""))])]
19009   ""
19010   "ix86_current_function_needs_cld = 1;")
19012 (define_insn "*strmovdi_rex_1"
19013   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
19014         (mem:DI (match_operand:DI 3 "register_operand" "1")))
19015    (set (match_operand:DI 0 "register_operand" "=D")
19016         (plus:DI (match_dup 2)
19017                  (const_int 8)))
19018    (set (match_operand:DI 1 "register_operand" "=S")
19019         (plus:DI (match_dup 3)
19020                  (const_int 8)))]
19021   "TARGET_64BIT"
19022   "movsq"
19023   [(set_attr "type" "str")
19024    (set_attr "mode" "DI")
19025    (set_attr "memory" "both")])
19027 (define_insn "*strmovsi_1"
19028   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
19029         (mem:SI (match_operand:SI 3 "register_operand" "1")))
19030    (set (match_operand:SI 0 "register_operand" "=D")
19031         (plus:SI (match_dup 2)
19032                  (const_int 4)))
19033    (set (match_operand:SI 1 "register_operand" "=S")
19034         (plus:SI (match_dup 3)
19035                  (const_int 4)))]
19036   "!TARGET_64BIT"
19037   "movs{l|d}"
19038   [(set_attr "type" "str")
19039    (set_attr "mode" "SI")
19040    (set_attr "memory" "both")])
19042 (define_insn "*strmovsi_rex_1"
19043   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
19044         (mem:SI (match_operand:DI 3 "register_operand" "1")))
19045    (set (match_operand:DI 0 "register_operand" "=D")
19046         (plus:DI (match_dup 2)
19047                  (const_int 4)))
19048    (set (match_operand:DI 1 "register_operand" "=S")
19049         (plus:DI (match_dup 3)
19050                  (const_int 4)))]
19051   "TARGET_64BIT"
19052   "movs{l|d}"
19053   [(set_attr "type" "str")
19054    (set_attr "mode" "SI")
19055    (set_attr "memory" "both")])
19057 (define_insn "*strmovhi_1"
19058   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
19059         (mem:HI (match_operand:SI 3 "register_operand" "1")))
19060    (set (match_operand:SI 0 "register_operand" "=D")
19061         (plus:SI (match_dup 2)
19062                  (const_int 2)))
19063    (set (match_operand:SI 1 "register_operand" "=S")
19064         (plus:SI (match_dup 3)
19065                  (const_int 2)))]
19066   "!TARGET_64BIT"
19067   "movsw"
19068   [(set_attr "type" "str")
19069    (set_attr "memory" "both")
19070    (set_attr "mode" "HI")])
19072 (define_insn "*strmovhi_rex_1"
19073   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
19074         (mem:HI (match_operand:DI 3 "register_operand" "1")))
19075    (set (match_operand:DI 0 "register_operand" "=D")
19076         (plus:DI (match_dup 2)
19077                  (const_int 2)))
19078    (set (match_operand:DI 1 "register_operand" "=S")
19079         (plus:DI (match_dup 3)
19080                  (const_int 2)))]
19081   "TARGET_64BIT"
19082   "movsw"
19083   [(set_attr "type" "str")
19084    (set_attr "memory" "both")
19085    (set_attr "mode" "HI")])
19087 (define_insn "*strmovqi_1"
19088   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
19089         (mem:QI (match_operand:SI 3 "register_operand" "1")))
19090    (set (match_operand:SI 0 "register_operand" "=D")
19091         (plus:SI (match_dup 2)
19092                  (const_int 1)))
19093    (set (match_operand:SI 1 "register_operand" "=S")
19094         (plus:SI (match_dup 3)
19095                  (const_int 1)))]
19096   "!TARGET_64BIT"
19097   "movsb"
19098   [(set_attr "type" "str")
19099    (set_attr "memory" "both")
19100    (set_attr "mode" "QI")])
19102 (define_insn "*strmovqi_rex_1"
19103   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19104         (mem:QI (match_operand:DI 3 "register_operand" "1")))
19105    (set (match_operand:DI 0 "register_operand" "=D")
19106         (plus:DI (match_dup 2)
19107                  (const_int 1)))
19108    (set (match_operand:DI 1 "register_operand" "=S")
19109         (plus:DI (match_dup 3)
19110                  (const_int 1)))]
19111   "TARGET_64BIT"
19112   "movsb"
19113   [(set_attr "type" "str")
19114    (set_attr "memory" "both")
19115    (set_attr "mode" "QI")])
19117 (define_expand "rep_mov"
19118   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19119               (set (match_operand 0 "register_operand" "")
19120                    (match_operand 5 "" ""))
19121               (set (match_operand 2 "register_operand" "")
19122                    (match_operand 6 "" ""))
19123               (set (match_operand 1 "memory_operand" "")
19124                    (match_operand 3 "memory_operand" ""))
19125               (use (match_dup 4))])]
19126   ""
19127   "ix86_current_function_needs_cld = 1;")
19129 (define_insn "*rep_movdi_rex64"
19130   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19131    (set (match_operand:DI 0 "register_operand" "=D")
19132         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19133                             (const_int 3))
19134                  (match_operand:DI 3 "register_operand" "0")))
19135    (set (match_operand:DI 1 "register_operand" "=S")
19136         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19137                  (match_operand:DI 4 "register_operand" "1")))
19138    (set (mem:BLK (match_dup 3))
19139         (mem:BLK (match_dup 4)))
19140    (use (match_dup 5))]
19141   "TARGET_64BIT"
19142   "rep movsq"
19143   [(set_attr "type" "str")
19144    (set_attr "prefix_rep" "1")
19145    (set_attr "memory" "both")
19146    (set_attr "mode" "DI")])
19148 (define_insn "*rep_movsi"
19149   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19150    (set (match_operand:SI 0 "register_operand" "=D")
19151         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19152                             (const_int 2))
19153                  (match_operand:SI 3 "register_operand" "0")))
19154    (set (match_operand:SI 1 "register_operand" "=S")
19155         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19156                  (match_operand:SI 4 "register_operand" "1")))
19157    (set (mem:BLK (match_dup 3))
19158         (mem:BLK (match_dup 4)))
19159    (use (match_dup 5))]
19160   "!TARGET_64BIT"
19161   "rep movs{l|d}"
19162   [(set_attr "type" "str")
19163    (set_attr "prefix_rep" "1")
19164    (set_attr "memory" "both")
19165    (set_attr "mode" "SI")])
19167 (define_insn "*rep_movsi_rex64"
19168   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19169    (set (match_operand:DI 0 "register_operand" "=D")
19170         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19171                             (const_int 2))
19172                  (match_operand:DI 3 "register_operand" "0")))
19173    (set (match_operand:DI 1 "register_operand" "=S")
19174         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19175                  (match_operand:DI 4 "register_operand" "1")))
19176    (set (mem:BLK (match_dup 3))
19177         (mem:BLK (match_dup 4)))
19178    (use (match_dup 5))]
19179   "TARGET_64BIT"
19180   "rep movs{l|d}"
19181   [(set_attr "type" "str")
19182    (set_attr "prefix_rep" "1")
19183    (set_attr "memory" "both")
19184    (set_attr "mode" "SI")])
19186 (define_insn "*rep_movqi"
19187   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19188    (set (match_operand:SI 0 "register_operand" "=D")
19189         (plus:SI (match_operand:SI 3 "register_operand" "0")
19190                  (match_operand:SI 5 "register_operand" "2")))
19191    (set (match_operand:SI 1 "register_operand" "=S")
19192         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19193    (set (mem:BLK (match_dup 3))
19194         (mem:BLK (match_dup 4)))
19195    (use (match_dup 5))]
19196   "!TARGET_64BIT"
19197   "rep movsb"
19198   [(set_attr "type" "str")
19199    (set_attr "prefix_rep" "1")
19200    (set_attr "memory" "both")
19201    (set_attr "mode" "SI")])
19203 (define_insn "*rep_movqi_rex64"
19204   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19205    (set (match_operand:DI 0 "register_operand" "=D")
19206         (plus:DI (match_operand:DI 3 "register_operand" "0")
19207                  (match_operand:DI 5 "register_operand" "2")))
19208    (set (match_operand:DI 1 "register_operand" "=S")
19209         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19210    (set (mem:BLK (match_dup 3))
19211         (mem:BLK (match_dup 4)))
19212    (use (match_dup 5))]
19213   "TARGET_64BIT"
19214   "rep movsb"
19215   [(set_attr "type" "str")
19216    (set_attr "prefix_rep" "1")
19217    (set_attr "memory" "both")
19218    (set_attr "mode" "SI")])
19220 (define_expand "setmemsi"
19221    [(use (match_operand:BLK 0 "memory_operand" ""))
19222     (use (match_operand:SI 1 "nonmemory_operand" ""))
19223     (use (match_operand 2 "const_int_operand" ""))
19224     (use (match_operand 3 "const_int_operand" ""))
19225     (use (match_operand:SI 4 "const_int_operand" ""))
19226     (use (match_operand:SI 5 "const_int_operand" ""))]
19227   ""
19229  if (ix86_expand_setmem (operands[0], operands[1],
19230                          operands[2], operands[3],
19231                          operands[4], operands[5]))
19232    DONE;
19233  else
19234    FAIL;
19237 (define_expand "setmemdi"
19238    [(use (match_operand:BLK 0 "memory_operand" ""))
19239     (use (match_operand:DI 1 "nonmemory_operand" ""))
19240     (use (match_operand 2 "const_int_operand" ""))
19241     (use (match_operand 3 "const_int_operand" ""))
19242     (use (match_operand 4 "const_int_operand" ""))
19243     (use (match_operand 5 "const_int_operand" ""))]
19244   "TARGET_64BIT"
19246  if (ix86_expand_setmem (operands[0], operands[1],
19247                          operands[2], operands[3],
19248                          operands[4], operands[5]))
19249    DONE;
19250  else
19251    FAIL;
19254 ;; Most CPUs don't like single string operations
19255 ;; Handle this case here to simplify previous expander.
19257 (define_expand "strset"
19258   [(set (match_operand 1 "memory_operand" "")
19259         (match_operand 2 "register_operand" ""))
19260    (parallel [(set (match_operand 0 "register_operand" "")
19261                    (match_dup 3))
19262               (clobber (reg:CC FLAGS_REG))])]
19263   ""
19265   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19266     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19268   /* If .md ever supports :P for Pmode, this can be directly
19269      in the pattern above.  */
19270   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19271                               GEN_INT (GET_MODE_SIZE (GET_MODE
19272                                                       (operands[2]))));
19273   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19274     {
19275       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19276                                       operands[3]));
19277       DONE;
19278     }
19281 (define_expand "strset_singleop"
19282   [(parallel [(set (match_operand 1 "memory_operand" "")
19283                    (match_operand 2 "register_operand" ""))
19284               (set (match_operand 0 "register_operand" "")
19285                    (match_operand 3 "" ""))])]
19286   ""
19287   "ix86_current_function_needs_cld = 1;")
19289 (define_insn "*strsetdi_rex_1"
19290   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19291         (match_operand:DI 2 "register_operand" "a"))
19292    (set (match_operand:DI 0 "register_operand" "=D")
19293         (plus:DI (match_dup 1)
19294                  (const_int 8)))]
19295   "TARGET_64BIT"
19296   "stosq"
19297   [(set_attr "type" "str")
19298    (set_attr "memory" "store")
19299    (set_attr "mode" "DI")])
19301 (define_insn "*strsetsi_1"
19302   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19303         (match_operand:SI 2 "register_operand" "a"))
19304    (set (match_operand:SI 0 "register_operand" "=D")
19305         (plus:SI (match_dup 1)
19306                  (const_int 4)))]
19307   "!TARGET_64BIT"
19308   "stos{l|d}"
19309   [(set_attr "type" "str")
19310    (set_attr "memory" "store")
19311    (set_attr "mode" "SI")])
19313 (define_insn "*strsetsi_rex_1"
19314   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19315         (match_operand:SI 2 "register_operand" "a"))
19316    (set (match_operand:DI 0 "register_operand" "=D")
19317         (plus:DI (match_dup 1)
19318                  (const_int 4)))]
19319   "TARGET_64BIT"
19320   "stos{l|d}"
19321   [(set_attr "type" "str")
19322    (set_attr "memory" "store")
19323    (set_attr "mode" "SI")])
19325 (define_insn "*strsethi_1"
19326   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19327         (match_operand:HI 2 "register_operand" "a"))
19328    (set (match_operand:SI 0 "register_operand" "=D")
19329         (plus:SI (match_dup 1)
19330                  (const_int 2)))]
19331   "!TARGET_64BIT"
19332   "stosw"
19333   [(set_attr "type" "str")
19334    (set_attr "memory" "store")
19335    (set_attr "mode" "HI")])
19337 (define_insn "*strsethi_rex_1"
19338   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19339         (match_operand:HI 2 "register_operand" "a"))
19340    (set (match_operand:DI 0 "register_operand" "=D")
19341         (plus:DI (match_dup 1)
19342                  (const_int 2)))]
19343   "TARGET_64BIT"
19344   "stosw"
19345   [(set_attr "type" "str")
19346    (set_attr "memory" "store")
19347    (set_attr "mode" "HI")])
19349 (define_insn "*strsetqi_1"
19350   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19351         (match_operand:QI 2 "register_operand" "a"))
19352    (set (match_operand:SI 0 "register_operand" "=D")
19353         (plus:SI (match_dup 1)
19354                  (const_int 1)))]
19355   "!TARGET_64BIT"
19356   "stosb"
19357   [(set_attr "type" "str")
19358    (set_attr "memory" "store")
19359    (set_attr "mode" "QI")])
19361 (define_insn "*strsetqi_rex_1"
19362   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19363         (match_operand:QI 2 "register_operand" "a"))
19364    (set (match_operand:DI 0 "register_operand" "=D")
19365         (plus:DI (match_dup 1)
19366                  (const_int 1)))]
19367   "TARGET_64BIT"
19368   "stosb"
19369   [(set_attr "type" "str")
19370    (set_attr "memory" "store")
19371    (set_attr "mode" "QI")])
19373 (define_expand "rep_stos"
19374   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19375               (set (match_operand 0 "register_operand" "")
19376                    (match_operand 4 "" ""))
19377               (set (match_operand 2 "memory_operand" "") (const_int 0))
19378               (use (match_operand 3 "register_operand" ""))
19379               (use (match_dup 1))])]
19380   ""
19381   "ix86_current_function_needs_cld = 1;")
19383 (define_insn "*rep_stosdi_rex64"
19384   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19385    (set (match_operand:DI 0 "register_operand" "=D")
19386         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19387                             (const_int 3))
19388                  (match_operand:DI 3 "register_operand" "0")))
19389    (set (mem:BLK (match_dup 3))
19390         (const_int 0))
19391    (use (match_operand:DI 2 "register_operand" "a"))
19392    (use (match_dup 4))]
19393   "TARGET_64BIT"
19394   "rep stosq"
19395   [(set_attr "type" "str")
19396    (set_attr "prefix_rep" "1")
19397    (set_attr "memory" "store")
19398    (set_attr "mode" "DI")])
19400 (define_insn "*rep_stossi"
19401   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19402    (set (match_operand:SI 0 "register_operand" "=D")
19403         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19404                             (const_int 2))
19405                  (match_operand:SI 3 "register_operand" "0")))
19406    (set (mem:BLK (match_dup 3))
19407         (const_int 0))
19408    (use (match_operand:SI 2 "register_operand" "a"))
19409    (use (match_dup 4))]
19410   "!TARGET_64BIT"
19411   "rep stos{l|d}"
19412   [(set_attr "type" "str")
19413    (set_attr "prefix_rep" "1")
19414    (set_attr "memory" "store")
19415    (set_attr "mode" "SI")])
19417 (define_insn "*rep_stossi_rex64"
19418   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19419    (set (match_operand:DI 0 "register_operand" "=D")
19420         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19421                             (const_int 2))
19422                  (match_operand:DI 3 "register_operand" "0")))
19423    (set (mem:BLK (match_dup 3))
19424         (const_int 0))
19425    (use (match_operand:SI 2 "register_operand" "a"))
19426    (use (match_dup 4))]
19427   "TARGET_64BIT"
19428   "rep stos{l|d}"
19429   [(set_attr "type" "str")
19430    (set_attr "prefix_rep" "1")
19431    (set_attr "memory" "store")
19432    (set_attr "mode" "SI")])
19434 (define_insn "*rep_stosqi"
19435   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19436    (set (match_operand:SI 0 "register_operand" "=D")
19437         (plus:SI (match_operand:SI 3 "register_operand" "0")
19438                  (match_operand:SI 4 "register_operand" "1")))
19439    (set (mem:BLK (match_dup 3))
19440         (const_int 0))
19441    (use (match_operand:QI 2 "register_operand" "a"))
19442    (use (match_dup 4))]
19443   "!TARGET_64BIT"
19444   "rep stosb"
19445   [(set_attr "type" "str")
19446    (set_attr "prefix_rep" "1")
19447    (set_attr "memory" "store")
19448    (set_attr "mode" "QI")])
19450 (define_insn "*rep_stosqi_rex64"
19451   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19452    (set (match_operand:DI 0 "register_operand" "=D")
19453         (plus:DI (match_operand:DI 3 "register_operand" "0")
19454                  (match_operand:DI 4 "register_operand" "1")))
19455    (set (mem:BLK (match_dup 3))
19456         (const_int 0))
19457    (use (match_operand:QI 2 "register_operand" "a"))
19458    (use (match_dup 4))]
19459   "TARGET_64BIT"
19460   "rep stosb"
19461   [(set_attr "type" "str")
19462    (set_attr "prefix_rep" "1")
19463    (set_attr "memory" "store")
19464    (set_attr "mode" "QI")])
19466 (define_expand "cmpstrnsi"
19467   [(set (match_operand:SI 0 "register_operand" "")
19468         (compare:SI (match_operand:BLK 1 "general_operand" "")
19469                     (match_operand:BLK 2 "general_operand" "")))
19470    (use (match_operand 3 "general_operand" ""))
19471    (use (match_operand 4 "immediate_operand" ""))]
19472   ""
19474   rtx addr1, addr2, out, outlow, count, countreg, align;
19476   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
19477     FAIL;
19479   /* Can't use this if the user has appropriated esi or edi.  */
19480   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19481     FAIL;
19483   out = operands[0];
19484   if (!REG_P (out))
19485     out = gen_reg_rtx (SImode);
19487   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19488   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19489   if (addr1 != XEXP (operands[1], 0))
19490     operands[1] = replace_equiv_address_nv (operands[1], addr1);
19491   if (addr2 != XEXP (operands[2], 0))
19492     operands[2] = replace_equiv_address_nv (operands[2], addr2);
19494   count = operands[3];
19495   countreg = ix86_zero_extend_to_Pmode (count);
19497   /* %%% Iff we are testing strict equality, we can use known alignment
19498      to good advantage.  This may be possible with combine, particularly
19499      once cc0 is dead.  */
19500   align = operands[4];
19502   if (CONST_INT_P (count))
19503     {
19504       if (INTVAL (count) == 0)
19505         {
19506           emit_move_insn (operands[0], const0_rtx);
19507           DONE;
19508         }
19509       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19510                                      operands[1], operands[2]));
19511     }
19512   else
19513     {
19514       if (TARGET_64BIT)
19515         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19516       else
19517         emit_insn (gen_cmpsi_1 (countreg, countreg));
19518       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19519                                   operands[1], operands[2]));
19520     }
19522   outlow = gen_lowpart (QImode, out);
19523   emit_insn (gen_cmpintqi (outlow));
19524   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19526   if (operands[0] != out)
19527     emit_move_insn (operands[0], out);
19529   DONE;
19532 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19534 (define_expand "cmpintqi"
19535   [(set (match_dup 1)
19536         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19537    (set (match_dup 2)
19538         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19539    (parallel [(set (match_operand:QI 0 "register_operand" "")
19540                    (minus:QI (match_dup 1)
19541                              (match_dup 2)))
19542               (clobber (reg:CC FLAGS_REG))])]
19543   ""
19544   "operands[1] = gen_reg_rtx (QImode);
19545    operands[2] = gen_reg_rtx (QImode);")
19547 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
19548 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
19550 (define_expand "cmpstrnqi_nz_1"
19551   [(parallel [(set (reg:CC FLAGS_REG)
19552                    (compare:CC (match_operand 4 "memory_operand" "")
19553                                (match_operand 5 "memory_operand" "")))
19554               (use (match_operand 2 "register_operand" ""))
19555               (use (match_operand:SI 3 "immediate_operand" ""))
19556               (clobber (match_operand 0 "register_operand" ""))
19557               (clobber (match_operand 1 "register_operand" ""))
19558               (clobber (match_dup 2))])]
19559   ""
19560   "ix86_current_function_needs_cld = 1;")
19562 (define_insn "*cmpstrnqi_nz_1"
19563   [(set (reg:CC FLAGS_REG)
19564         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19565                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19566    (use (match_operand:SI 6 "register_operand" "2"))
19567    (use (match_operand:SI 3 "immediate_operand" "i"))
19568    (clobber (match_operand:SI 0 "register_operand" "=S"))
19569    (clobber (match_operand:SI 1 "register_operand" "=D"))
19570    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19571   "!TARGET_64BIT"
19572   "repz cmpsb"
19573   [(set_attr "type" "str")
19574    (set_attr "mode" "QI")
19575    (set_attr "prefix_rep" "1")])
19577 (define_insn "*cmpstrnqi_nz_rex_1"
19578   [(set (reg:CC FLAGS_REG)
19579         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19580                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19581    (use (match_operand:DI 6 "register_operand" "2"))
19582    (use (match_operand:SI 3 "immediate_operand" "i"))
19583    (clobber (match_operand:DI 0 "register_operand" "=S"))
19584    (clobber (match_operand:DI 1 "register_operand" "=D"))
19585    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19586   "TARGET_64BIT"
19587   "repz cmpsb"
19588   [(set_attr "type" "str")
19589    (set_attr "mode" "QI")
19590    (set_attr "prefix_rep" "1")])
19592 ;; The same, but the count is not known to not be zero.
19594 (define_expand "cmpstrnqi_1"
19595   [(parallel [(set (reg:CC FLAGS_REG)
19596                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19597                                      (const_int 0))
19598                   (compare:CC (match_operand 4 "memory_operand" "")
19599                               (match_operand 5 "memory_operand" ""))
19600                   (const_int 0)))
19601               (use (match_operand:SI 3 "immediate_operand" ""))
19602               (use (reg:CC FLAGS_REG))
19603               (clobber (match_operand 0 "register_operand" ""))
19604               (clobber (match_operand 1 "register_operand" ""))
19605               (clobber (match_dup 2))])]
19606   ""
19607   "ix86_current_function_needs_cld = 1;")
19609 (define_insn "*cmpstrnqi_1"
19610   [(set (reg:CC FLAGS_REG)
19611         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19612                              (const_int 0))
19613           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19614                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19615           (const_int 0)))
19616    (use (match_operand:SI 3 "immediate_operand" "i"))
19617    (use (reg:CC FLAGS_REG))
19618    (clobber (match_operand:SI 0 "register_operand" "=S"))
19619    (clobber (match_operand:SI 1 "register_operand" "=D"))
19620    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19621   "!TARGET_64BIT"
19622   "repz cmpsb"
19623   [(set_attr "type" "str")
19624    (set_attr "mode" "QI")
19625    (set_attr "prefix_rep" "1")])
19627 (define_insn "*cmpstrnqi_rex_1"
19628   [(set (reg:CC FLAGS_REG)
19629         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19630                              (const_int 0))
19631           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19632                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19633           (const_int 0)))
19634    (use (match_operand:SI 3 "immediate_operand" "i"))
19635    (use (reg:CC FLAGS_REG))
19636    (clobber (match_operand:DI 0 "register_operand" "=S"))
19637    (clobber (match_operand:DI 1 "register_operand" "=D"))
19638    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19639   "TARGET_64BIT"
19640   "repz cmpsb"
19641   [(set_attr "type" "str")
19642    (set_attr "mode" "QI")
19643    (set_attr "prefix_rep" "1")])
19645 (define_expand "strlensi"
19646   [(set (match_operand:SI 0 "register_operand" "")
19647         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19648                     (match_operand:QI 2 "immediate_operand" "")
19649                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19650   ""
19652  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19653    DONE;
19654  else
19655    FAIL;
19658 (define_expand "strlendi"
19659   [(set (match_operand:DI 0 "register_operand" "")
19660         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19661                     (match_operand:QI 2 "immediate_operand" "")
19662                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19663   ""
19665  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19666    DONE;
19667  else
19668    FAIL;
19671 (define_expand "strlenqi_1"
19672   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19673               (clobber (match_operand 1 "register_operand" ""))
19674               (clobber (reg:CC FLAGS_REG))])]
19675   ""
19676   "ix86_current_function_needs_cld = 1;")
19678 (define_insn "*strlenqi_1"
19679   [(set (match_operand:SI 0 "register_operand" "=&c")
19680         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19681                     (match_operand:QI 2 "register_operand" "a")
19682                     (match_operand:SI 3 "immediate_operand" "i")
19683                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19684    (clobber (match_operand:SI 1 "register_operand" "=D"))
19685    (clobber (reg:CC FLAGS_REG))]
19686   "!TARGET_64BIT"
19687   "repnz scasb"
19688   [(set_attr "type" "str")
19689    (set_attr "mode" "QI")
19690    (set_attr "prefix_rep" "1")])
19692 (define_insn "*strlenqi_rex_1"
19693   [(set (match_operand:DI 0 "register_operand" "=&c")
19694         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19695                     (match_operand:QI 2 "register_operand" "a")
19696                     (match_operand:DI 3 "immediate_operand" "i")
19697                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19698    (clobber (match_operand:DI 1 "register_operand" "=D"))
19699    (clobber (reg:CC FLAGS_REG))]
19700   "TARGET_64BIT"
19701   "repnz scasb"
19702   [(set_attr "type" "str")
19703    (set_attr "mode" "QI")
19704    (set_attr "prefix_rep" "1")])
19706 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19707 ;; handled in combine, but it is not currently up to the task.
19708 ;; When used for their truth value, the cmpstrn* expanders generate
19709 ;; code like this:
19711 ;;   repz cmpsb
19712 ;;   seta       %al
19713 ;;   setb       %dl
19714 ;;   cmpb       %al, %dl
19715 ;;   jcc        label
19717 ;; The intermediate three instructions are unnecessary.
19719 ;; This one handles cmpstrn*_nz_1...
19720 (define_peephole2
19721   [(parallel[
19722      (set (reg:CC FLAGS_REG)
19723           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19724                       (mem:BLK (match_operand 5 "register_operand" ""))))
19725      (use (match_operand 6 "register_operand" ""))
19726      (use (match_operand:SI 3 "immediate_operand" ""))
19727      (clobber (match_operand 0 "register_operand" ""))
19728      (clobber (match_operand 1 "register_operand" ""))
19729      (clobber (match_operand 2 "register_operand" ""))])
19730    (set (match_operand:QI 7 "register_operand" "")
19731         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19732    (set (match_operand:QI 8 "register_operand" "")
19733         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19734    (set (reg FLAGS_REG)
19735         (compare (match_dup 7) (match_dup 8)))
19736   ]
19737   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19738   [(parallel[
19739      (set (reg:CC FLAGS_REG)
19740           (compare:CC (mem:BLK (match_dup 4))
19741                       (mem:BLK (match_dup 5))))
19742      (use (match_dup 6))
19743      (use (match_dup 3))
19744      (clobber (match_dup 0))
19745      (clobber (match_dup 1))
19746      (clobber (match_dup 2))])]
19747   "")
19749 ;; ...and this one handles cmpstrn*_1.
19750 (define_peephole2
19751   [(parallel[
19752      (set (reg:CC FLAGS_REG)
19753           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19754                                (const_int 0))
19755             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19756                         (mem:BLK (match_operand 5 "register_operand" "")))
19757             (const_int 0)))
19758      (use (match_operand:SI 3 "immediate_operand" ""))
19759      (use (reg:CC FLAGS_REG))
19760      (clobber (match_operand 0 "register_operand" ""))
19761      (clobber (match_operand 1 "register_operand" ""))
19762      (clobber (match_operand 2 "register_operand" ""))])
19763    (set (match_operand:QI 7 "register_operand" "")
19764         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19765    (set (match_operand:QI 8 "register_operand" "")
19766         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19767    (set (reg FLAGS_REG)
19768         (compare (match_dup 7) (match_dup 8)))
19769   ]
19770   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19771   [(parallel[
19772      (set (reg:CC FLAGS_REG)
19773           (if_then_else:CC (ne (match_dup 6)
19774                                (const_int 0))
19775             (compare:CC (mem:BLK (match_dup 4))
19776                         (mem:BLK (match_dup 5)))
19777             (const_int 0)))
19778      (use (match_dup 3))
19779      (use (reg:CC FLAGS_REG))
19780      (clobber (match_dup 0))
19781      (clobber (match_dup 1))
19782      (clobber (match_dup 2))])]
19783   "")
19787 ;; Conditional move instructions.
19789 (define_expand "movdicc"
19790   [(set (match_operand:DI 0 "register_operand" "")
19791         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19792                          (match_operand:DI 2 "general_operand" "")
19793                          (match_operand:DI 3 "general_operand" "")))]
19794   "TARGET_64BIT"
19795   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19797 (define_insn "x86_movdicc_0_m1_rex64"
19798   [(set (match_operand:DI 0 "register_operand" "=r")
19799         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19800           (const_int -1)
19801           (const_int 0)))
19802    (clobber (reg:CC FLAGS_REG))]
19803   "TARGET_64BIT"
19804   "sbb{q}\t%0, %0"
19805   ; Since we don't have the proper number of operands for an alu insn,
19806   ; fill in all the blanks.
19807   [(set_attr "type" "alu")
19808    (set_attr "pent_pair" "pu")
19809    (set_attr "memory" "none")
19810    (set_attr "imm_disp" "false")
19811    (set_attr "mode" "DI")
19812    (set_attr "length_immediate" "0")])
19814 (define_insn "*x86_movdicc_0_m1_se"
19815   [(set (match_operand:DI 0 "register_operand" "=r")
19816         (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19817                          (const_int 1)
19818                          (const_int 0)))
19819    (clobber (reg:CC FLAGS_REG))]
19820   ""
19821   "sbb{q}\t%0, %0"
19822   [(set_attr "type" "alu")
19823    (set_attr "pent_pair" "pu")
19824    (set_attr "memory" "none")
19825    (set_attr "imm_disp" "false")
19826    (set_attr "mode" "DI")
19827    (set_attr "length_immediate" "0")])
19829 (define_insn "*movdicc_c_rex64"
19830   [(set (match_operand:DI 0 "register_operand" "=r,r")
19831         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19832                                 [(reg FLAGS_REG) (const_int 0)])
19833                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19834                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19835   "TARGET_64BIT && TARGET_CMOVE
19836    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19837   "@
19838    cmov%O2%C1\t{%2, %0|%0, %2}
19839    cmov%O2%c1\t{%3, %0|%0, %3}"
19840   [(set_attr "type" "icmov")
19841    (set_attr "mode" "DI")])
19843 (define_expand "movsicc"
19844   [(set (match_operand:SI 0 "register_operand" "")
19845         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19846                          (match_operand:SI 2 "general_operand" "")
19847                          (match_operand:SI 3 "general_operand" "")))]
19848   ""
19849   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19851 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19852 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19853 ;; So just document what we're doing explicitly.
19855 (define_insn "x86_movsicc_0_m1"
19856   [(set (match_operand:SI 0 "register_operand" "=r")
19857         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19858           (const_int -1)
19859           (const_int 0)))
19860    (clobber (reg:CC FLAGS_REG))]
19861   ""
19862   "sbb{l}\t%0, %0"
19863   ; Since we don't have the proper number of operands for an alu insn,
19864   ; fill in all the blanks.
19865   [(set_attr "type" "alu")
19866    (set_attr "pent_pair" "pu")
19867    (set_attr "memory" "none")
19868    (set_attr "imm_disp" "false")
19869    (set_attr "mode" "SI")
19870    (set_attr "length_immediate" "0")])
19872 (define_insn "*x86_movsicc_0_m1_se"
19873   [(set (match_operand:SI 0 "register_operand" "=r")
19874         (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19875                          (const_int 1)
19876                          (const_int 0)))
19877    (clobber (reg:CC FLAGS_REG))]
19878   ""
19879   "sbb{l}\t%0, %0"
19880   [(set_attr "type" "alu")
19881    (set_attr "pent_pair" "pu")
19882    (set_attr "memory" "none")
19883    (set_attr "imm_disp" "false")
19884    (set_attr "mode" "SI")
19885    (set_attr "length_immediate" "0")])
19887 (define_insn "*movsicc_noc"
19888   [(set (match_operand:SI 0 "register_operand" "=r,r")
19889         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19890                                 [(reg FLAGS_REG) (const_int 0)])
19891                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19892                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19893   "TARGET_CMOVE
19894    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19895   "@
19896    cmov%O2%C1\t{%2, %0|%0, %2}
19897    cmov%O2%c1\t{%3, %0|%0, %3}"
19898   [(set_attr "type" "icmov")
19899    (set_attr "mode" "SI")])
19901 (define_expand "movhicc"
19902   [(set (match_operand:HI 0 "register_operand" "")
19903         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19904                          (match_operand:HI 2 "general_operand" "")
19905                          (match_operand:HI 3 "general_operand" "")))]
19906   "TARGET_HIMODE_MATH"
19907   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19909 (define_insn "*movhicc_noc"
19910   [(set (match_operand:HI 0 "register_operand" "=r,r")
19911         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19912                                 [(reg FLAGS_REG) (const_int 0)])
19913                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19914                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19915   "TARGET_CMOVE
19916    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19917   "@
19918    cmov%O2%C1\t{%2, %0|%0, %2}
19919    cmov%O2%c1\t{%3, %0|%0, %3}"
19920   [(set_attr "type" "icmov")
19921    (set_attr "mode" "HI")])
19923 (define_expand "movqicc"
19924   [(set (match_operand:QI 0 "register_operand" "")
19925         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19926                          (match_operand:QI 2 "general_operand" "")
19927                          (match_operand:QI 3 "general_operand" "")))]
19928   "TARGET_QIMODE_MATH"
19929   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19931 (define_insn_and_split "*movqicc_noc"
19932   [(set (match_operand:QI 0 "register_operand" "=r,r")
19933         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19934                                 [(match_operand 4 "flags_reg_operand" "")
19935                                  (const_int 0)])
19936                       (match_operand:QI 2 "register_operand" "r,0")
19937                       (match_operand:QI 3 "register_operand" "0,r")))]
19938   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19939   "#"
19940   "&& reload_completed"
19941   [(set (match_dup 0)
19942         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19943                       (match_dup 2)
19944                       (match_dup 3)))]
19945   "operands[0] = gen_lowpart (SImode, operands[0]);
19946    operands[2] = gen_lowpart (SImode, operands[2]);
19947    operands[3] = gen_lowpart (SImode, operands[3]);"
19948   [(set_attr "type" "icmov")
19949    (set_attr "mode" "SI")])
19951 (define_expand "mov<mode>cc"
19952   [(set (match_operand:X87MODEF 0 "register_operand" "")
19953         (if_then_else:X87MODEF
19954           (match_operand 1 "comparison_operator" "")
19955           (match_operand:X87MODEF 2 "register_operand" "")
19956           (match_operand:X87MODEF 3 "register_operand" "")))]
19957   "(TARGET_80387 && TARGET_CMOVE)
19958    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19959   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19961 (define_insn "*movsfcc_1_387"
19962   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19963         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19964                                 [(reg FLAGS_REG) (const_int 0)])
19965                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19966                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19967   "TARGET_80387 && TARGET_CMOVE
19968    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19969   "@
19970    fcmov%F1\t{%2, %0|%0, %2}
19971    fcmov%f1\t{%3, %0|%0, %3}
19972    cmov%O2%C1\t{%2, %0|%0, %2}
19973    cmov%O2%c1\t{%3, %0|%0, %3}"
19974   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19975    (set_attr "mode" "SF,SF,SI,SI")])
19977 (define_insn "*movdfcc_1"
19978   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19979         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19980                                 [(reg FLAGS_REG) (const_int 0)])
19981                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19982                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19983   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19984    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19985   "@
19986    fcmov%F1\t{%2, %0|%0, %2}
19987    fcmov%f1\t{%3, %0|%0, %3}
19988    #
19989    #"
19990   [(set_attr "type" "fcmov,fcmov,multi,multi")
19991    (set_attr "mode" "DF")])
19993 (define_insn "*movdfcc_1_rex64"
19994   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19995         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19996                                 [(reg FLAGS_REG) (const_int 0)])
19997                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19998                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19999   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20000    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20001   "@
20002    fcmov%F1\t{%2, %0|%0, %2}
20003    fcmov%f1\t{%3, %0|%0, %3}
20004    cmov%O2%C1\t{%2, %0|%0, %2}
20005    cmov%O2%c1\t{%3, %0|%0, %3}"
20006   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20007    (set_attr "mode" "DF")])
20009 (define_split
20010   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
20011         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20012                                 [(match_operand 4 "flags_reg_operand" "")
20013                                  (const_int 0)])
20014                       (match_operand:DF 2 "nonimmediate_operand" "")
20015                       (match_operand:DF 3 "nonimmediate_operand" "")))]
20016   "!TARGET_64BIT && reload_completed"
20017   [(set (match_dup 2)
20018         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20019                       (match_dup 5)
20020                       (match_dup 6)))
20021    (set (match_dup 3)
20022         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20023                       (match_dup 7)
20024                       (match_dup 8)))]
20025   "split_di (&operands[2], 2, &operands[5], &operands[7]);
20026    split_di (&operands[0], 1, &operands[2], &operands[3]);")
20028 (define_insn "*movxfcc_1"
20029   [(set (match_operand:XF 0 "register_operand" "=f,f")
20030         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
20031                                 [(reg FLAGS_REG) (const_int 0)])
20032                       (match_operand:XF 2 "register_operand" "f,0")
20033                       (match_operand:XF 3 "register_operand" "0,f")))]
20034   "TARGET_80387 && TARGET_CMOVE"
20035   "@
20036    fcmov%F1\t{%2, %0|%0, %2}
20037    fcmov%f1\t{%3, %0|%0, %3}"
20038   [(set_attr "type" "fcmov")
20039    (set_attr "mode" "XF")])
20041 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
20042 ;; the scalar versions to have only XMM registers as operands.
20044 ;; SSE5 conditional move
20045 (define_insn "*sse5_pcmov_<mode>"
20046   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
20047         (if_then_else:MODEF
20048           (match_operand:MODEF 1 "register_operand" "x,0")
20049           (match_operand:MODEF 2 "register_operand" "0,x")
20050           (match_operand:MODEF 3 "register_operand" "x,x")))]
20051   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
20052   "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
20053   [(set_attr "type" "sse4arg")])
20055 ;; These versions of the min/max patterns are intentionally ignorant of
20056 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
20057 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
20058 ;; are undefined in this condition, we're certain this is correct.
20060 (define_insn "*avx_<code><mode>3"
20061   [(set (match_operand:MODEF 0 "register_operand" "=x")
20062         (smaxmin:MODEF
20063           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
20064           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20065   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20066   "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20067   [(set_attr "type" "sseadd")
20068    (set_attr "prefix" "vex")
20069    (set_attr "mode" "<MODE>")])
20071 (define_insn "<code><mode>3"
20072   [(set (match_operand:MODEF 0 "register_operand" "=x")
20073         (smaxmin:MODEF
20074           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
20075           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20076   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20077   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
20078   [(set_attr "type" "sseadd")
20079    (set_attr "mode" "<MODE>")])
20081 ;; These versions of the min/max patterns implement exactly the operations
20082 ;;   min = (op1 < op2 ? op1 : op2)
20083 ;;   max = (!(op1 < op2) ? op1 : op2)
20084 ;; Their operands are not commutative, and thus they may be used in the
20085 ;; presence of -0.0 and NaN.
20087 (define_insn "*avx_ieee_smin<mode>3"
20088   [(set (match_operand:MODEF 0 "register_operand" "=x")
20089         (unspec:MODEF
20090           [(match_operand:MODEF 1 "register_operand" "x")
20091            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20092          UNSPEC_IEEE_MIN))]
20093   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20094   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20095   [(set_attr "type" "sseadd")
20096    (set_attr "prefix" "vex")
20097    (set_attr "mode" "<MODE>")])
20099 (define_insn "*ieee_smin<mode>3"
20100   [(set (match_operand:MODEF 0 "register_operand" "=x")
20101         (unspec:MODEF
20102           [(match_operand:MODEF 1 "register_operand" "0")
20103            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20104          UNSPEC_IEEE_MIN))]
20105   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20106   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20107   [(set_attr "type" "sseadd")
20108    (set_attr "mode" "<MODE>")])
20110 (define_insn "*avx_ieee_smax<mode>3"
20111   [(set (match_operand:MODEF 0 "register_operand" "=x")
20112         (unspec:MODEF
20113           [(match_operand:MODEF 1 "register_operand" "0")
20114            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20115          UNSPEC_IEEE_MAX))]
20116   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20117   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20118   [(set_attr "type" "sseadd")
20119    (set_attr "prefix" "vex")
20120    (set_attr "mode" "<MODE>")])
20122 (define_insn "*ieee_smax<mode>3"
20123   [(set (match_operand:MODEF 0 "register_operand" "=x")
20124         (unspec:MODEF
20125           [(match_operand:MODEF 1 "register_operand" "0")
20126            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20127          UNSPEC_IEEE_MAX))]
20128   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20129   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20130   [(set_attr "type" "sseadd")
20131    (set_attr "mode" "<MODE>")])
20133 ;; Make two stack loads independent:
20134 ;;   fld aa              fld aa
20135 ;;   fld %st(0)     ->   fld bb
20136 ;;   fmul bb             fmul %st(1), %st
20138 ;; Actually we only match the last two instructions for simplicity.
20139 (define_peephole2
20140   [(set (match_operand 0 "fp_register_operand" "")
20141         (match_operand 1 "fp_register_operand" ""))
20142    (set (match_dup 0)
20143         (match_operator 2 "binary_fp_operator"
20144            [(match_dup 0)
20145             (match_operand 3 "memory_operand" "")]))]
20146   "REGNO (operands[0]) != REGNO (operands[1])"
20147   [(set (match_dup 0) (match_dup 3))
20148    (set (match_dup 0) (match_dup 4))]
20150   ;; The % modifier is not operational anymore in peephole2's, so we have to
20151   ;; swap the operands manually in the case of addition and multiplication.
20152   "if (COMMUTATIVE_ARITH_P (operands[2]))
20153      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20154                                  operands[0], operands[1]);
20155    else
20156      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20157                                  operands[1], operands[0]);")
20159 ;; Conditional addition patterns
20160 (define_expand "add<mode>cc"
20161   [(match_operand:SWI 0 "register_operand" "")
20162    (match_operand 1 "comparison_operator" "")
20163    (match_operand:SWI 2 "register_operand" "")
20164    (match_operand:SWI 3 "const_int_operand" "")]
20165   ""
20166   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20169 ;; Misc patterns (?)
20171 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20172 ;; Otherwise there will be nothing to keep
20174 ;; [(set (reg ebp) (reg esp))]
20175 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20176 ;;  (clobber (eflags)]
20177 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20179 ;; in proper program order.
20180 (define_insn "pro_epilogue_adjust_stack_1"
20181   [(set (match_operand:SI 0 "register_operand" "=r,r")
20182         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20183                  (match_operand:SI 2 "immediate_operand" "i,i")))
20184    (clobber (reg:CC FLAGS_REG))
20185    (clobber (mem:BLK (scratch)))]
20186   "!TARGET_64BIT"
20188   switch (get_attr_type (insn))
20189     {
20190     case TYPE_IMOV:
20191       return "mov{l}\t{%1, %0|%0, %1}";
20193     case TYPE_ALU:
20194       if (CONST_INT_P (operands[2])
20195           && (INTVAL (operands[2]) == 128
20196               || (INTVAL (operands[2]) < 0
20197                   && INTVAL (operands[2]) != -128)))
20198         {
20199           operands[2] = GEN_INT (-INTVAL (operands[2]));
20200           return "sub{l}\t{%2, %0|%0, %2}";
20201         }
20202       return "add{l}\t{%2, %0|%0, %2}";
20204     case TYPE_LEA:
20205       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20206       return "lea{l}\t{%a2, %0|%0, %a2}";
20208     default:
20209       gcc_unreachable ();
20210     }
20212   [(set (attr "type")
20213         (cond [(eq_attr "alternative" "0")
20214                  (const_string "alu")
20215                (match_operand:SI 2 "const0_operand" "")
20216                  (const_string "imov")
20217               ]
20218               (const_string "lea")))
20219    (set_attr "mode" "SI")])
20221 (define_insn "pro_epilogue_adjust_stack_rex64"
20222   [(set (match_operand:DI 0 "register_operand" "=r,r")
20223         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20224                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20225    (clobber (reg:CC FLAGS_REG))
20226    (clobber (mem:BLK (scratch)))]
20227   "TARGET_64BIT"
20229   switch (get_attr_type (insn))
20230     {
20231     case TYPE_IMOV:
20232       return "mov{q}\t{%1, %0|%0, %1}";
20234     case TYPE_ALU:
20235       if (CONST_INT_P (operands[2])
20236           /* Avoid overflows.  */
20237           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20238           && (INTVAL (operands[2]) == 128
20239               || (INTVAL (operands[2]) < 0
20240                   && INTVAL (operands[2]) != -128)))
20241         {
20242           operands[2] = GEN_INT (-INTVAL (operands[2]));
20243           return "sub{q}\t{%2, %0|%0, %2}";
20244         }
20245       return "add{q}\t{%2, %0|%0, %2}";
20247     case TYPE_LEA:
20248       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20249       return "lea{q}\t{%a2, %0|%0, %a2}";
20251     default:
20252       gcc_unreachable ();
20253     }
20255   [(set (attr "type")
20256         (cond [(eq_attr "alternative" "0")
20257                  (const_string "alu")
20258                (match_operand:DI 2 "const0_operand" "")
20259                  (const_string "imov")
20260               ]
20261               (const_string "lea")))
20262    (set_attr "mode" "DI")])
20264 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20265   [(set (match_operand:DI 0 "register_operand" "=r,r")
20266         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20267                  (match_operand:DI 3 "immediate_operand" "i,i")))
20268    (use (match_operand:DI 2 "register_operand" "r,r"))
20269    (clobber (reg:CC FLAGS_REG))
20270    (clobber (mem:BLK (scratch)))]
20271   "TARGET_64BIT"
20273   switch (get_attr_type (insn))
20274     {
20275     case TYPE_ALU:
20276       return "add{q}\t{%2, %0|%0, %2}";
20278     case TYPE_LEA:
20279       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20280       return "lea{q}\t{%a2, %0|%0, %a2}";
20282     default:
20283       gcc_unreachable ();
20284     }
20286   [(set_attr "type" "alu,lea")
20287    (set_attr "mode" "DI")])
20289 (define_insn "allocate_stack_worker_32"
20290   [(set (match_operand:SI 0 "register_operand" "=a")
20291         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20292                             UNSPECV_STACK_PROBE))
20293    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
20294    (clobber (reg:CC FLAGS_REG))]
20295   "!TARGET_64BIT && TARGET_STACK_PROBE"
20296   "call\t___chkstk"
20297   [(set_attr "type" "multi")
20298    (set_attr "length" "5")])
20300 (define_insn "allocate_stack_worker_64"
20301   [(set (match_operand:DI 0 "register_operand" "=a")
20302         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
20303                             UNSPECV_STACK_PROBE))
20304    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
20305    (clobber (reg:DI R10_REG))
20306    (clobber (reg:DI R11_REG))
20307    (clobber (reg:CC FLAGS_REG))]
20308   "TARGET_64BIT && TARGET_STACK_PROBE"
20309   "call\t___chkstk"
20310   [(set_attr "type" "multi")
20311    (set_attr "length" "5")])
20313 (define_expand "allocate_stack"
20314   [(match_operand 0 "register_operand" "")
20315    (match_operand 1 "general_operand" "")]
20316   "TARGET_STACK_PROBE"
20318   rtx x;
20320 #ifndef CHECK_STACK_LIMIT
20321 #define CHECK_STACK_LIMIT 0
20322 #endif
20324   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20325       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20326     {
20327       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20328                                stack_pointer_rtx, 0, OPTAB_DIRECT);
20329       if (x != stack_pointer_rtx)
20330         emit_move_insn (stack_pointer_rtx, x);
20331     }
20332   else
20333     {
20334       x = copy_to_mode_reg (Pmode, operands[1]);
20335       if (TARGET_64BIT)
20336         x = gen_allocate_stack_worker_64 (x, x);
20337       else
20338         x = gen_allocate_stack_worker_32 (x, x);
20339       emit_insn (x);
20340     }
20342   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20343   DONE;
20346 (define_expand "builtin_setjmp_receiver"
20347   [(label_ref (match_operand 0 "" ""))]
20348   "!TARGET_64BIT && flag_pic"
20350 #if TARGET_MACHO
20351   if (TARGET_MACHO)
20352     {
20353       rtx xops[3];
20354       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20355       rtx label_rtx = gen_label_rtx ();
20356       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20357       xops[0] = xops[1] = picreg;
20358       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20359       ix86_expand_binary_operator (MINUS, SImode, xops);
20360     }
20361   else
20362 #endif
20363     emit_insn (gen_set_got (pic_offset_table_rtx));
20364   DONE;
20367 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20369 (define_split
20370   [(set (match_operand 0 "register_operand" "")
20371         (match_operator 3 "promotable_binary_operator"
20372            [(match_operand 1 "register_operand" "")
20373             (match_operand 2 "aligned_operand" "")]))
20374    (clobber (reg:CC FLAGS_REG))]
20375   "! TARGET_PARTIAL_REG_STALL && reload_completed
20376    && ((GET_MODE (operands[0]) == HImode
20377         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
20378             /* ??? next two lines just !satisfies_constraint_K (...) */
20379             || !CONST_INT_P (operands[2])
20380             || satisfies_constraint_K (operands[2])))
20381        || (GET_MODE (operands[0]) == QImode
20382            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
20383   [(parallel [(set (match_dup 0)
20384                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20385               (clobber (reg:CC FLAGS_REG))])]
20386   "operands[0] = gen_lowpart (SImode, operands[0]);
20387    operands[1] = gen_lowpart (SImode, operands[1]);
20388    if (GET_CODE (operands[3]) != ASHIFT)
20389      operands[2] = gen_lowpart (SImode, operands[2]);
20390    PUT_MODE (operands[3], SImode);")
20392 ; Promote the QImode tests, as i386 has encoding of the AND
20393 ; instruction with 32-bit sign-extended immediate and thus the
20394 ; instruction size is unchanged, except in the %eax case for
20395 ; which it is increased by one byte, hence the ! optimize_size.
20396 (define_split
20397   [(set (match_operand 0 "flags_reg_operand" "")
20398         (match_operator 2 "compare_operator"
20399           [(and (match_operand 3 "aligned_operand" "")
20400                 (match_operand 4 "const_int_operand" ""))
20401            (const_int 0)]))
20402    (set (match_operand 1 "register_operand" "")
20403         (and (match_dup 3) (match_dup 4)))]
20404   "! TARGET_PARTIAL_REG_STALL && reload_completed
20405    && optimize_insn_for_speed_p ()
20406    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20407        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20408    /* Ensure that the operand will remain sign-extended immediate.  */
20409    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20410   [(parallel [(set (match_dup 0)
20411                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20412                                     (const_int 0)]))
20413               (set (match_dup 1)
20414                    (and:SI (match_dup 3) (match_dup 4)))])]
20416   operands[4]
20417     = gen_int_mode (INTVAL (operands[4])
20418                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20419   operands[1] = gen_lowpart (SImode, operands[1]);
20420   operands[3] = gen_lowpart (SImode, operands[3]);
20423 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20424 ; the TEST instruction with 32-bit sign-extended immediate and thus
20425 ; the instruction size would at least double, which is not what we
20426 ; want even with ! optimize_size.
20427 (define_split
20428   [(set (match_operand 0 "flags_reg_operand" "")
20429         (match_operator 1 "compare_operator"
20430           [(and (match_operand:HI 2 "aligned_operand" "")
20431                 (match_operand:HI 3 "const_int_operand" ""))
20432            (const_int 0)]))]
20433   "! TARGET_PARTIAL_REG_STALL && reload_completed
20434    && ! TARGET_FAST_PREFIX
20435    && optimize_insn_for_speed_p ()
20436    /* Ensure that the operand will remain sign-extended immediate.  */
20437    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20438   [(set (match_dup 0)
20439         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20440                          (const_int 0)]))]
20442   operands[3]
20443     = gen_int_mode (INTVAL (operands[3])
20444                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20445   operands[2] = gen_lowpart (SImode, operands[2]);
20448 (define_split
20449   [(set (match_operand 0 "register_operand" "")
20450         (neg (match_operand 1 "register_operand" "")))
20451    (clobber (reg:CC FLAGS_REG))]
20452   "! TARGET_PARTIAL_REG_STALL && reload_completed
20453    && (GET_MODE (operands[0]) == HImode
20454        || (GET_MODE (operands[0]) == QImode
20455            && (TARGET_PROMOTE_QImode
20456                || optimize_insn_for_size_p ())))"
20457   [(parallel [(set (match_dup 0)
20458                    (neg:SI (match_dup 1)))
20459               (clobber (reg:CC FLAGS_REG))])]
20460   "operands[0] = gen_lowpart (SImode, operands[0]);
20461    operands[1] = gen_lowpart (SImode, operands[1]);")
20463 (define_split
20464   [(set (match_operand 0 "register_operand" "")
20465         (not (match_operand 1 "register_operand" "")))]
20466   "! TARGET_PARTIAL_REG_STALL && reload_completed
20467    && (GET_MODE (operands[0]) == HImode
20468        || (GET_MODE (operands[0]) == QImode
20469            && (TARGET_PROMOTE_QImode
20470                || optimize_insn_for_size_p ())))"
20471   [(set (match_dup 0)
20472         (not:SI (match_dup 1)))]
20473   "operands[0] = gen_lowpart (SImode, operands[0]);
20474    operands[1] = gen_lowpart (SImode, operands[1]);")
20476 (define_split
20477   [(set (match_operand 0 "register_operand" "")
20478         (if_then_else (match_operator 1 "comparison_operator"
20479                                 [(reg FLAGS_REG) (const_int 0)])
20480                       (match_operand 2 "register_operand" "")
20481                       (match_operand 3 "register_operand" "")))]
20482   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20483    && (GET_MODE (operands[0]) == HImode
20484        || (GET_MODE (operands[0]) == QImode
20485            && (TARGET_PROMOTE_QImode
20486                || optimize_insn_for_size_p ())))"
20487   [(set (match_dup 0)
20488         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20489   "operands[0] = gen_lowpart (SImode, operands[0]);
20490    operands[2] = gen_lowpart (SImode, operands[2]);
20491    operands[3] = gen_lowpart (SImode, operands[3]);")
20494 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
20495 ;; transform a complex memory operation into two memory to register operations.
20497 ;; Don't push memory operands
20498 (define_peephole2
20499   [(set (match_operand:SI 0 "push_operand" "")
20500         (match_operand:SI 1 "memory_operand" ""))
20501    (match_scratch:SI 2 "r")]
20502   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20503    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20504   [(set (match_dup 2) (match_dup 1))
20505    (set (match_dup 0) (match_dup 2))]
20506   "")
20508 (define_peephole2
20509   [(set (match_operand:DI 0 "push_operand" "")
20510         (match_operand:DI 1 "memory_operand" ""))
20511    (match_scratch:DI 2 "r")]
20512   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20513    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20514   [(set (match_dup 2) (match_dup 1))
20515    (set (match_dup 0) (match_dup 2))]
20516   "")
20518 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20519 ;; SImode pushes.
20520 (define_peephole2
20521   [(set (match_operand:SF 0 "push_operand" "")
20522         (match_operand:SF 1 "memory_operand" ""))
20523    (match_scratch:SF 2 "r")]
20524   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20525    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20526   [(set (match_dup 2) (match_dup 1))
20527    (set (match_dup 0) (match_dup 2))]
20528   "")
20530 (define_peephole2
20531   [(set (match_operand:HI 0 "push_operand" "")
20532         (match_operand:HI 1 "memory_operand" ""))
20533    (match_scratch:HI 2 "r")]
20534   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20535    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20536   [(set (match_dup 2) (match_dup 1))
20537    (set (match_dup 0) (match_dup 2))]
20538   "")
20540 (define_peephole2
20541   [(set (match_operand:QI 0 "push_operand" "")
20542         (match_operand:QI 1 "memory_operand" ""))
20543    (match_scratch:QI 2 "q")]
20544   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20545    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20546   [(set (match_dup 2) (match_dup 1))
20547    (set (match_dup 0) (match_dup 2))]
20548   "")
20550 ;; Don't move an immediate directly to memory when the instruction
20551 ;; gets too big.
20552 (define_peephole2
20553   [(match_scratch:SI 1 "r")
20554    (set (match_operand:SI 0 "memory_operand" "")
20555         (const_int 0))]
20556   "optimize_insn_for_speed_p ()
20557    && ! TARGET_USE_MOV0
20558    && TARGET_SPLIT_LONG_MOVES
20559    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20560    && peep2_regno_dead_p (0, FLAGS_REG)"
20561   [(parallel [(set (match_dup 1) (const_int 0))
20562               (clobber (reg:CC FLAGS_REG))])
20563    (set (match_dup 0) (match_dup 1))]
20564   "")
20566 (define_peephole2
20567   [(match_scratch:HI 1 "r")
20568    (set (match_operand:HI 0 "memory_operand" "")
20569         (const_int 0))]
20570   "optimize_insn_for_speed_p ()
20571    && ! TARGET_USE_MOV0
20572    && TARGET_SPLIT_LONG_MOVES
20573    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20574    && peep2_regno_dead_p (0, FLAGS_REG)"
20575   [(parallel [(set (match_dup 2) (const_int 0))
20576               (clobber (reg:CC FLAGS_REG))])
20577    (set (match_dup 0) (match_dup 1))]
20578   "operands[2] = gen_lowpart (SImode, operands[1]);")
20580 (define_peephole2
20581   [(match_scratch:QI 1 "q")
20582    (set (match_operand:QI 0 "memory_operand" "")
20583         (const_int 0))]
20584   "optimize_insn_for_speed_p ()
20585    && ! TARGET_USE_MOV0
20586    && TARGET_SPLIT_LONG_MOVES
20587    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20588    && peep2_regno_dead_p (0, FLAGS_REG)"
20589   [(parallel [(set (match_dup 2) (const_int 0))
20590               (clobber (reg:CC FLAGS_REG))])
20591    (set (match_dup 0) (match_dup 1))]
20592   "operands[2] = gen_lowpart (SImode, operands[1]);")
20594 (define_peephole2
20595   [(match_scratch:SI 2 "r")
20596    (set (match_operand:SI 0 "memory_operand" "")
20597         (match_operand:SI 1 "immediate_operand" ""))]
20598   "optimize_insn_for_speed_p ()
20599    && TARGET_SPLIT_LONG_MOVES
20600    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20601   [(set (match_dup 2) (match_dup 1))
20602    (set (match_dup 0) (match_dup 2))]
20603   "")
20605 (define_peephole2
20606   [(match_scratch:HI 2 "r")
20607    (set (match_operand:HI 0 "memory_operand" "")
20608         (match_operand:HI 1 "immediate_operand" ""))]
20609   "optimize_insn_for_speed_p ()
20610    && TARGET_SPLIT_LONG_MOVES
20611    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20612   [(set (match_dup 2) (match_dup 1))
20613    (set (match_dup 0) (match_dup 2))]
20614   "")
20616 (define_peephole2
20617   [(match_scratch:QI 2 "q")
20618    (set (match_operand:QI 0 "memory_operand" "")
20619         (match_operand:QI 1 "immediate_operand" ""))]
20620   "optimize_insn_for_speed_p ()
20621    && TARGET_SPLIT_LONG_MOVES
20622    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20623   [(set (match_dup 2) (match_dup 1))
20624    (set (match_dup 0) (match_dup 2))]
20625   "")
20627 ;; Don't compare memory with zero, load and use a test instead.
20628 (define_peephole2
20629   [(set (match_operand 0 "flags_reg_operand" "")
20630         (match_operator 1 "compare_operator"
20631           [(match_operand:SI 2 "memory_operand" "")
20632            (const_int 0)]))
20633    (match_scratch:SI 3 "r")]
20634   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
20635   [(set (match_dup 3) (match_dup 2))
20636    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20637   "")
20639 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20640 ;; Don't split NOTs with a displacement operand, because resulting XOR
20641 ;; will not be pairable anyway.
20643 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20644 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20645 ;; so this split helps here as well.
20647 ;; Note: Can't do this as a regular split because we can't get proper
20648 ;; lifetime information then.
20650 (define_peephole2
20651   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20652         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20653   "optimize_insn_for_speed_p ()
20654    && ((TARGET_NOT_UNPAIRABLE
20655         && (!MEM_P (operands[0])
20656             || !memory_displacement_operand (operands[0], SImode)))
20657        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20658    && peep2_regno_dead_p (0, FLAGS_REG)"
20659   [(parallel [(set (match_dup 0)
20660                    (xor:SI (match_dup 1) (const_int -1)))
20661               (clobber (reg:CC FLAGS_REG))])]
20662   "")
20664 (define_peephole2
20665   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20666         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20667   "optimize_insn_for_speed_p ()
20668    && ((TARGET_NOT_UNPAIRABLE
20669         && (!MEM_P (operands[0])
20670             || !memory_displacement_operand (operands[0], HImode)))
20671        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20672    && peep2_regno_dead_p (0, FLAGS_REG)"
20673   [(parallel [(set (match_dup 0)
20674                    (xor:HI (match_dup 1) (const_int -1)))
20675               (clobber (reg:CC FLAGS_REG))])]
20676   "")
20678 (define_peephole2
20679   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20680         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20681   "optimize_insn_for_speed_p ()
20682    && ((TARGET_NOT_UNPAIRABLE
20683         && (!MEM_P (operands[0])
20684             || !memory_displacement_operand (operands[0], QImode)))
20685        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20686    && peep2_regno_dead_p (0, FLAGS_REG)"
20687   [(parallel [(set (match_dup 0)
20688                    (xor:QI (match_dup 1) (const_int -1)))
20689               (clobber (reg:CC FLAGS_REG))])]
20690   "")
20692 ;; Non pairable "test imm, reg" instructions can be translated to
20693 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20694 ;; byte opcode instead of two, have a short form for byte operands),
20695 ;; so do it for other CPUs as well.  Given that the value was dead,
20696 ;; this should not create any new dependencies.  Pass on the sub-word
20697 ;; versions if we're concerned about partial register stalls.
20699 (define_peephole2
20700   [(set (match_operand 0 "flags_reg_operand" "")
20701         (match_operator 1 "compare_operator"
20702           [(and:SI (match_operand:SI 2 "register_operand" "")
20703                    (match_operand:SI 3 "immediate_operand" ""))
20704            (const_int 0)]))]
20705   "ix86_match_ccmode (insn, CCNOmode)
20706    && (true_regnum (operands[2]) != AX_REG
20707        || satisfies_constraint_K (operands[3]))
20708    && peep2_reg_dead_p (1, operands[2])"
20709   [(parallel
20710      [(set (match_dup 0)
20711            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20712                             (const_int 0)]))
20713       (set (match_dup 2)
20714            (and:SI (match_dup 2) (match_dup 3)))])]
20715   "")
20717 ;; We don't need to handle HImode case, because it will be promoted to SImode
20718 ;; on ! TARGET_PARTIAL_REG_STALL
20720 (define_peephole2
20721   [(set (match_operand 0 "flags_reg_operand" "")
20722         (match_operator 1 "compare_operator"
20723           [(and:QI (match_operand:QI 2 "register_operand" "")
20724                    (match_operand:QI 3 "immediate_operand" ""))
20725            (const_int 0)]))]
20726   "! TARGET_PARTIAL_REG_STALL
20727    && ix86_match_ccmode (insn, CCNOmode)
20728    && true_regnum (operands[2]) != AX_REG
20729    && peep2_reg_dead_p (1, operands[2])"
20730   [(parallel
20731      [(set (match_dup 0)
20732            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20733                             (const_int 0)]))
20734       (set (match_dup 2)
20735            (and:QI (match_dup 2) (match_dup 3)))])]
20736   "")
20738 (define_peephole2
20739   [(set (match_operand 0 "flags_reg_operand" "")
20740         (match_operator 1 "compare_operator"
20741           [(and:SI
20742              (zero_extract:SI
20743                (match_operand 2 "ext_register_operand" "")
20744                (const_int 8)
20745                (const_int 8))
20746              (match_operand 3 "const_int_operand" ""))
20747            (const_int 0)]))]
20748   "! TARGET_PARTIAL_REG_STALL
20749    && ix86_match_ccmode (insn, CCNOmode)
20750    && true_regnum (operands[2]) != AX_REG
20751    && peep2_reg_dead_p (1, operands[2])"
20752   [(parallel [(set (match_dup 0)
20753                    (match_op_dup 1
20754                      [(and:SI
20755                         (zero_extract:SI
20756                           (match_dup 2)
20757                           (const_int 8)
20758                           (const_int 8))
20759                         (match_dup 3))
20760                       (const_int 0)]))
20761               (set (zero_extract:SI (match_dup 2)
20762                                     (const_int 8)
20763                                     (const_int 8))
20764                    (and:SI
20765                      (zero_extract:SI
20766                        (match_dup 2)
20767                        (const_int 8)
20768                        (const_int 8))
20769                      (match_dup 3)))])]
20770   "")
20772 ;; Don't do logical operations with memory inputs.
20773 (define_peephole2
20774   [(match_scratch:SI 2 "r")
20775    (parallel [(set (match_operand:SI 0 "register_operand" "")
20776                    (match_operator:SI 3 "arith_or_logical_operator"
20777                      [(match_dup 0)
20778                       (match_operand:SI 1 "memory_operand" "")]))
20779               (clobber (reg:CC FLAGS_REG))])]
20780   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20781   [(set (match_dup 2) (match_dup 1))
20782    (parallel [(set (match_dup 0)
20783                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20784               (clobber (reg:CC FLAGS_REG))])]
20785   "")
20787 (define_peephole2
20788   [(match_scratch:SI 2 "r")
20789    (parallel [(set (match_operand:SI 0 "register_operand" "")
20790                    (match_operator:SI 3 "arith_or_logical_operator"
20791                      [(match_operand:SI 1 "memory_operand" "")
20792                       (match_dup 0)]))
20793               (clobber (reg:CC FLAGS_REG))])]
20794   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20795   [(set (match_dup 2) (match_dup 1))
20796    (parallel [(set (match_dup 0)
20797                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20798               (clobber (reg:CC FLAGS_REG))])]
20799   "")
20801 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
20802 ;; refers to the destination of the load!
20804 (define_peephole2
20805   [(set (match_operand:SI 0 "register_operand" "")
20806         (match_operand:SI 1 "register_operand" ""))
20807    (parallel [(set (match_dup 0)
20808                    (match_operator:SI 3 "commutative_operator"
20809                      [(match_dup 0)
20810                       (match_operand:SI 2 "memory_operand" "")]))
20811               (clobber (reg:CC FLAGS_REG))])]
20812   "REGNO (operands[0]) != REGNO (operands[1])
20813    && GENERAL_REGNO_P (REGNO (operands[0]))
20814    && GENERAL_REGNO_P (REGNO (operands[1]))"
20815   [(set (match_dup 0) (match_dup 4))
20816    (parallel [(set (match_dup 0)
20817                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
20818               (clobber (reg:CC FLAGS_REG))])]
20819   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
20821 (define_peephole2
20822   [(set (match_operand 0 "register_operand" "")
20823         (match_operand 1 "register_operand" ""))
20824    (set (match_dup 0)
20825                    (match_operator 3 "commutative_operator"
20826                      [(match_dup 0)
20827                       (match_operand 2 "memory_operand" "")]))]
20828   "REGNO (operands[0]) != REGNO (operands[1])
20829    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
20830        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
20831   [(set (match_dup 0) (match_dup 2))
20832    (set (match_dup 0)
20833         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
20834   "")
20836 ; Don't do logical operations with memory outputs
20838 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20839 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20840 ; the same decoder scheduling characteristics as the original.
20842 (define_peephole2
20843   [(match_scratch:SI 2 "r")
20844    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20845                    (match_operator:SI 3 "arith_or_logical_operator"
20846                      [(match_dup 0)
20847                       (match_operand:SI 1 "nonmemory_operand" "")]))
20848               (clobber (reg:CC FLAGS_REG))])]
20849   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20850   [(set (match_dup 2) (match_dup 0))
20851    (parallel [(set (match_dup 2)
20852                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20853               (clobber (reg:CC FLAGS_REG))])
20854    (set (match_dup 0) (match_dup 2))]
20855   "")
20857 (define_peephole2
20858   [(match_scratch:SI 2 "r")
20859    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20860                    (match_operator:SI 3 "arith_or_logical_operator"
20861                      [(match_operand:SI 1 "nonmemory_operand" "")
20862                       (match_dup 0)]))
20863               (clobber (reg:CC FLAGS_REG))])]
20864   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20865   [(set (match_dup 2) (match_dup 0))
20866    (parallel [(set (match_dup 2)
20867                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20868               (clobber (reg:CC FLAGS_REG))])
20869    (set (match_dup 0) (match_dup 2))]
20870   "")
20872 ;; Attempt to always use XOR for zeroing registers.
20873 (define_peephole2
20874   [(set (match_operand 0 "register_operand" "")
20875         (match_operand 1 "const0_operand" ""))]
20876   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20877    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20878    && GENERAL_REG_P (operands[0])
20879    && peep2_regno_dead_p (0, FLAGS_REG)"
20880   [(parallel [(set (match_dup 0) (const_int 0))
20881               (clobber (reg:CC FLAGS_REG))])]
20883   operands[0] = gen_lowpart (word_mode, operands[0]);
20886 (define_peephole2
20887   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20888         (const_int 0))]
20889   "(GET_MODE (operands[0]) == QImode
20890     || GET_MODE (operands[0]) == HImode)
20891    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20892    && peep2_regno_dead_p (0, FLAGS_REG)"
20893   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20894               (clobber (reg:CC FLAGS_REG))])])
20896 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20897 (define_peephole2
20898   [(set (match_operand 0 "register_operand" "")
20899         (const_int -1))]
20900   "(GET_MODE (operands[0]) == HImode
20901     || GET_MODE (operands[0]) == SImode
20902     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20903    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
20904    && peep2_regno_dead_p (0, FLAGS_REG)"
20905   [(parallel [(set (match_dup 0) (const_int -1))
20906               (clobber (reg:CC FLAGS_REG))])]
20907   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20908                               operands[0]);")
20910 ;; Attempt to convert simple leas to adds. These can be created by
20911 ;; move expanders.
20912 (define_peephole2
20913   [(set (match_operand:SI 0 "register_operand" "")
20914         (plus:SI (match_dup 0)
20915                  (match_operand:SI 1 "nonmemory_operand" "")))]
20916   "peep2_regno_dead_p (0, FLAGS_REG)"
20917   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20918               (clobber (reg:CC FLAGS_REG))])]
20919   "")
20921 (define_peephole2
20922   [(set (match_operand:SI 0 "register_operand" "")
20923         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20924                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20925   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20926   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20927               (clobber (reg:CC FLAGS_REG))])]
20928   "operands[2] = gen_lowpart (SImode, operands[2]);")
20930 (define_peephole2
20931   [(set (match_operand:DI 0 "register_operand" "")
20932         (plus:DI (match_dup 0)
20933                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20934   "peep2_regno_dead_p (0, FLAGS_REG)"
20935   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20936               (clobber (reg:CC FLAGS_REG))])]
20937   "")
20939 (define_peephole2
20940   [(set (match_operand:SI 0 "register_operand" "")
20941         (mult:SI (match_dup 0)
20942                  (match_operand:SI 1 "const_int_operand" "")))]
20943   "exact_log2 (INTVAL (operands[1])) >= 0
20944    && peep2_regno_dead_p (0, FLAGS_REG)"
20945   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20946               (clobber (reg:CC FLAGS_REG))])]
20947   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20949 (define_peephole2
20950   [(set (match_operand:DI 0 "register_operand" "")
20951         (mult:DI (match_dup 0)
20952                  (match_operand:DI 1 "const_int_operand" "")))]
20953   "exact_log2 (INTVAL (operands[1])) >= 0
20954    && peep2_regno_dead_p (0, FLAGS_REG)"
20955   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20956               (clobber (reg:CC FLAGS_REG))])]
20957   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20959 (define_peephole2
20960   [(set (match_operand:SI 0 "register_operand" "")
20961         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20962                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20963   "exact_log2 (INTVAL (operands[2])) >= 0
20964    && REGNO (operands[0]) == REGNO (operands[1])
20965    && peep2_regno_dead_p (0, FLAGS_REG)"
20966   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20967               (clobber (reg:CC FLAGS_REG))])]
20968   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20970 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20971 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20972 ;; many CPUs it is also faster, since special hardware to avoid esp
20973 ;; dependencies is present.
20975 ;; While some of these conversions may be done using splitters, we use peepholes
20976 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20978 ;; Convert prologue esp subtractions to push.
20979 ;; We need register to push.  In order to keep verify_flow_info happy we have
20980 ;; two choices
20981 ;; - use scratch and clobber it in order to avoid dependencies
20982 ;; - use already live register
20983 ;; We can't use the second way right now, since there is no reliable way how to
20984 ;; verify that given register is live.  First choice will also most likely in
20985 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20986 ;; call clobbered registers are dead.  We may want to use base pointer as an
20987 ;; alternative when no register is available later.
20989 (define_peephole2
20990   [(match_scratch:SI 0 "r")
20991    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20992               (clobber (reg:CC FLAGS_REG))
20993               (clobber (mem:BLK (scratch)))])]
20994   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20995   [(clobber (match_dup 0))
20996    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20997               (clobber (mem:BLK (scratch)))])])
20999 (define_peephole2
21000   [(match_scratch:SI 0 "r")
21001    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21002               (clobber (reg:CC FLAGS_REG))
21003               (clobber (mem:BLK (scratch)))])]
21004   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21005   [(clobber (match_dup 0))
21006    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21007    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21008               (clobber (mem:BLK (scratch)))])])
21010 ;; Convert esp subtractions to push.
21011 (define_peephole2
21012   [(match_scratch:SI 0 "r")
21013    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21014               (clobber (reg:CC FLAGS_REG))])]
21015   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21016   [(clobber (match_dup 0))
21017    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21019 (define_peephole2
21020   [(match_scratch:SI 0 "r")
21021    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21022               (clobber (reg:CC FLAGS_REG))])]
21023   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21024   [(clobber (match_dup 0))
21025    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21026    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21028 ;; Convert epilogue deallocator to pop.
21029 (define_peephole2
21030   [(match_scratch:SI 0 "r")
21031    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21032               (clobber (reg:CC FLAGS_REG))
21033               (clobber (mem:BLK (scratch)))])]
21034   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21035   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21036               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21037               (clobber (mem:BLK (scratch)))])]
21038   "")
21040 ;; Two pops case is tricky, since pop causes dependency on destination register.
21041 ;; We use two registers if available.
21042 (define_peephole2
21043   [(match_scratch:SI 0 "r")
21044    (match_scratch:SI 1 "r")
21045    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21046               (clobber (reg:CC FLAGS_REG))
21047               (clobber (mem:BLK (scratch)))])]
21048   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21049   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21050               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21051               (clobber (mem:BLK (scratch)))])
21052    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21053               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21054   "")
21056 (define_peephole2
21057   [(match_scratch:SI 0 "r")
21058    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21059               (clobber (reg:CC FLAGS_REG))
21060               (clobber (mem:BLK (scratch)))])]
21061   "optimize_insn_for_size_p ()"
21062   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21063               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21064               (clobber (mem:BLK (scratch)))])
21065    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21066               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21067   "")
21069 ;; Convert esp additions to pop.
21070 (define_peephole2
21071   [(match_scratch:SI 0 "r")
21072    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21073               (clobber (reg:CC FLAGS_REG))])]
21074   ""
21075   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21076               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21077   "")
21079 ;; Two pops case is tricky, since pop causes dependency on destination register.
21080 ;; We use two registers if available.
21081 (define_peephole2
21082   [(match_scratch:SI 0 "r")
21083    (match_scratch:SI 1 "r")
21084    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21085               (clobber (reg:CC FLAGS_REG))])]
21086   ""
21087   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21088               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21089    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21090               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21091   "")
21093 (define_peephole2
21094   [(match_scratch:SI 0 "r")
21095    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21096               (clobber (reg:CC FLAGS_REG))])]
21097   "optimize_insn_for_size_p ()"
21098   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21099               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21100    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21101               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21102   "")
21104 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
21105 ;; required and register dies.  Similarly for 128 to -128.
21106 (define_peephole2
21107   [(set (match_operand 0 "flags_reg_operand" "")
21108         (match_operator 1 "compare_operator"
21109           [(match_operand 2 "register_operand" "")
21110            (match_operand 3 "const_int_operand" "")]))]
21111   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_size)
21112      && incdec_operand (operands[3], GET_MODE (operands[3])))
21113     || (!TARGET_FUSE_CMP_AND_BRANCH
21114         && INTVAL (operands[3]) == 128))
21115    && ix86_match_ccmode (insn, CCGCmode)
21116    && peep2_reg_dead_p (1, operands[2])"
21117   [(parallel [(set (match_dup 0)
21118                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
21119               (clobber (match_dup 2))])]
21120   "")
21122 (define_peephole2
21123   [(match_scratch:DI 0 "r")
21124    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21125               (clobber (reg:CC FLAGS_REG))
21126               (clobber (mem:BLK (scratch)))])]
21127   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21128   [(clobber (match_dup 0))
21129    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21130               (clobber (mem:BLK (scratch)))])])
21132 (define_peephole2
21133   [(match_scratch:DI 0 "r")
21134    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21135               (clobber (reg:CC FLAGS_REG))
21136               (clobber (mem:BLK (scratch)))])]
21137   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21138   [(clobber (match_dup 0))
21139    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21140    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21141               (clobber (mem:BLK (scratch)))])])
21143 ;; Convert esp subtractions to push.
21144 (define_peephole2
21145   [(match_scratch:DI 0 "r")
21146    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21147               (clobber (reg:CC FLAGS_REG))])]
21148   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21149   [(clobber (match_dup 0))
21150    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21152 (define_peephole2
21153   [(match_scratch:DI 0 "r")
21154    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21155               (clobber (reg:CC FLAGS_REG))])]
21156   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21157   [(clobber (match_dup 0))
21158    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21159    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21161 ;; Convert epilogue deallocator to pop.
21162 (define_peephole2
21163   [(match_scratch:DI 0 "r")
21164    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21165               (clobber (reg:CC FLAGS_REG))
21166               (clobber (mem:BLK (scratch)))])]
21167   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21168   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21169               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21170               (clobber (mem:BLK (scratch)))])]
21171   "")
21173 ;; Two pops case is tricky, since pop causes dependency on destination register.
21174 ;; We use two registers if available.
21175 (define_peephole2
21176   [(match_scratch:DI 0 "r")
21177    (match_scratch:DI 1 "r")
21178    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21179               (clobber (reg:CC FLAGS_REG))
21180               (clobber (mem:BLK (scratch)))])]
21181   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21182   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21183               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21184               (clobber (mem:BLK (scratch)))])
21185    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21186               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21187   "")
21189 (define_peephole2
21190   [(match_scratch:DI 0 "r")
21191    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21192               (clobber (reg:CC FLAGS_REG))
21193               (clobber (mem:BLK (scratch)))])]
21194   "optimize_insn_for_size_p ()"
21195   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21196               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21197               (clobber (mem:BLK (scratch)))])
21198    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21199               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21200   "")
21202 ;; Convert esp additions to pop.
21203 (define_peephole2
21204   [(match_scratch:DI 0 "r")
21205    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21206               (clobber (reg:CC FLAGS_REG))])]
21207   ""
21208   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21209               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21210   "")
21212 ;; Two pops case is tricky, since pop causes dependency on destination register.
21213 ;; We use two registers if available.
21214 (define_peephole2
21215   [(match_scratch:DI 0 "r")
21216    (match_scratch:DI 1 "r")
21217    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21218               (clobber (reg:CC FLAGS_REG))])]
21219   ""
21220   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21221               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21222    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21223               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21224   "")
21226 (define_peephole2
21227   [(match_scratch:DI 0 "r")
21228    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21229               (clobber (reg:CC FLAGS_REG))])]
21230   "optimize_insn_for_size_p ()"
21231   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21232               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21233    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21234               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21235   "")
21237 ;; Convert imul by three, five and nine into lea
21238 (define_peephole2
21239   [(parallel
21240     [(set (match_operand:SI 0 "register_operand" "")
21241           (mult:SI (match_operand:SI 1 "register_operand" "")
21242                    (match_operand:SI 2 "const_int_operand" "")))
21243      (clobber (reg:CC FLAGS_REG))])]
21244   "INTVAL (operands[2]) == 3
21245    || INTVAL (operands[2]) == 5
21246    || INTVAL (operands[2]) == 9"
21247   [(set (match_dup 0)
21248         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21249                  (match_dup 1)))]
21250   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21252 (define_peephole2
21253   [(parallel
21254     [(set (match_operand:SI 0 "register_operand" "")
21255           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21256                    (match_operand:SI 2 "const_int_operand" "")))
21257      (clobber (reg:CC FLAGS_REG))])]
21258   "optimize_insn_for_speed_p ()
21259    && (INTVAL (operands[2]) == 3
21260        || INTVAL (operands[2]) == 5
21261        || INTVAL (operands[2]) == 9)"
21262   [(set (match_dup 0) (match_dup 1))
21263    (set (match_dup 0)
21264         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21265                  (match_dup 0)))]
21266   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21268 (define_peephole2
21269   [(parallel
21270     [(set (match_operand:DI 0 "register_operand" "")
21271           (mult:DI (match_operand:DI 1 "register_operand" "")
21272                    (match_operand:DI 2 "const_int_operand" "")))
21273      (clobber (reg:CC FLAGS_REG))])]
21274   "TARGET_64BIT
21275    && (INTVAL (operands[2]) == 3
21276        || INTVAL (operands[2]) == 5
21277        || INTVAL (operands[2]) == 9)"
21278   [(set (match_dup 0)
21279         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21280                  (match_dup 1)))]
21281   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21283 (define_peephole2
21284   [(parallel
21285     [(set (match_operand:DI 0 "register_operand" "")
21286           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21287                    (match_operand:DI 2 "const_int_operand" "")))
21288      (clobber (reg:CC FLAGS_REG))])]
21289   "TARGET_64BIT
21290    && optimize_insn_for_speed_p ()
21291    && (INTVAL (operands[2]) == 3
21292        || INTVAL (operands[2]) == 5
21293        || INTVAL (operands[2]) == 9)"
21294   [(set (match_dup 0) (match_dup 1))
21295    (set (match_dup 0)
21296         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21297                  (match_dup 0)))]
21298   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21300 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21301 ;; imul $32bit_imm, reg, reg is direct decoded.
21302 (define_peephole2
21303   [(match_scratch:DI 3 "r")
21304    (parallel [(set (match_operand:DI 0 "register_operand" "")
21305                    (mult:DI (match_operand:DI 1 "memory_operand" "")
21306                             (match_operand:DI 2 "immediate_operand" "")))
21307               (clobber (reg:CC FLAGS_REG))])]
21308   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21309    && !satisfies_constraint_K (operands[2])"
21310   [(set (match_dup 3) (match_dup 1))
21311    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21312               (clobber (reg:CC FLAGS_REG))])]
21315 (define_peephole2
21316   [(match_scratch:SI 3 "r")
21317    (parallel [(set (match_operand:SI 0 "register_operand" "")
21318                    (mult:SI (match_operand:SI 1 "memory_operand" "")
21319                             (match_operand:SI 2 "immediate_operand" "")))
21320               (clobber (reg:CC FLAGS_REG))])]
21321   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21322    && !satisfies_constraint_K (operands[2])"
21323   [(set (match_dup 3) (match_dup 1))
21324    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21325               (clobber (reg:CC FLAGS_REG))])]
21328 (define_peephole2
21329   [(match_scratch:SI 3 "r")
21330    (parallel [(set (match_operand:DI 0 "register_operand" "")
21331                    (zero_extend:DI
21332                      (mult:SI (match_operand:SI 1 "memory_operand" "")
21333                               (match_operand:SI 2 "immediate_operand" ""))))
21334               (clobber (reg:CC FLAGS_REG))])]
21335   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21336    && !satisfies_constraint_K (operands[2])"
21337   [(set (match_dup 3) (match_dup 1))
21338    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21339               (clobber (reg:CC FLAGS_REG))])]
21342 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21343 ;; Convert it into imul reg, reg
21344 ;; It would be better to force assembler to encode instruction using long
21345 ;; immediate, but there is apparently no way to do so.
21346 (define_peephole2
21347   [(parallel [(set (match_operand:DI 0 "register_operand" "")
21348                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21349                             (match_operand:DI 2 "const_int_operand" "")))
21350               (clobber (reg:CC FLAGS_REG))])
21351    (match_scratch:DI 3 "r")]
21352   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21353    && satisfies_constraint_K (operands[2])"
21354   [(set (match_dup 3) (match_dup 2))
21355    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21356               (clobber (reg:CC FLAGS_REG))])]
21358   if (!rtx_equal_p (operands[0], operands[1]))
21359     emit_move_insn (operands[0], operands[1]);
21362 (define_peephole2
21363   [(parallel [(set (match_operand:SI 0 "register_operand" "")
21364                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21365                             (match_operand:SI 2 "const_int_operand" "")))
21366               (clobber (reg:CC FLAGS_REG))])
21367    (match_scratch:SI 3 "r")]
21368   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21369    && satisfies_constraint_K (operands[2])"
21370   [(set (match_dup 3) (match_dup 2))
21371    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21372               (clobber (reg:CC FLAGS_REG))])]
21374   if (!rtx_equal_p (operands[0], operands[1]))
21375     emit_move_insn (operands[0], operands[1]);
21378 (define_peephole2
21379   [(parallel [(set (match_operand:HI 0 "register_operand" "")
21380                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
21381                             (match_operand:HI 2 "immediate_operand" "")))
21382               (clobber (reg:CC FLAGS_REG))])
21383    (match_scratch:HI 3 "r")]
21384   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
21385   [(set (match_dup 3) (match_dup 2))
21386    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21387               (clobber (reg:CC FLAGS_REG))])]
21389   if (!rtx_equal_p (operands[0], operands[1]))
21390     emit_move_insn (operands[0], operands[1]);
21393 ;; After splitting up read-modify operations, array accesses with memory
21394 ;; operands might end up in form:
21395 ;;  sall    $2, %eax
21396 ;;  movl    4(%esp), %edx
21397 ;;  addl    %edx, %eax
21398 ;; instead of pre-splitting:
21399 ;;  sall    $2, %eax
21400 ;;  addl    4(%esp), %eax
21401 ;; Turn it into:
21402 ;;  movl    4(%esp), %edx
21403 ;;  leal    (%edx,%eax,4), %eax
21405 (define_peephole2
21406   [(parallel [(set (match_operand 0 "register_operand" "")
21407                    (ashift (match_operand 1 "register_operand" "")
21408                            (match_operand 2 "const_int_operand" "")))
21409                (clobber (reg:CC FLAGS_REG))])
21410    (set (match_operand 3 "register_operand")
21411         (match_operand 4 "x86_64_general_operand" ""))
21412    (parallel [(set (match_operand 5 "register_operand" "")
21413                    (plus (match_operand 6 "register_operand" "")
21414                          (match_operand 7 "register_operand" "")))
21415                    (clobber (reg:CC FLAGS_REG))])]
21416   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21417    /* Validate MODE for lea.  */
21418    && ((!TARGET_PARTIAL_REG_STALL
21419         && (GET_MODE (operands[0]) == QImode
21420             || GET_MODE (operands[0]) == HImode))
21421        || GET_MODE (operands[0]) == SImode
21422        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21423    /* We reorder load and the shift.  */
21424    && !rtx_equal_p (operands[1], operands[3])
21425    && !reg_overlap_mentioned_p (operands[0], operands[4])
21426    /* Last PLUS must consist of operand 0 and 3.  */
21427    && !rtx_equal_p (operands[0], operands[3])
21428    && (rtx_equal_p (operands[3], operands[6])
21429        || rtx_equal_p (operands[3], operands[7]))
21430    && (rtx_equal_p (operands[0], operands[6])
21431        || rtx_equal_p (operands[0], operands[7]))
21432    /* The intermediate operand 0 must die or be same as output.  */
21433    && (rtx_equal_p (operands[0], operands[5])
21434        || peep2_reg_dead_p (3, operands[0]))"
21435   [(set (match_dup 3) (match_dup 4))
21436    (set (match_dup 0) (match_dup 1))]
21438   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21439   int scale = 1 << INTVAL (operands[2]);
21440   rtx index = gen_lowpart (Pmode, operands[1]);
21441   rtx base = gen_lowpart (Pmode, operands[3]);
21442   rtx dest = gen_lowpart (mode, operands[5]);
21444   operands[1] = gen_rtx_PLUS (Pmode, base,
21445                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21446   if (mode != Pmode)
21447     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21448   operands[0] = dest;
21451 ;; Call-value patterns last so that the wildcard operand does not
21452 ;; disrupt insn-recog's switch tables.
21454 (define_insn "*call_value_pop_0"
21455   [(set (match_operand 0 "" "")
21456         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21457               (match_operand:SI 2 "" "")))
21458    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21459                             (match_operand:SI 3 "immediate_operand" "")))]
21460   "!TARGET_64BIT"
21462   if (SIBLING_CALL_P (insn))
21463     return "jmp\t%P1";
21464   else
21465     return "call\t%P1";
21467   [(set_attr "type" "callv")])
21469 (define_insn "*call_value_pop_1"
21470   [(set (match_operand 0 "" "")
21471         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21472               (match_operand:SI 2 "" "")))
21473    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21474                             (match_operand:SI 3 "immediate_operand" "i")))]
21475   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21477   if (constant_call_address_operand (operands[1], Pmode))
21478     return "call\t%P1";
21479   return "call\t%A1";
21481   [(set_attr "type" "callv")])
21483 (define_insn "*sibcall_value_pop_1"
21484   [(set (match_operand 0 "" "")
21485         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
21486               (match_operand:SI 2 "" "")))
21487    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21488                             (match_operand:SI 3 "immediate_operand" "i,i")))]
21489   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21490   "@
21491    jmp\t%P1
21492    jmp\t%A1"
21493   [(set_attr "type" "callv")])
21495 (define_insn "*call_value_0"
21496   [(set (match_operand 0 "" "")
21497         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21498               (match_operand:SI 2 "" "")))]
21499   "!TARGET_64BIT"
21501   if (SIBLING_CALL_P (insn))
21502     return "jmp\t%P1";
21503   else
21504     return "call\t%P1";
21506   [(set_attr "type" "callv")])
21508 (define_insn "*call_value_0_rex64"
21509   [(set (match_operand 0 "" "")
21510         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21511               (match_operand:DI 2 "const_int_operand" "")))]
21512   "TARGET_64BIT"
21514   if (SIBLING_CALL_P (insn))
21515     return "jmp\t%P1";
21516   else
21517     return "call\t%P1";
21519   [(set_attr "type" "callv")])
21521 (define_insn "*call_value_0_rex64_ms_sysv"
21522   [(set (match_operand 0 "" "")
21523         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21524               (match_operand:DI 2 "const_int_operand" "")))
21525    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21526    (clobber (reg:TI XMM6_REG))
21527    (clobber (reg:TI XMM7_REG))
21528    (clobber (reg:TI XMM8_REG))
21529    (clobber (reg:TI XMM9_REG))
21530    (clobber (reg:TI XMM10_REG))
21531    (clobber (reg:TI XMM11_REG))
21532    (clobber (reg:TI XMM12_REG))
21533    (clobber (reg:TI XMM13_REG))
21534    (clobber (reg:TI XMM14_REG))
21535    (clobber (reg:TI XMM15_REG))
21536    (clobber (reg:DI SI_REG))
21537    (clobber (reg:DI DI_REG))]
21538   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21540   if (SIBLING_CALL_P (insn))
21541     return "jmp\t%P1";
21542   else
21543     return "call\t%P1";
21545   [(set_attr "type" "callv")])
21547 (define_insn "*call_value_1"
21548   [(set (match_operand 0 "" "")
21549         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21550               (match_operand:SI 2 "" "")))]
21551   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21553   if (constant_call_address_operand (operands[1], Pmode))
21554     return "call\t%P1";
21555   return "call\t%A1";
21557   [(set_attr "type" "callv")])
21559 (define_insn "*sibcall_value_1"
21560   [(set (match_operand 0 "" "")
21561         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
21562               (match_operand:SI 2 "" "")))]
21563   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21564   "@
21565    jmp\t%P1
21566    jmp\t%A1"
21567   [(set_attr "type" "callv")])
21569 (define_insn "*call_value_1_rex64"
21570   [(set (match_operand 0 "" "")
21571         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21572               (match_operand:DI 2 "" "")))]
21573   "!SIBLING_CALL_P (insn) && TARGET_64BIT
21574    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21576   if (constant_call_address_operand (operands[1], Pmode))
21577     return "call\t%P1";
21578   return "call\t%A1";
21580   [(set_attr "type" "callv")])
21582 (define_insn "*call_value_1_rex64_ms_sysv"
21583   [(set (match_operand 0 "" "")
21584         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21585               (match_operand:DI 2 "" "")))
21586    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21587    (clobber (reg:TI 27))
21588    (clobber (reg:TI 28))
21589    (clobber (reg:TI 45))
21590    (clobber (reg:TI 46))
21591    (clobber (reg:TI 47))
21592    (clobber (reg:TI 48))
21593    (clobber (reg:TI 49))
21594    (clobber (reg:TI 50))
21595    (clobber (reg:TI 51))
21596    (clobber (reg:TI 52))
21597    (clobber (reg:DI SI_REG))
21598    (clobber (reg:DI DI_REG))]
21599   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21601   if (constant_call_address_operand (operands[1], Pmode))
21602     return "call\t%P1";
21603   return "call\t%A1";
21605   [(set_attr "type" "callv")])
21607 (define_insn "*call_value_1_rex64_large"
21608   [(set (match_operand 0 "" "")
21609         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21610               (match_operand:DI 2 "" "")))]
21611   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21612   "call\t%A1"
21613   [(set_attr "type" "callv")])
21615 (define_insn "*sibcall_value_1_rex64"
21616   [(set (match_operand 0 "" "")
21617         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
21618               (match_operand:DI 2 "" "")))]
21619   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21620   "@
21621    jmp\t%P1
21622    jmp\t%A1"
21623   [(set_attr "type" "callv")])
21625 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21626 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21627 ;; caught for use by garbage collectors and the like.  Using an insn that
21628 ;; maps to SIGILL makes it more likely the program will rightfully die.
21629 ;; Keeping with tradition, "6" is in honor of #UD.
21630 (define_insn "trap"
21631   [(trap_if (const_int 1) (const_int 6))]
21632   ""
21633   { return ASM_SHORT "0x0b0f"; }
21634   [(set_attr "length" "2")])
21636 (define_expand "sse_prologue_save"
21637   [(parallel [(set (match_operand:BLK 0 "" "")
21638                    (unspec:BLK [(reg:DI 21)
21639                                 (reg:DI 22)
21640                                 (reg:DI 23)
21641                                 (reg:DI 24)
21642                                 (reg:DI 25)
21643                                 (reg:DI 26)
21644                                 (reg:DI 27)
21645                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21646               (use (match_operand:DI 1 "register_operand" ""))
21647               (use (match_operand:DI 2 "immediate_operand" ""))
21648               (use (label_ref:DI (match_operand 3 "" "")))])]
21649   "TARGET_64BIT"
21650   "")
21652 (define_insn "*sse_prologue_save_insn"
21653   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21654                           (match_operand:DI 4 "const_int_operand" "n")))
21655         (unspec:BLK [(reg:DI 21)
21656                      (reg:DI 22)
21657                      (reg:DI 23)
21658                      (reg:DI 24)
21659                      (reg:DI 25)
21660                      (reg:DI 26)
21661                      (reg:DI 27)
21662                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21663    (use (match_operand:DI 1 "register_operand" "r"))
21664    (use (match_operand:DI 2 "const_int_operand" "i"))
21665    (use (label_ref:DI (match_operand 3 "" "X")))]
21666   "TARGET_64BIT
21667    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21668    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21670   int i;
21671   operands[0] = gen_rtx_MEM (Pmode,
21672                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21673   /* VEX instruction with a REX prefix will #UD.  */
21674   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
21675     gcc_unreachable ();
21677   output_asm_insn ("jmp\t%A1", operands);
21678   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21679     {
21680       operands[4] = adjust_address (operands[0], DImode, i*16);
21681       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21682       PUT_MODE (operands[4], TImode);
21683       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21684         output_asm_insn ("rex", operands);
21685       output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
21686     }
21687   (*targetm.asm_out.internal_label) (asm_out_file, "L",
21688                                      CODE_LABEL_NUMBER (operands[3]));
21689   return "";
21691   [(set_attr "type" "other")
21692    (set_attr "length_immediate" "0")
21693    (set_attr "length_address" "0")
21694    (set (attr "length")
21695      (if_then_else
21696        (eq (symbol_ref "TARGET_AVX") (const_int 0))
21697        (const_string "34")
21698        (const_string "42")))
21699    (set_attr "memory" "store")
21700    (set_attr "modrm" "0")
21701    (set_attr "prefix" "maybe_vex")
21702    (set_attr "mode" "DI")])
21704 (define_expand "prefetch"
21705   [(prefetch (match_operand 0 "address_operand" "")
21706              (match_operand:SI 1 "const_int_operand" "")
21707              (match_operand:SI 2 "const_int_operand" ""))]
21708   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21710   int rw = INTVAL (operands[1]);
21711   int locality = INTVAL (operands[2]);
21713   gcc_assert (rw == 0 || rw == 1);
21714   gcc_assert (locality >= 0 && locality <= 3);
21715   gcc_assert (GET_MODE (operands[0]) == Pmode
21716               || GET_MODE (operands[0]) == VOIDmode);
21718   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21719      supported by SSE counterpart or the SSE prefetch is not available
21720      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21721      of locality.  */
21722   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21723     operands[2] = GEN_INT (3);
21724   else
21725     operands[1] = const0_rtx;
21728 (define_insn "*prefetch_sse"
21729   [(prefetch (match_operand:SI 0 "address_operand" "p")
21730              (const_int 0)
21731              (match_operand:SI 1 "const_int_operand" ""))]
21732   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21734   static const char * const patterns[4] = {
21735    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21736   };
21738   int locality = INTVAL (operands[1]);
21739   gcc_assert (locality >= 0 && locality <= 3);
21741   return patterns[locality];
21743   [(set_attr "type" "sse")
21744    (set_attr "memory" "none")])
21746 (define_insn "*prefetch_sse_rex"
21747   [(prefetch (match_operand:DI 0 "address_operand" "p")
21748              (const_int 0)
21749              (match_operand:SI 1 "const_int_operand" ""))]
21750   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21752   static const char * const patterns[4] = {
21753    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21754   };
21756   int locality = INTVAL (operands[1]);
21757   gcc_assert (locality >= 0 && locality <= 3);
21759   return patterns[locality];
21761   [(set_attr "type" "sse")
21762    (set_attr "memory" "none")])
21764 (define_insn "*prefetch_3dnow"
21765   [(prefetch (match_operand:SI 0 "address_operand" "p")
21766              (match_operand:SI 1 "const_int_operand" "n")
21767              (const_int 3))]
21768   "TARGET_3DNOW && !TARGET_64BIT"
21770   if (INTVAL (operands[1]) == 0)
21771     return "prefetch\t%a0";
21772   else
21773     return "prefetchw\t%a0";
21775   [(set_attr "type" "mmx")
21776    (set_attr "memory" "none")])
21778 (define_insn "*prefetch_3dnow_rex"
21779   [(prefetch (match_operand:DI 0 "address_operand" "p")
21780              (match_operand:SI 1 "const_int_operand" "n")
21781              (const_int 3))]
21782   "TARGET_3DNOW && TARGET_64BIT"
21784   if (INTVAL (operands[1]) == 0)
21785     return "prefetch\t%a0";
21786   else
21787     return "prefetchw\t%a0";
21789   [(set_attr "type" "mmx")
21790    (set_attr "memory" "none")])
21792 (define_expand "stack_protect_set"
21793   [(match_operand 0 "memory_operand" "")
21794    (match_operand 1 "memory_operand" "")]
21795   ""
21797 #ifdef TARGET_THREAD_SSP_OFFSET
21798   if (TARGET_64BIT)
21799     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21800                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21801   else
21802     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21803                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21804 #else
21805   if (TARGET_64BIT)
21806     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21807   else
21808     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21809 #endif
21810   DONE;
21813 (define_insn "stack_protect_set_si"
21814   [(set (match_operand:SI 0 "memory_operand" "=m")
21815         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21816    (set (match_scratch:SI 2 "=&r") (const_int 0))
21817    (clobber (reg:CC FLAGS_REG))]
21818   ""
21819   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21820   [(set_attr "type" "multi")])
21822 (define_insn "stack_protect_set_di"
21823   [(set (match_operand:DI 0 "memory_operand" "=m")
21824         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21825    (set (match_scratch:DI 2 "=&r") (const_int 0))
21826    (clobber (reg:CC FLAGS_REG))]
21827   "TARGET_64BIT"
21828   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21829   [(set_attr "type" "multi")])
21831 (define_insn "stack_tls_protect_set_si"
21832   [(set (match_operand:SI 0 "memory_operand" "=m")
21833         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21834    (set (match_scratch:SI 2 "=&r") (const_int 0))
21835    (clobber (reg:CC FLAGS_REG))]
21836   ""
21837   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21838   [(set_attr "type" "multi")])
21840 (define_insn "stack_tls_protect_set_di"
21841   [(set (match_operand:DI 0 "memory_operand" "=m")
21842         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21843    (set (match_scratch:DI 2 "=&r") (const_int 0))
21844    (clobber (reg:CC FLAGS_REG))]
21845   "TARGET_64BIT"
21846   {
21847      /* The kernel uses a different segment register for performance reasons; a
21848         system call would not have to trash the userspace segment register,
21849         which would be expensive */
21850      if (ix86_cmodel != CM_KERNEL)
21851         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21852      else
21853         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21854   }
21855   [(set_attr "type" "multi")])
21857 (define_expand "stack_protect_test"
21858   [(match_operand 0 "memory_operand" "")
21859    (match_operand 1 "memory_operand" "")
21860    (match_operand 2 "" "")]
21861   ""
21863   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21864   ix86_compare_op0 = operands[0];
21865   ix86_compare_op1 = operands[1];
21866   ix86_compare_emitted = flags;
21868 #ifdef TARGET_THREAD_SSP_OFFSET
21869   if (TARGET_64BIT)
21870     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21871                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21872   else
21873     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21874                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21875 #else
21876   if (TARGET_64BIT)
21877     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21878   else
21879     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21880 #endif
21881   emit_jump_insn (gen_beq (operands[2]));
21882   DONE;
21885 (define_insn "stack_protect_test_si"
21886   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21887         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21888                      (match_operand:SI 2 "memory_operand" "m")]
21889                     UNSPEC_SP_TEST))
21890    (clobber (match_scratch:SI 3 "=&r"))]
21891   ""
21892   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21893   [(set_attr "type" "multi")])
21895 (define_insn "stack_protect_test_di"
21896   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21897         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21898                      (match_operand:DI 2 "memory_operand" "m")]
21899                     UNSPEC_SP_TEST))
21900    (clobber (match_scratch:DI 3 "=&r"))]
21901   "TARGET_64BIT"
21902   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21903   [(set_attr "type" "multi")])
21905 (define_insn "stack_tls_protect_test_si"
21906   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21907         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21908                      (match_operand:SI 2 "const_int_operand" "i")]
21909                     UNSPEC_SP_TLS_TEST))
21910    (clobber (match_scratch:SI 3 "=r"))]
21911   ""
21912   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21913   [(set_attr "type" "multi")])
21915 (define_insn "stack_tls_protect_test_di"
21916   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21917         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21918                      (match_operand:DI 2 "const_int_operand" "i")]
21919                     UNSPEC_SP_TLS_TEST))
21920    (clobber (match_scratch:DI 3 "=r"))]
21921   "TARGET_64BIT"
21922   {
21923      /* The kernel uses a different segment register for performance reasons; a
21924         system call would not have to trash the userspace segment register,
21925         which would be expensive */
21926      if (ix86_cmodel != CM_KERNEL)
21927         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21928      else
21929         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21930   }
21931   [(set_attr "type" "multi")])
21933 (define_mode_iterator CRC32MODE [QI HI SI])
21934 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21935 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21937 (define_insn "sse4_2_crc32<mode>"
21938   [(set (match_operand:SI 0 "register_operand" "=r")
21939         (unspec:SI
21940           [(match_operand:SI 1 "register_operand" "0")
21941            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21942           UNSPEC_CRC32))]
21943   "TARGET_SSE4_2"
21944   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21945   [(set_attr "type" "sselog1")
21946    (set_attr "prefix_rep" "1")
21947    (set_attr "prefix_extra" "1")
21948    (set_attr "mode" "SI")])
21950 (define_insn "sse4_2_crc32di"
21951   [(set (match_operand:DI 0 "register_operand" "=r")
21952         (unspec:DI
21953           [(match_operand:DI 1 "register_operand" "0")
21954            (match_operand:DI 2 "nonimmediate_operand" "rm")]
21955           UNSPEC_CRC32))]
21956   "TARGET_SSE4_2 && TARGET_64BIT"
21957   "crc32q\t{%2, %0|%0, %2}"
21958   [(set_attr "type" "sselog1")
21959    (set_attr "prefix_rep" "1")
21960    (set_attr "prefix_extra" "1")
21961    (set_attr "mode" "DI")])
21963 (include "mmx.md")
21964 (include "sse.md")
21965 (include "sync.md")